dom/mobilemessage/src/ipc/SmsParent.cpp

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:a056d2e35b84
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "SmsParent.h"
7 #include "nsISmsService.h"
8 #include "nsIMmsService.h"
9 #include "nsIObserverService.h"
10 #include "mozilla/Services.h"
11 #include "nsIDOMMozSmsMessage.h"
12 #include "nsIDOMMozMmsMessage.h"
13 #include "mozilla/unused.h"
14 #include "SmsMessage.h"
15 #include "MmsMessage.h"
16 #include "nsIMobileMessageDatabaseService.h"
17 #include "SmsFilter.h"
18 #include "SmsSegmentInfo.h"
19 #include "MobileMessageThread.h"
20 #include "nsIDOMFile.h"
21 #include "mozilla/dom/ipc/Blob.h"
22 #include "mozilla/dom/ContentParent.h"
23 #include "mozilla/dom/mobilemessage/Constants.h" // For MessageType
24 #include "nsContentUtils.h"
25 #include "nsTArrayHelpers.h"
26 #include "nsCxPusher.h"
27 #include "xpcpublic.h"
28 #include "nsServiceManagerUtils.h"
29
30 namespace mozilla {
31 namespace dom {
32 namespace mobilemessage {
33
34 static JSObject*
35 MmsAttachmentDataToJSObject(JSContext* aContext,
36 const MmsAttachmentData& aAttachment)
37 {
38 JS::Rooted<JSObject*> obj(aContext, JS_NewObject(aContext, nullptr, JS::NullPtr(),
39 JS::NullPtr()));
40 NS_ENSURE_TRUE(obj, nullptr);
41
42 JS::Rooted<JSString*> idStr(aContext, JS_NewUCStringCopyN(aContext,
43 aAttachment.id().get(),
44 aAttachment.id().Length()));
45 NS_ENSURE_TRUE(idStr, nullptr);
46 if (!JS_DefineProperty(aContext, obj, "id", idStr, 0)) {
47 return nullptr;
48 }
49
50 JS::Rooted<JSString*> locStr(aContext, JS_NewUCStringCopyN(aContext,
51 aAttachment.location().get(),
52 aAttachment.location().Length()));
53 NS_ENSURE_TRUE(locStr, nullptr);
54 if (!JS_DefineProperty(aContext, obj, "location", locStr, 0)) {
55 return nullptr;
56 }
57
58 nsCOMPtr<nsIDOMBlob> blob = static_cast<BlobParent*>(aAttachment.contentParent())->GetBlob();
59 JS::Rooted<JS::Value> content(aContext);
60 nsresult rv = nsContentUtils::WrapNative(aContext,
61 blob,
62 &NS_GET_IID(nsIDOMBlob),
63 &content);
64 NS_ENSURE_SUCCESS(rv, nullptr);
65 if (!JS_DefineProperty(aContext, obj, "content", content, 0)) {
66 return nullptr;
67 }
68
69 return obj;
70 }
71
72 static bool
73 GetParamsFromSendMmsMessageRequest(JSContext* aCx,
74 const SendMmsMessageRequest& aRequest,
75 JS::Value* aParam)
76 {
77 JS::Rooted<JSObject*> paramsObj(aCx, JS_NewObject(aCx, nullptr, JS::NullPtr(), JS::NullPtr()));
78 NS_ENSURE_TRUE(paramsObj, false);
79
80 // smil
81 JS::Rooted<JSString*> smilStr(aCx, JS_NewUCStringCopyN(aCx,
82 aRequest.smil().get(),
83 aRequest.smil().Length()));
84 NS_ENSURE_TRUE(smilStr, false);
85 if(!JS_DefineProperty(aCx, paramsObj, "smil", smilStr, 0)) {
86 return false;
87 }
88
89 // subject
90 JS::Rooted<JSString*> subjectStr(aCx, JS_NewUCStringCopyN(aCx,
91 aRequest.subject().get(),
92 aRequest.subject().Length()));
93 NS_ENSURE_TRUE(subjectStr, false);
94 if(!JS_DefineProperty(aCx, paramsObj, "subject", subjectStr, 0)) {
95 return false;
96 }
97
98 // receivers
99 JS::Rooted<JSObject*> receiverArray(aCx);
100 if (NS_FAILED(nsTArrayToJSArray(aCx,
101 aRequest.receivers(),
102 receiverArray.address()))) {
103 return false;
104 }
105 if (!JS_DefineProperty(aCx, paramsObj, "receivers", receiverArray, 0)) {
106 return false;
107 }
108
109 // attachments
110 JS::Rooted<JSObject*> attachmentArray(aCx, JS_NewArrayObject(aCx,
111 aRequest.attachments().Length()));
112 for (uint32_t i = 0; i < aRequest.attachments().Length(); i++) {
113 JS::Rooted<JSObject*> obj(aCx,
114 MmsAttachmentDataToJSObject(aCx, aRequest.attachments().ElementAt(i)));
115 NS_ENSURE_TRUE(obj, false);
116 if (!JS_SetElement(aCx, attachmentArray, i, obj)) {
117 return false;
118 }
119 }
120
121 if (!JS_DefineProperty(aCx, paramsObj, "attachments", attachmentArray, 0)) {
122 return false;
123 }
124
125 aParam->setObject(*paramsObj);
126 return true;
127 }
128
129 NS_IMPL_ISUPPORTS(SmsParent, nsIObserver)
130
131 SmsParent::SmsParent()
132 {
133 MOZ_COUNT_CTOR(SmsParent);
134 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
135 if (!obs) {
136 return;
137 }
138
139 obs->AddObserver(this, kSmsReceivedObserverTopic, false);
140 obs->AddObserver(this, kSmsRetrievingObserverTopic, false);
141 obs->AddObserver(this, kSmsSendingObserverTopic, false);
142 obs->AddObserver(this, kSmsSentObserverTopic, false);
143 obs->AddObserver(this, kSmsFailedObserverTopic, false);
144 obs->AddObserver(this, kSmsDeliverySuccessObserverTopic, false);
145 obs->AddObserver(this, kSmsDeliveryErrorObserverTopic, false);
146 obs->AddObserver(this, kSilentSmsReceivedObserverTopic, false);
147 obs->AddObserver(this, kSmsReadSuccessObserverTopic, false);
148 obs->AddObserver(this, kSmsReadErrorObserverTopic, false);
149 }
150
151 void
152 SmsParent::ActorDestroy(ActorDestroyReason why)
153 {
154 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
155 if (!obs) {
156 return;
157 }
158
159 obs->RemoveObserver(this, kSmsReceivedObserverTopic);
160 obs->RemoveObserver(this, kSmsRetrievingObserverTopic);
161 obs->RemoveObserver(this, kSmsSendingObserverTopic);
162 obs->RemoveObserver(this, kSmsSentObserverTopic);
163 obs->RemoveObserver(this, kSmsFailedObserverTopic);
164 obs->RemoveObserver(this, kSmsDeliverySuccessObserverTopic);
165 obs->RemoveObserver(this, kSmsDeliveryErrorObserverTopic);
166 obs->RemoveObserver(this, kSilentSmsReceivedObserverTopic);
167 obs->RemoveObserver(this, kSmsReadSuccessObserverTopic);
168 obs->RemoveObserver(this, kSmsReadErrorObserverTopic);
169 }
170
171 NS_IMETHODIMP
172 SmsParent::Observe(nsISupports* aSubject, const char* aTopic,
173 const char16_t* aData)
174 {
175 if (!strcmp(aTopic, kSmsReceivedObserverTopic)) {
176 MobileMessageData msgData;
177 if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
178 NS_ERROR("Got a 'sms-received' topic without a valid message!");
179 return NS_OK;
180 }
181
182 unused << SendNotifyReceivedMessage(msgData);
183 return NS_OK;
184 }
185
186 if (!strcmp(aTopic, kSmsRetrievingObserverTopic)) {
187 MobileMessageData msgData;
188 if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
189 NS_ERROR("Got a 'sms-retrieving' topic without a valid message!");
190 return NS_OK;
191 }
192
193 unused << SendNotifyRetrievingMessage(msgData);
194 return NS_OK;
195 }
196
197 if (!strcmp(aTopic, kSmsSendingObserverTopic)) {
198 MobileMessageData msgData;
199 if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
200 NS_ERROR("Got a 'sms-sending' topic without a valid message!");
201 return NS_OK;
202 }
203
204 unused << SendNotifySendingMessage(msgData);
205 return NS_OK;
206 }
207
208 if (!strcmp(aTopic, kSmsSentObserverTopic)) {
209 MobileMessageData msgData;
210 if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
211 NS_ERROR("Got a 'sms-sent' topic without a valid message!");
212 return NS_OK;
213 }
214
215 unused << SendNotifySentMessage(msgData);
216 return NS_OK;
217 }
218
219 if (!strcmp(aTopic, kSmsFailedObserverTopic)) {
220 MobileMessageData msgData;
221 if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
222 NS_ERROR("Got a 'sms-failed' topic without a valid message!");
223 return NS_OK;
224 }
225
226 unused << SendNotifyFailedMessage(msgData);
227 return NS_OK;
228 }
229
230 if (!strcmp(aTopic, kSmsDeliverySuccessObserverTopic)) {
231 MobileMessageData msgData;
232 if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
233 NS_ERROR("Got a 'sms-sending' topic without a valid message!");
234 return NS_OK;
235 }
236
237 unused << SendNotifyDeliverySuccessMessage(msgData);
238 return NS_OK;
239 }
240
241 if (!strcmp(aTopic, kSmsDeliveryErrorObserverTopic)) {
242 MobileMessageData msgData;
243 if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
244 NS_ERROR("Got a 'sms-delivery-error' topic without a valid message!");
245 return NS_OK;
246 }
247
248 unused << SendNotifyDeliveryErrorMessage(msgData);
249 return NS_OK;
250 }
251
252 if (!strcmp(aTopic, kSilentSmsReceivedObserverTopic)) {
253 nsCOMPtr<nsIDOMMozSmsMessage> smsMsg = do_QueryInterface(aSubject);
254 if (!smsMsg) {
255 return NS_OK;
256 }
257
258 nsString sender;
259 if (NS_FAILED(smsMsg->GetSender(sender)) ||
260 !mSilentNumbers.Contains(sender)) {
261 return NS_OK;
262 }
263
264 MobileMessageData msgData =
265 static_cast<SmsMessage*>(smsMsg.get())->GetData();
266 unused << SendNotifyReceivedSilentMessage(msgData);
267 return NS_OK;
268 }
269
270
271 if (!strcmp(aTopic, kSmsReadSuccessObserverTopic)) {
272 MobileMessageData msgData;
273 if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
274 NS_ERROR("Got a 'sms-read-success' topic without a valid message!");
275 return NS_OK;
276 }
277
278 unused << SendNotifyReadSuccessMessage(msgData);
279 return NS_OK;
280 }
281
282 if (!strcmp(aTopic, kSmsReadErrorObserverTopic)) {
283 MobileMessageData msgData;
284 if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
285 NS_ERROR("Got a 'sms-read-error' topic without a valid message!");
286 return NS_OK;
287 }
288
289 unused << SendNotifyReadErrorMessage(msgData);
290 return NS_OK;
291 }
292
293
294 return NS_OK;
295 }
296
297 bool
298 SmsParent::GetMobileMessageDataFromMessage(nsISupports *aMsg,
299 MobileMessageData &aData)
300 {
301 nsCOMPtr<nsIDOMMozMmsMessage> mmsMsg = do_QueryInterface(aMsg);
302 if (mmsMsg) {
303 MmsMessageData data;
304 ContentParent *parent = static_cast<ContentParent*>(Manager());
305 if (!static_cast<MmsMessage*>(mmsMsg.get())->GetData(parent, data)) {
306 return false;
307 }
308 aData = data;
309 return true;
310 }
311
312 nsCOMPtr<nsIDOMMozSmsMessage> smsMsg = do_QueryInterface(aMsg);
313 if (smsMsg) {
314 aData = static_cast<SmsMessage*>(smsMsg.get())->GetData();
315 return true;
316 }
317
318 NS_WARNING("Cannot get MobileMessageData");
319 return false;
320 }
321
322 bool
323 SmsParent::RecvAddSilentNumber(const nsString& aNumber)
324 {
325 if (mSilentNumbers.Contains(aNumber)) {
326 return true;
327 }
328
329 nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
330 NS_ENSURE_TRUE(smsService, true);
331
332 nsresult rv = smsService->AddSilentNumber(aNumber);
333 if (NS_SUCCEEDED(rv)) {
334 mSilentNumbers.AppendElement(aNumber);
335 }
336
337 return true;
338 }
339
340 bool
341 SmsParent::RecvRemoveSilentNumber(const nsString& aNumber)
342 {
343 if (!mSilentNumbers.Contains(aNumber)) {
344 return true;
345 }
346
347 nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
348 NS_ENSURE_TRUE(smsService, true);
349
350 nsresult rv = smsService->RemoveSilentNumber(aNumber);
351 if (NS_SUCCEEDED(rv)) {
352 mSilentNumbers.RemoveElement(aNumber);
353 }
354
355 return true;
356 }
357
358 bool
359 SmsParent::RecvPSmsRequestConstructor(PSmsRequestParent* aActor,
360 const IPCSmsRequest& aRequest)
361 {
362 SmsRequestParent* actor = static_cast<SmsRequestParent*>(aActor);
363
364 switch (aRequest.type()) {
365 case IPCSmsRequest::TSendMessageRequest:
366 return actor->DoRequest(aRequest.get_SendMessageRequest());
367 case IPCSmsRequest::TRetrieveMessageRequest:
368 return actor->DoRequest(aRequest.get_RetrieveMessageRequest());
369 case IPCSmsRequest::TGetMessageRequest:
370 return actor->DoRequest(aRequest.get_GetMessageRequest());
371 case IPCSmsRequest::TDeleteMessageRequest:
372 return actor->DoRequest(aRequest.get_DeleteMessageRequest());
373 case IPCSmsRequest::TMarkMessageReadRequest:
374 return actor->DoRequest(aRequest.get_MarkMessageReadRequest());
375 case IPCSmsRequest::TGetSegmentInfoForTextRequest:
376 return actor->DoRequest(aRequest.get_GetSegmentInfoForTextRequest());
377 case IPCSmsRequest::TGetSmscAddressRequest:
378 return actor->DoRequest(aRequest.get_GetSmscAddressRequest());
379 default:
380 MOZ_CRASH("Unknown type!");
381 }
382
383 return false;
384 }
385
386 PSmsRequestParent*
387 SmsParent::AllocPSmsRequestParent(const IPCSmsRequest& aRequest)
388 {
389 SmsRequestParent* actor = new SmsRequestParent();
390 // Add an extra ref for IPDL. Will be released in
391 // SmsParent::DeallocPSmsRequestParent().
392 actor->AddRef();
393
394 return actor;
395 }
396
397 bool
398 SmsParent::DeallocPSmsRequestParent(PSmsRequestParent* aActor)
399 {
400 // SmsRequestParent is refcounted, must not be freed manually.
401 static_cast<SmsRequestParent*>(aActor)->Release();
402 return true;
403 }
404
405 bool
406 SmsParent::RecvPMobileMessageCursorConstructor(PMobileMessageCursorParent* aActor,
407 const IPCMobileMessageCursor& aRequest)
408 {
409 MobileMessageCursorParent* actor =
410 static_cast<MobileMessageCursorParent*>(aActor);
411
412 switch (aRequest.type()) {
413 case IPCMobileMessageCursor::TCreateMessageCursorRequest:
414 return actor->DoRequest(aRequest.get_CreateMessageCursorRequest());
415 case IPCMobileMessageCursor::TCreateThreadCursorRequest:
416 return actor->DoRequest(aRequest.get_CreateThreadCursorRequest());
417 default:
418 MOZ_CRASH("Unknown type!");
419 }
420
421 return false;
422 }
423
424 PMobileMessageCursorParent*
425 SmsParent::AllocPMobileMessageCursorParent(const IPCMobileMessageCursor& aRequest)
426 {
427 MobileMessageCursorParent* actor = new MobileMessageCursorParent();
428 // Add an extra ref for IPDL. Will be released in
429 // SmsParent::DeallocPMobileMessageCursorParent().
430 actor->AddRef();
431
432 return actor;
433 }
434
435 bool
436 SmsParent::DeallocPMobileMessageCursorParent(PMobileMessageCursorParent* aActor)
437 {
438 // MobileMessageCursorParent is refcounted, must not be freed manually.
439 static_cast<MobileMessageCursorParent*>(aActor)->Release();
440 return true;
441 }
442
443 /*******************************************************************************
444 * SmsRequestParent
445 ******************************************************************************/
446
447 NS_IMPL_ISUPPORTS(SmsRequestParent, nsIMobileMessageCallback)
448
449 void
450 SmsRequestParent::ActorDestroy(ActorDestroyReason aWhy)
451 {
452 mActorDestroyed = true;
453 }
454
455 bool
456 SmsRequestParent::DoRequest(const SendMessageRequest& aRequest)
457 {
458 switch(aRequest.type()) {
459 case SendMessageRequest::TSendSmsMessageRequest: {
460 nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
461 NS_ENSURE_TRUE(smsService, true);
462
463 const SendSmsMessageRequest &req = aRequest.get_SendSmsMessageRequest();
464 smsService->Send(req.serviceId(), req.number(), req.message(),
465 req.silent(), this);
466 }
467 break;
468 case SendMessageRequest::TSendMmsMessageRequest: {
469 nsCOMPtr<nsIMmsService> mmsService = do_GetService(MMS_SERVICE_CONTRACTID);
470 NS_ENSURE_TRUE(mmsService, true);
471
472 // There are cases (see bug 981202) where this is called with no JS on the
473 // stack. And since mmsService might be JS-Implemented, we need to pass a
474 // jsval to ::Send. Only system code should be looking at the result here,
475 // so we just create it in the System-Principaled Junk Scope.
476 AutoJSContext cx;
477 JSAutoCompartment ac(cx, xpc::GetJunkScope());
478 JS::Rooted<JS::Value> params(cx);
479 const SendMmsMessageRequest &req = aRequest.get_SendMmsMessageRequest();
480 if (!GetParamsFromSendMmsMessageRequest(cx,
481 req,
482 params.address())) {
483 NS_WARNING("SmsRequestParent: Fail to build MMS params.");
484 return true;
485 }
486 mmsService->Send(req.serviceId(), params, this);
487 }
488 break;
489 default:
490 MOZ_CRASH("Unknown type of SendMessageRequest!");
491 }
492 return true;
493 }
494
495 bool
496 SmsRequestParent::DoRequest(const RetrieveMessageRequest& aRequest)
497 {
498 nsresult rv = NS_ERROR_FAILURE;
499
500 nsCOMPtr<nsIMmsService> mmsService = do_GetService(MMS_SERVICE_CONTRACTID);
501 if (mmsService) {
502 rv = mmsService->Retrieve(aRequest.messageId(), this);
503 }
504
505 if (NS_FAILED(rv)) {
506 return NS_SUCCEEDED(NotifyGetMessageFailed(nsIMobileMessageCallback::INTERNAL_ERROR));
507 }
508
509 return true;
510 }
511
512 bool
513 SmsRequestParent::DoRequest(const GetMessageRequest& aRequest)
514 {
515 nsresult rv = NS_ERROR_FAILURE;
516
517 nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
518 do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
519 if (dbService) {
520 rv = dbService->GetMessageMoz(aRequest.messageId(), this);
521 }
522
523 if (NS_FAILED(rv)) {
524 return NS_SUCCEEDED(NotifyGetMessageFailed(nsIMobileMessageCallback::INTERNAL_ERROR));
525 }
526
527 return true;
528 }
529
530 bool
531 SmsRequestParent::DoRequest(const GetSmscAddressRequest& aRequest)
532 {
533 nsresult rv = NS_ERROR_FAILURE;
534
535 nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
536 if (smsService) {
537 rv = smsService->GetSmscAddress(aRequest.serviceId(), this);
538 }
539
540 if (NS_FAILED(rv)) {
541 return NS_SUCCEEDED(NotifyGetSmscAddressFailed(nsIMobileMessageCallback::INTERNAL_ERROR));
542 }
543
544 return true;
545 }
546
547 bool
548 SmsRequestParent::DoRequest(const DeleteMessageRequest& aRequest)
549 {
550 nsresult rv = NS_ERROR_FAILURE;
551
552 nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
553 do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
554 if (dbService) {
555 const InfallibleTArray<int32_t>& messageIds = aRequest.messageIds();
556 rv = dbService->DeleteMessage(const_cast<int32_t *>(messageIds.Elements()),
557 messageIds.Length(), this);
558 }
559
560 if (NS_FAILED(rv)) {
561 return NS_SUCCEEDED(NotifyDeleteMessageFailed(nsIMobileMessageCallback::INTERNAL_ERROR));
562 }
563
564 return true;
565 }
566
567 bool
568 SmsRequestParent::DoRequest(const MarkMessageReadRequest& aRequest)
569 {
570 nsresult rv = NS_ERROR_FAILURE;
571
572 nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
573 do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
574 if (dbService) {
575 rv = dbService->MarkMessageRead(aRequest.messageId(), aRequest.value(),
576 aRequest.sendReadReport(), this);
577 }
578
579 if (NS_FAILED(rv)) {
580 return NS_SUCCEEDED(NotifyMarkMessageReadFailed(nsIMobileMessageCallback::INTERNAL_ERROR));
581 }
582
583 return true;
584 }
585
586 bool
587 SmsRequestParent::DoRequest(const GetSegmentInfoForTextRequest& aRequest)
588 {
589 nsresult rv = NS_ERROR_FAILURE;
590
591 nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
592 if (smsService) {
593 rv = smsService->GetSegmentInfoForText(aRequest.text(), this);
594 }
595
596 if (NS_FAILED(rv)) {
597 return NS_SUCCEEDED(NotifyGetSegmentInfoForTextFailed(
598 nsIMobileMessageCallback::INTERNAL_ERROR));
599 }
600
601 return true;
602 }
603
604 nsresult
605 SmsRequestParent::SendReply(const MessageReply& aReply)
606 {
607 // The child process could die before this asynchronous notification, in which
608 // case ActorDestroy() was called and mActorDestroyed is set to true. Return
609 // an error here to avoid sending a message to the dead process.
610 NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
611
612 return Send__delete__(this, aReply) ? NS_OK : NS_ERROR_FAILURE;
613 }
614
615 // nsIMobileMessageCallback
616
617 NS_IMETHODIMP
618 SmsRequestParent::NotifyMessageSent(nsISupports *aMessage)
619 {
620 NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
621
622 nsCOMPtr<nsIDOMMozMmsMessage> mms = do_QueryInterface(aMessage);
623 if (mms) {
624 MmsMessage *msg = static_cast<MmsMessage*>(mms.get());
625 ContentParent *parent = static_cast<ContentParent*>(Manager()->Manager());
626 MmsMessageData data;
627 if (!msg->GetData(parent, data)) {
628 return NS_ERROR_FAILURE;
629 }
630 return SendReply(ReplyMessageSend(MobileMessageData(data)));
631 }
632
633 nsCOMPtr<nsIDOMMozSmsMessage> sms = do_QueryInterface(aMessage);
634 if (sms) {
635 SmsMessage* msg = static_cast<SmsMessage*>(sms.get());
636 return SendReply(ReplyMessageSend(MobileMessageData(msg->GetData())));
637 }
638
639 return NS_ERROR_FAILURE;
640 }
641
642 NS_IMETHODIMP
643 SmsRequestParent::NotifySendMessageFailed(int32_t aError)
644 {
645 return SendReply(ReplyMessageSendFail(aError));
646 }
647
648 NS_IMETHODIMP
649 SmsRequestParent::NotifyMessageGot(nsISupports *aMessage)
650 {
651 NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
652
653 nsCOMPtr<nsIDOMMozMmsMessage> mms = do_QueryInterface(aMessage);
654 if (mms) {
655 MmsMessage *msg = static_cast<MmsMessage*>(mms.get());
656 ContentParent *parent = static_cast<ContentParent*>(Manager()->Manager());
657 MmsMessageData data;
658 if (!msg->GetData(parent, data)) {
659 return NS_ERROR_FAILURE;
660 }
661 return SendReply(ReplyGetMessage(MobileMessageData(data)));
662 }
663
664 nsCOMPtr<nsIDOMMozSmsMessage> sms = do_QueryInterface(aMessage);
665 if (sms) {
666 SmsMessage* msg = static_cast<SmsMessage*>(sms.get());
667 return SendReply(ReplyGetMessage(MobileMessageData(msg->GetData())));
668 }
669
670 return NS_ERROR_FAILURE;
671 }
672
673 NS_IMETHODIMP
674 SmsRequestParent::NotifyGetMessageFailed(int32_t aError)
675 {
676 return SendReply(ReplyGetMessageFail(aError));
677 }
678
679 NS_IMETHODIMP
680 SmsRequestParent::NotifyMessageDeleted(bool *aDeleted, uint32_t aSize)
681 {
682 ReplyMessageDelete data;
683 data.deleted().AppendElements(aDeleted, aSize);
684 return SendReply(data);
685 }
686
687 NS_IMETHODIMP
688 SmsRequestParent::NotifyDeleteMessageFailed(int32_t aError)
689 {
690 return SendReply(ReplyMessageDeleteFail(aError));
691 }
692
693 NS_IMETHODIMP
694 SmsRequestParent::NotifyMessageMarkedRead(bool aRead)
695 {
696 return SendReply(ReplyMarkeMessageRead(aRead));
697 }
698
699 NS_IMETHODIMP
700 SmsRequestParent::NotifyMarkMessageReadFailed(int32_t aError)
701 {
702 return SendReply(ReplyMarkeMessageReadFail(aError));
703 }
704
705 NS_IMETHODIMP
706 SmsRequestParent::NotifySegmentInfoForTextGot(nsIDOMMozSmsSegmentInfo *aInfo)
707 {
708 SmsSegmentInfo* info = static_cast<SmsSegmentInfo*>(aInfo);
709 return SendReply(ReplyGetSegmentInfoForText(info->GetData()));
710 }
711
712 NS_IMETHODIMP
713 SmsRequestParent::NotifyGetSegmentInfoForTextFailed(int32_t aError)
714 {
715 return SendReply(ReplyGetSegmentInfoForTextFail(aError));
716 }
717
718 NS_IMETHODIMP
719 SmsRequestParent::NotifyGetSmscAddress(const nsAString& aSmscAddress)
720 {
721 return SendReply(ReplyGetSmscAddress(nsString(aSmscAddress)));
722 }
723
724 NS_IMETHODIMP
725 SmsRequestParent::NotifyGetSmscAddressFailed(int32_t aError)
726 {
727 return SendReply(ReplyGetSmscAddressFail(aError));
728 }
729
730 /*******************************************************************************
731 * MobileMessageCursorParent
732 ******************************************************************************/
733
734 NS_IMPL_ISUPPORTS(MobileMessageCursorParent, nsIMobileMessageCursorCallback)
735
736 void
737 MobileMessageCursorParent::ActorDestroy(ActorDestroyReason aWhy)
738 {
739 // Two possible scenarios here:
740 // 1) When parent fails to SendNotifyResult() in NotifyCursorResult(), it's
741 // destroyed without nulling out mContinueCallback.
742 // 2) When parent dies normally, mContinueCallback should have been cleared in
743 // NotifyCursorError(), but just ensure this again.
744 mContinueCallback = nullptr;
745 }
746
747 bool
748 MobileMessageCursorParent::RecvContinue()
749 {
750 MOZ_ASSERT(mContinueCallback);
751
752 if (NS_FAILED(mContinueCallback->HandleContinue())) {
753 return NS_SUCCEEDED(NotifyCursorError(nsIMobileMessageCallback::INTERNAL_ERROR));
754 }
755
756 return true;
757 }
758
759 bool
760 MobileMessageCursorParent::DoRequest(const CreateMessageCursorRequest& aRequest)
761 {
762 nsresult rv = NS_ERROR_FAILURE;
763
764 nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
765 do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
766 if (dbService) {
767 nsCOMPtr<nsIDOMMozSmsFilter> filter = new SmsFilter(aRequest.filter());
768 bool reverse = aRequest.reverse();
769
770 rv = dbService->CreateMessageCursor(filter, reverse, this,
771 getter_AddRefs(mContinueCallback));
772 }
773
774 if (NS_FAILED(rv)) {
775 return NS_SUCCEEDED(NotifyCursorError(nsIMobileMessageCallback::INTERNAL_ERROR));
776 }
777
778 return true;
779 }
780
781 bool
782 MobileMessageCursorParent::DoRequest(const CreateThreadCursorRequest& aRequest)
783 {
784 nsresult rv = NS_ERROR_FAILURE;
785
786 nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
787 do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
788 if (dbService) {
789 rv = dbService->CreateThreadCursor(this,
790 getter_AddRefs(mContinueCallback));
791 }
792
793 if (NS_FAILED(rv)) {
794 return NS_SUCCEEDED(NotifyCursorError(nsIMobileMessageCallback::INTERNAL_ERROR));
795 }
796
797 return true;
798 }
799
800 // nsIMobileMessageCursorCallback
801
802 NS_IMETHODIMP
803 MobileMessageCursorParent::NotifyCursorError(int32_t aError)
804 {
805 // The child process could die before this asynchronous notification, in which
806 // case ActorDestroy() was called and mContinueCallback is now null. Return an
807 // error here to avoid sending a message to the dead process.
808 NS_ENSURE_TRUE(mContinueCallback, NS_ERROR_FAILURE);
809
810 mContinueCallback = nullptr;
811
812 return Send__delete__(this, aError) ? NS_OK : NS_ERROR_FAILURE;
813 }
814
815 NS_IMETHODIMP
816 MobileMessageCursorParent::NotifyCursorResult(nsISupports* aResult)
817 {
818 // The child process could die before this asynchronous notification, in which
819 // case ActorDestroy() was called and mContinueCallback is now null. Return an
820 // error here to avoid sending a message to the dead process.
821 NS_ENSURE_TRUE(mContinueCallback, NS_ERROR_FAILURE);
822
823 nsCOMPtr<nsIDOMMozSmsMessage> iSms = do_QueryInterface(aResult);
824 if (iSms) {
825 SmsMessage* message = static_cast<SmsMessage*>(aResult);
826 return SendNotifyResult(MobileMessageCursorData(message->GetData()))
827 ? NS_OK : NS_ERROR_FAILURE;
828 }
829
830 nsCOMPtr<nsIDOMMozMmsMessage> iMms = do_QueryInterface(aResult);
831 if (iMms) {
832 MmsMessage* message = static_cast<MmsMessage*>(aResult);
833 ContentParent* parent = static_cast<ContentParent*>(Manager()->Manager());
834 MmsMessageData data;
835 if (!message->GetData(parent, data)) {
836 return NS_ERROR_FAILURE;
837 }
838 return SendNotifyResult(MobileMessageCursorData(data))
839 ? NS_OK : NS_ERROR_FAILURE;
840 }
841
842 nsCOMPtr<nsIDOMMozMobileMessageThread> iThread = do_QueryInterface(aResult);
843 if (iThread) {
844 MobileMessageThread* thread = static_cast<MobileMessageThread*>(aResult);
845 return SendNotifyResult(MobileMessageCursorData(thread->GetData()))
846 ? NS_OK : NS_ERROR_FAILURE;
847 }
848
849 MOZ_CRASH("Received invalid response parameters!");
850 }
851
852 NS_IMETHODIMP
853 MobileMessageCursorParent::NotifyCursorDone()
854 {
855 return NotifyCursorError(nsIMobileMessageCallback::SUCCESS_NO_ERROR);
856 }
857
858 } // namespace mobilemessage
859 } // namespace dom
860 } // namespace mozilla

mercurial