Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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/. */
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"
30 namespace mozilla {
31 namespace dom {
32 namespace mobilemessage {
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);
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 }
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 }
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 }
69 return obj;
70 }
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);
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 }
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 }
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 }
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 }
121 if (!JS_DefineProperty(aCx, paramsObj, "attachments", attachmentArray, 0)) {
122 return false;
123 }
125 aParam->setObject(*paramsObj);
126 return true;
127 }
129 NS_IMPL_ISUPPORTS(SmsParent, nsIObserver)
131 SmsParent::SmsParent()
132 {
133 MOZ_COUNT_CTOR(SmsParent);
134 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
135 if (!obs) {
136 return;
137 }
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 }
151 void
152 SmsParent::ActorDestroy(ActorDestroyReason why)
153 {
154 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
155 if (!obs) {
156 return;
157 }
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 }
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 }
182 unused << SendNotifyReceivedMessage(msgData);
183 return NS_OK;
184 }
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 }
193 unused << SendNotifyRetrievingMessage(msgData);
194 return NS_OK;
195 }
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 }
204 unused << SendNotifySendingMessage(msgData);
205 return NS_OK;
206 }
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 }
215 unused << SendNotifySentMessage(msgData);
216 return NS_OK;
217 }
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 }
226 unused << SendNotifyFailedMessage(msgData);
227 return NS_OK;
228 }
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 }
237 unused << SendNotifyDeliverySuccessMessage(msgData);
238 return NS_OK;
239 }
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 }
248 unused << SendNotifyDeliveryErrorMessage(msgData);
249 return NS_OK;
250 }
252 if (!strcmp(aTopic, kSilentSmsReceivedObserverTopic)) {
253 nsCOMPtr<nsIDOMMozSmsMessage> smsMsg = do_QueryInterface(aSubject);
254 if (!smsMsg) {
255 return NS_OK;
256 }
258 nsString sender;
259 if (NS_FAILED(smsMsg->GetSender(sender)) ||
260 !mSilentNumbers.Contains(sender)) {
261 return NS_OK;
262 }
264 MobileMessageData msgData =
265 static_cast<SmsMessage*>(smsMsg.get())->GetData();
266 unused << SendNotifyReceivedSilentMessage(msgData);
267 return NS_OK;
268 }
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 }
278 unused << SendNotifyReadSuccessMessage(msgData);
279 return NS_OK;
280 }
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 }
289 unused << SendNotifyReadErrorMessage(msgData);
290 return NS_OK;
291 }
294 return NS_OK;
295 }
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 }
312 nsCOMPtr<nsIDOMMozSmsMessage> smsMsg = do_QueryInterface(aMsg);
313 if (smsMsg) {
314 aData = static_cast<SmsMessage*>(smsMsg.get())->GetData();
315 return true;
316 }
318 NS_WARNING("Cannot get MobileMessageData");
319 return false;
320 }
322 bool
323 SmsParent::RecvAddSilentNumber(const nsString& aNumber)
324 {
325 if (mSilentNumbers.Contains(aNumber)) {
326 return true;
327 }
329 nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
330 NS_ENSURE_TRUE(smsService, true);
332 nsresult rv = smsService->AddSilentNumber(aNumber);
333 if (NS_SUCCEEDED(rv)) {
334 mSilentNumbers.AppendElement(aNumber);
335 }
337 return true;
338 }
340 bool
341 SmsParent::RecvRemoveSilentNumber(const nsString& aNumber)
342 {
343 if (!mSilentNumbers.Contains(aNumber)) {
344 return true;
345 }
347 nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
348 NS_ENSURE_TRUE(smsService, true);
350 nsresult rv = smsService->RemoveSilentNumber(aNumber);
351 if (NS_SUCCEEDED(rv)) {
352 mSilentNumbers.RemoveElement(aNumber);
353 }
355 return true;
356 }
358 bool
359 SmsParent::RecvPSmsRequestConstructor(PSmsRequestParent* aActor,
360 const IPCSmsRequest& aRequest)
361 {
362 SmsRequestParent* actor = static_cast<SmsRequestParent*>(aActor);
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 }
383 return false;
384 }
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();
394 return actor;
395 }
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 }
405 bool
406 SmsParent::RecvPMobileMessageCursorConstructor(PMobileMessageCursorParent* aActor,
407 const IPCMobileMessageCursor& aRequest)
408 {
409 MobileMessageCursorParent* actor =
410 static_cast<MobileMessageCursorParent*>(aActor);
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 }
421 return false;
422 }
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();
432 return actor;
433 }
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 }
443 /*******************************************************************************
444 * SmsRequestParent
445 ******************************************************************************/
447 NS_IMPL_ISUPPORTS(SmsRequestParent, nsIMobileMessageCallback)
449 void
450 SmsRequestParent::ActorDestroy(ActorDestroyReason aWhy)
451 {
452 mActorDestroyed = true;
453 }
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);
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);
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 }
495 bool
496 SmsRequestParent::DoRequest(const RetrieveMessageRequest& aRequest)
497 {
498 nsresult rv = NS_ERROR_FAILURE;
500 nsCOMPtr<nsIMmsService> mmsService = do_GetService(MMS_SERVICE_CONTRACTID);
501 if (mmsService) {
502 rv = mmsService->Retrieve(aRequest.messageId(), this);
503 }
505 if (NS_FAILED(rv)) {
506 return NS_SUCCEEDED(NotifyGetMessageFailed(nsIMobileMessageCallback::INTERNAL_ERROR));
507 }
509 return true;
510 }
512 bool
513 SmsRequestParent::DoRequest(const GetMessageRequest& aRequest)
514 {
515 nsresult rv = NS_ERROR_FAILURE;
517 nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
518 do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
519 if (dbService) {
520 rv = dbService->GetMessageMoz(aRequest.messageId(), this);
521 }
523 if (NS_FAILED(rv)) {
524 return NS_SUCCEEDED(NotifyGetMessageFailed(nsIMobileMessageCallback::INTERNAL_ERROR));
525 }
527 return true;
528 }
530 bool
531 SmsRequestParent::DoRequest(const GetSmscAddressRequest& aRequest)
532 {
533 nsresult rv = NS_ERROR_FAILURE;
535 nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
536 if (smsService) {
537 rv = smsService->GetSmscAddress(aRequest.serviceId(), this);
538 }
540 if (NS_FAILED(rv)) {
541 return NS_SUCCEEDED(NotifyGetSmscAddressFailed(nsIMobileMessageCallback::INTERNAL_ERROR));
542 }
544 return true;
545 }
547 bool
548 SmsRequestParent::DoRequest(const DeleteMessageRequest& aRequest)
549 {
550 nsresult rv = NS_ERROR_FAILURE;
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 }
560 if (NS_FAILED(rv)) {
561 return NS_SUCCEEDED(NotifyDeleteMessageFailed(nsIMobileMessageCallback::INTERNAL_ERROR));
562 }
564 return true;
565 }
567 bool
568 SmsRequestParent::DoRequest(const MarkMessageReadRequest& aRequest)
569 {
570 nsresult rv = NS_ERROR_FAILURE;
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 }
579 if (NS_FAILED(rv)) {
580 return NS_SUCCEEDED(NotifyMarkMessageReadFailed(nsIMobileMessageCallback::INTERNAL_ERROR));
581 }
583 return true;
584 }
586 bool
587 SmsRequestParent::DoRequest(const GetSegmentInfoForTextRequest& aRequest)
588 {
589 nsresult rv = NS_ERROR_FAILURE;
591 nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
592 if (smsService) {
593 rv = smsService->GetSegmentInfoForText(aRequest.text(), this);
594 }
596 if (NS_FAILED(rv)) {
597 return NS_SUCCEEDED(NotifyGetSegmentInfoForTextFailed(
598 nsIMobileMessageCallback::INTERNAL_ERROR));
599 }
601 return true;
602 }
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);
612 return Send__delete__(this, aReply) ? NS_OK : NS_ERROR_FAILURE;
613 }
615 // nsIMobileMessageCallback
617 NS_IMETHODIMP
618 SmsRequestParent::NotifyMessageSent(nsISupports *aMessage)
619 {
620 NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
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 }
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 }
639 return NS_ERROR_FAILURE;
640 }
642 NS_IMETHODIMP
643 SmsRequestParent::NotifySendMessageFailed(int32_t aError)
644 {
645 return SendReply(ReplyMessageSendFail(aError));
646 }
648 NS_IMETHODIMP
649 SmsRequestParent::NotifyMessageGot(nsISupports *aMessage)
650 {
651 NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
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 }
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 }
670 return NS_ERROR_FAILURE;
671 }
673 NS_IMETHODIMP
674 SmsRequestParent::NotifyGetMessageFailed(int32_t aError)
675 {
676 return SendReply(ReplyGetMessageFail(aError));
677 }
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 }
687 NS_IMETHODIMP
688 SmsRequestParent::NotifyDeleteMessageFailed(int32_t aError)
689 {
690 return SendReply(ReplyMessageDeleteFail(aError));
691 }
693 NS_IMETHODIMP
694 SmsRequestParent::NotifyMessageMarkedRead(bool aRead)
695 {
696 return SendReply(ReplyMarkeMessageRead(aRead));
697 }
699 NS_IMETHODIMP
700 SmsRequestParent::NotifyMarkMessageReadFailed(int32_t aError)
701 {
702 return SendReply(ReplyMarkeMessageReadFail(aError));
703 }
705 NS_IMETHODIMP
706 SmsRequestParent::NotifySegmentInfoForTextGot(nsIDOMMozSmsSegmentInfo *aInfo)
707 {
708 SmsSegmentInfo* info = static_cast<SmsSegmentInfo*>(aInfo);
709 return SendReply(ReplyGetSegmentInfoForText(info->GetData()));
710 }
712 NS_IMETHODIMP
713 SmsRequestParent::NotifyGetSegmentInfoForTextFailed(int32_t aError)
714 {
715 return SendReply(ReplyGetSegmentInfoForTextFail(aError));
716 }
718 NS_IMETHODIMP
719 SmsRequestParent::NotifyGetSmscAddress(const nsAString& aSmscAddress)
720 {
721 return SendReply(ReplyGetSmscAddress(nsString(aSmscAddress)));
722 }
724 NS_IMETHODIMP
725 SmsRequestParent::NotifyGetSmscAddressFailed(int32_t aError)
726 {
727 return SendReply(ReplyGetSmscAddressFail(aError));
728 }
730 /*******************************************************************************
731 * MobileMessageCursorParent
732 ******************************************************************************/
734 NS_IMPL_ISUPPORTS(MobileMessageCursorParent, nsIMobileMessageCursorCallback)
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 }
747 bool
748 MobileMessageCursorParent::RecvContinue()
749 {
750 MOZ_ASSERT(mContinueCallback);
752 if (NS_FAILED(mContinueCallback->HandleContinue())) {
753 return NS_SUCCEEDED(NotifyCursorError(nsIMobileMessageCallback::INTERNAL_ERROR));
754 }
756 return true;
757 }
759 bool
760 MobileMessageCursorParent::DoRequest(const CreateMessageCursorRequest& aRequest)
761 {
762 nsresult rv = NS_ERROR_FAILURE;
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();
770 rv = dbService->CreateMessageCursor(filter, reverse, this,
771 getter_AddRefs(mContinueCallback));
772 }
774 if (NS_FAILED(rv)) {
775 return NS_SUCCEEDED(NotifyCursorError(nsIMobileMessageCallback::INTERNAL_ERROR));
776 }
778 return true;
779 }
781 bool
782 MobileMessageCursorParent::DoRequest(const CreateThreadCursorRequest& aRequest)
783 {
784 nsresult rv = NS_ERROR_FAILURE;
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 }
793 if (NS_FAILED(rv)) {
794 return NS_SUCCEEDED(NotifyCursorError(nsIMobileMessageCallback::INTERNAL_ERROR));
795 }
797 return true;
798 }
800 // nsIMobileMessageCursorCallback
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);
810 mContinueCallback = nullptr;
812 return Send__delete__(this, aError) ? NS_OK : NS_ERROR_FAILURE;
813 }
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);
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 }
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 }
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 }
849 MOZ_CRASH("Received invalid response parameters!");
850 }
852 NS_IMETHODIMP
853 MobileMessageCursorParent::NotifyCursorDone()
854 {
855 return NotifyCursorError(nsIMobileMessageCallback::SUCCESS_NO_ERROR);
856 }
858 } // namespace mobilemessage
859 } // namespace dom
860 } // namespace mozilla