dom/mobilemessage/src/ipc/SmsParent.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

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

mercurial