dom/mobilemessage/src/ipc/SmsParent.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/mobilemessage/src/ipc/SmsParent.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,860 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.7 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "SmsParent.h"
    1.10 +#include "nsISmsService.h"
    1.11 +#include "nsIMmsService.h"
    1.12 +#include "nsIObserverService.h"
    1.13 +#include "mozilla/Services.h"
    1.14 +#include "nsIDOMMozSmsMessage.h"
    1.15 +#include "nsIDOMMozMmsMessage.h"
    1.16 +#include "mozilla/unused.h"
    1.17 +#include "SmsMessage.h"
    1.18 +#include "MmsMessage.h"
    1.19 +#include "nsIMobileMessageDatabaseService.h"
    1.20 +#include "SmsFilter.h"
    1.21 +#include "SmsSegmentInfo.h"
    1.22 +#include "MobileMessageThread.h"
    1.23 +#include "nsIDOMFile.h"
    1.24 +#include "mozilla/dom/ipc/Blob.h"
    1.25 +#include "mozilla/dom/ContentParent.h"
    1.26 +#include "mozilla/dom/mobilemessage/Constants.h" // For MessageType
    1.27 +#include "nsContentUtils.h"
    1.28 +#include "nsTArrayHelpers.h"
    1.29 +#include "nsCxPusher.h"
    1.30 +#include "xpcpublic.h"
    1.31 +#include "nsServiceManagerUtils.h"
    1.32 +
    1.33 +namespace mozilla {
    1.34 +namespace dom {
    1.35 +namespace mobilemessage {
    1.36 +
    1.37 +static JSObject*
    1.38 +MmsAttachmentDataToJSObject(JSContext* aContext,
    1.39 +                            const MmsAttachmentData& aAttachment)
    1.40 +{
    1.41 +  JS::Rooted<JSObject*> obj(aContext, JS_NewObject(aContext, nullptr, JS::NullPtr(),
    1.42 +                                                   JS::NullPtr()));
    1.43 +  NS_ENSURE_TRUE(obj, nullptr);
    1.44 +
    1.45 +  JS::Rooted<JSString*> idStr(aContext, JS_NewUCStringCopyN(aContext,
    1.46 +                                                            aAttachment.id().get(),
    1.47 +                                                            aAttachment.id().Length()));
    1.48 +  NS_ENSURE_TRUE(idStr, nullptr);
    1.49 +  if (!JS_DefineProperty(aContext, obj, "id", idStr, 0)) {
    1.50 +    return nullptr;
    1.51 +  }
    1.52 +
    1.53 +  JS::Rooted<JSString*> locStr(aContext, JS_NewUCStringCopyN(aContext,
    1.54 +                                                             aAttachment.location().get(),
    1.55 +                                                             aAttachment.location().Length()));
    1.56 +  NS_ENSURE_TRUE(locStr, nullptr);
    1.57 +  if (!JS_DefineProperty(aContext, obj, "location", locStr, 0)) {
    1.58 +    return nullptr;
    1.59 +  }
    1.60 +
    1.61 +  nsCOMPtr<nsIDOMBlob> blob = static_cast<BlobParent*>(aAttachment.contentParent())->GetBlob();
    1.62 +  JS::Rooted<JS::Value> content(aContext);
    1.63 +  nsresult rv = nsContentUtils::WrapNative(aContext,
    1.64 +                                           blob,
    1.65 +                                           &NS_GET_IID(nsIDOMBlob),
    1.66 +                                           &content);
    1.67 +  NS_ENSURE_SUCCESS(rv, nullptr);
    1.68 +  if (!JS_DefineProperty(aContext, obj, "content", content, 0)) {
    1.69 +    return nullptr;
    1.70 +  }
    1.71 +
    1.72 +  return obj;
    1.73 +}
    1.74 +
    1.75 +static bool
    1.76 +GetParamsFromSendMmsMessageRequest(JSContext* aCx,
    1.77 +                                   const SendMmsMessageRequest& aRequest,
    1.78 +                                   JS::Value* aParam)
    1.79 +{
    1.80 +  JS::Rooted<JSObject*> paramsObj(aCx, JS_NewObject(aCx, nullptr, JS::NullPtr(), JS::NullPtr()));
    1.81 +  NS_ENSURE_TRUE(paramsObj, false);
    1.82 +
    1.83 +  // smil
    1.84 +  JS::Rooted<JSString*> smilStr(aCx, JS_NewUCStringCopyN(aCx,
    1.85 +                                                         aRequest.smil().get(),
    1.86 +                                                         aRequest.smil().Length()));
    1.87 +  NS_ENSURE_TRUE(smilStr, false);
    1.88 +  if(!JS_DefineProperty(aCx, paramsObj, "smil", smilStr, 0)) {
    1.89 +    return false;
    1.90 +  }
    1.91 +
    1.92 +  // subject
    1.93 +  JS::Rooted<JSString*> subjectStr(aCx, JS_NewUCStringCopyN(aCx,
    1.94 +                                                            aRequest.subject().get(),
    1.95 +                                                            aRequest.subject().Length()));
    1.96 +  NS_ENSURE_TRUE(subjectStr, false);
    1.97 +  if(!JS_DefineProperty(aCx, paramsObj, "subject", subjectStr, 0)) {
    1.98 +    return false;
    1.99 +  }
   1.100 +
   1.101 +  // receivers
   1.102 +  JS::Rooted<JSObject*> receiverArray(aCx);
   1.103 +  if (NS_FAILED(nsTArrayToJSArray(aCx,
   1.104 +                                  aRequest.receivers(),
   1.105 +                                  receiverArray.address()))) {
   1.106 +    return false;
   1.107 +  }
   1.108 +  if (!JS_DefineProperty(aCx, paramsObj, "receivers", receiverArray, 0)) {
   1.109 +    return false;
   1.110 +  }
   1.111 +
   1.112 +  // attachments
   1.113 +  JS::Rooted<JSObject*> attachmentArray(aCx, JS_NewArrayObject(aCx,
   1.114 +                                                               aRequest.attachments().Length()));
   1.115 +  for (uint32_t i = 0; i < aRequest.attachments().Length(); i++) {
   1.116 +    JS::Rooted<JSObject*> obj(aCx,
   1.117 +      MmsAttachmentDataToJSObject(aCx, aRequest.attachments().ElementAt(i)));
   1.118 +    NS_ENSURE_TRUE(obj, false);
   1.119 +    if (!JS_SetElement(aCx, attachmentArray, i, obj)) {
   1.120 +      return false;
   1.121 +    }
   1.122 +  }
   1.123 +
   1.124 +  if (!JS_DefineProperty(aCx, paramsObj, "attachments", attachmentArray, 0)) {
   1.125 +    return false;
   1.126 +  }
   1.127 +
   1.128 +  aParam->setObject(*paramsObj);
   1.129 +  return true;
   1.130 +}
   1.131 +
   1.132 +NS_IMPL_ISUPPORTS(SmsParent, nsIObserver)
   1.133 +
   1.134 +SmsParent::SmsParent()
   1.135 +{
   1.136 +  MOZ_COUNT_CTOR(SmsParent);
   1.137 +  nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   1.138 +  if (!obs) {
   1.139 +    return;
   1.140 +  }
   1.141 +
   1.142 +  obs->AddObserver(this, kSmsReceivedObserverTopic, false);
   1.143 +  obs->AddObserver(this, kSmsRetrievingObserverTopic, false);
   1.144 +  obs->AddObserver(this, kSmsSendingObserverTopic, false);
   1.145 +  obs->AddObserver(this, kSmsSentObserverTopic, false);
   1.146 +  obs->AddObserver(this, kSmsFailedObserverTopic, false);
   1.147 +  obs->AddObserver(this, kSmsDeliverySuccessObserverTopic, false);
   1.148 +  obs->AddObserver(this, kSmsDeliveryErrorObserverTopic, false);
   1.149 +  obs->AddObserver(this, kSilentSmsReceivedObserverTopic, false);
   1.150 +  obs->AddObserver(this, kSmsReadSuccessObserverTopic, false);
   1.151 +  obs->AddObserver(this, kSmsReadErrorObserverTopic, false);
   1.152 +}
   1.153 +
   1.154 +void
   1.155 +SmsParent::ActorDestroy(ActorDestroyReason why)
   1.156 +{
   1.157 +  nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   1.158 +  if (!obs) {
   1.159 +    return;
   1.160 +  }
   1.161 +
   1.162 +  obs->RemoveObserver(this, kSmsReceivedObserverTopic);
   1.163 +  obs->RemoveObserver(this, kSmsRetrievingObserverTopic);
   1.164 +  obs->RemoveObserver(this, kSmsSendingObserverTopic);
   1.165 +  obs->RemoveObserver(this, kSmsSentObserverTopic);
   1.166 +  obs->RemoveObserver(this, kSmsFailedObserverTopic);
   1.167 +  obs->RemoveObserver(this, kSmsDeliverySuccessObserverTopic);
   1.168 +  obs->RemoveObserver(this, kSmsDeliveryErrorObserverTopic);
   1.169 +  obs->RemoveObserver(this, kSilentSmsReceivedObserverTopic);
   1.170 +  obs->RemoveObserver(this, kSmsReadSuccessObserverTopic);
   1.171 +  obs->RemoveObserver(this, kSmsReadErrorObserverTopic);
   1.172 +}
   1.173 +
   1.174 +NS_IMETHODIMP
   1.175 +SmsParent::Observe(nsISupports* aSubject, const char* aTopic,
   1.176 +                   const char16_t* aData)
   1.177 +{
   1.178 +  if (!strcmp(aTopic, kSmsReceivedObserverTopic)) {
   1.179 +    MobileMessageData msgData;
   1.180 +    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
   1.181 +      NS_ERROR("Got a 'sms-received' topic without a valid message!");
   1.182 +      return NS_OK;
   1.183 +    }
   1.184 +
   1.185 +    unused << SendNotifyReceivedMessage(msgData);
   1.186 +    return NS_OK;
   1.187 +  }
   1.188 +
   1.189 +  if (!strcmp(aTopic, kSmsRetrievingObserverTopic)) {
   1.190 +    MobileMessageData msgData;
   1.191 +    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
   1.192 +      NS_ERROR("Got a 'sms-retrieving' topic without a valid message!");
   1.193 +      return NS_OK;
   1.194 +    }
   1.195 +
   1.196 +    unused << SendNotifyRetrievingMessage(msgData);
   1.197 +    return NS_OK;
   1.198 +  }
   1.199 +
   1.200 +  if (!strcmp(aTopic, kSmsSendingObserverTopic)) {
   1.201 +    MobileMessageData msgData;
   1.202 +    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
   1.203 +      NS_ERROR("Got a 'sms-sending' topic without a valid message!");
   1.204 +      return NS_OK;
   1.205 +    }
   1.206 +
   1.207 +    unused << SendNotifySendingMessage(msgData);
   1.208 +    return NS_OK;
   1.209 +  }
   1.210 +
   1.211 +  if (!strcmp(aTopic, kSmsSentObserverTopic)) {
   1.212 +    MobileMessageData msgData;
   1.213 +    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
   1.214 +      NS_ERROR("Got a 'sms-sent' topic without a valid message!");
   1.215 +      return NS_OK;
   1.216 +    }
   1.217 +
   1.218 +    unused << SendNotifySentMessage(msgData);
   1.219 +    return NS_OK;
   1.220 +  }
   1.221 +
   1.222 +  if (!strcmp(aTopic, kSmsFailedObserverTopic)) {
   1.223 +    MobileMessageData msgData;
   1.224 +    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
   1.225 +      NS_ERROR("Got a 'sms-failed' topic without a valid message!");
   1.226 +      return NS_OK;
   1.227 +    }
   1.228 +
   1.229 +    unused << SendNotifyFailedMessage(msgData);
   1.230 +    return NS_OK;
   1.231 +  }
   1.232 +
   1.233 +  if (!strcmp(aTopic, kSmsDeliverySuccessObserverTopic)) {
   1.234 +    MobileMessageData msgData;
   1.235 +    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
   1.236 +      NS_ERROR("Got a 'sms-sending' topic without a valid message!");
   1.237 +      return NS_OK;
   1.238 +    }
   1.239 +
   1.240 +    unused << SendNotifyDeliverySuccessMessage(msgData);
   1.241 +    return NS_OK;
   1.242 +  }
   1.243 +
   1.244 +  if (!strcmp(aTopic, kSmsDeliveryErrorObserverTopic)) {
   1.245 +    MobileMessageData msgData;
   1.246 +    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
   1.247 +      NS_ERROR("Got a 'sms-delivery-error' topic without a valid message!");
   1.248 +      return NS_OK;
   1.249 +    }
   1.250 +
   1.251 +    unused << SendNotifyDeliveryErrorMessage(msgData);
   1.252 +    return NS_OK;
   1.253 +  }
   1.254 +
   1.255 +  if (!strcmp(aTopic, kSilentSmsReceivedObserverTopic)) {
   1.256 +    nsCOMPtr<nsIDOMMozSmsMessage> smsMsg = do_QueryInterface(aSubject);
   1.257 +    if (!smsMsg) {
   1.258 +      return NS_OK;
   1.259 +    }
   1.260 +
   1.261 +    nsString sender;
   1.262 +    if (NS_FAILED(smsMsg->GetSender(sender)) ||
   1.263 +        !mSilentNumbers.Contains(sender)) {
   1.264 +      return NS_OK;
   1.265 +    }
   1.266 +
   1.267 +    MobileMessageData msgData =
   1.268 +      static_cast<SmsMessage*>(smsMsg.get())->GetData();
   1.269 +    unused << SendNotifyReceivedSilentMessage(msgData);
   1.270 +    return NS_OK;
   1.271 +  }
   1.272 +
   1.273 +
   1.274 +  if (!strcmp(aTopic, kSmsReadSuccessObserverTopic)) {
   1.275 +    MobileMessageData msgData;
   1.276 +    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
   1.277 +      NS_ERROR("Got a 'sms-read-success' topic without a valid message!");
   1.278 +      return NS_OK;
   1.279 +    }
   1.280 +
   1.281 +    unused << SendNotifyReadSuccessMessage(msgData);
   1.282 +    return NS_OK;
   1.283 +  }
   1.284 +
   1.285 +  if (!strcmp(aTopic, kSmsReadErrorObserverTopic)) {
   1.286 +    MobileMessageData msgData;
   1.287 +    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
   1.288 +      NS_ERROR("Got a 'sms-read-error' topic without a valid message!");
   1.289 +      return NS_OK;
   1.290 +    }
   1.291 +
   1.292 +    unused << SendNotifyReadErrorMessage(msgData);
   1.293 +    return NS_OK;
   1.294 +  }
   1.295 +
   1.296 +
   1.297 +  return NS_OK;
   1.298 +}
   1.299 +
   1.300 +bool
   1.301 +SmsParent::GetMobileMessageDataFromMessage(nsISupports *aMsg,
   1.302 +                                           MobileMessageData &aData)
   1.303 +{
   1.304 +  nsCOMPtr<nsIDOMMozMmsMessage> mmsMsg = do_QueryInterface(aMsg);
   1.305 +  if (mmsMsg) {
   1.306 +    MmsMessageData data;
   1.307 +    ContentParent *parent = static_cast<ContentParent*>(Manager());
   1.308 +    if (!static_cast<MmsMessage*>(mmsMsg.get())->GetData(parent, data)) {
   1.309 +      return false;
   1.310 +    }
   1.311 +    aData = data;
   1.312 +    return true;
   1.313 +  }
   1.314 +
   1.315 +  nsCOMPtr<nsIDOMMozSmsMessage> smsMsg = do_QueryInterface(aMsg);
   1.316 +  if (smsMsg) {
   1.317 +    aData = static_cast<SmsMessage*>(smsMsg.get())->GetData();
   1.318 +    return true;
   1.319 +  }
   1.320 +
   1.321 +  NS_WARNING("Cannot get MobileMessageData");
   1.322 +  return false;
   1.323 +}
   1.324 +
   1.325 +bool
   1.326 +SmsParent::RecvAddSilentNumber(const nsString& aNumber)
   1.327 +{
   1.328 +  if (mSilentNumbers.Contains(aNumber)) {
   1.329 +    return true;
   1.330 +  }
   1.331 +
   1.332 +  nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
   1.333 +  NS_ENSURE_TRUE(smsService, true);
   1.334 +
   1.335 +  nsresult rv = smsService->AddSilentNumber(aNumber);
   1.336 +  if (NS_SUCCEEDED(rv)) {
   1.337 +    mSilentNumbers.AppendElement(aNumber);
   1.338 +  }
   1.339 +
   1.340 +  return true;
   1.341 +}
   1.342 +
   1.343 +bool
   1.344 +SmsParent::RecvRemoveSilentNumber(const nsString& aNumber)
   1.345 +{
   1.346 +  if (!mSilentNumbers.Contains(aNumber)) {
   1.347 +    return true;
   1.348 +  }
   1.349 +
   1.350 +  nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
   1.351 +  NS_ENSURE_TRUE(smsService, true);
   1.352 +
   1.353 +  nsresult rv = smsService->RemoveSilentNumber(aNumber);
   1.354 +  if (NS_SUCCEEDED(rv)) {
   1.355 +    mSilentNumbers.RemoveElement(aNumber);
   1.356 +  }
   1.357 +
   1.358 +  return true;
   1.359 +}
   1.360 +
   1.361 +bool
   1.362 +SmsParent::RecvPSmsRequestConstructor(PSmsRequestParent* aActor,
   1.363 +                                      const IPCSmsRequest& aRequest)
   1.364 +{
   1.365 +  SmsRequestParent* actor = static_cast<SmsRequestParent*>(aActor);
   1.366 +
   1.367 +  switch (aRequest.type()) {
   1.368 +    case IPCSmsRequest::TSendMessageRequest:
   1.369 +      return actor->DoRequest(aRequest.get_SendMessageRequest());
   1.370 +    case IPCSmsRequest::TRetrieveMessageRequest:
   1.371 +      return actor->DoRequest(aRequest.get_RetrieveMessageRequest());
   1.372 +    case IPCSmsRequest::TGetMessageRequest:
   1.373 +      return actor->DoRequest(aRequest.get_GetMessageRequest());
   1.374 +    case IPCSmsRequest::TDeleteMessageRequest:
   1.375 +      return actor->DoRequest(aRequest.get_DeleteMessageRequest());
   1.376 +    case IPCSmsRequest::TMarkMessageReadRequest:
   1.377 +      return actor->DoRequest(aRequest.get_MarkMessageReadRequest());
   1.378 +    case IPCSmsRequest::TGetSegmentInfoForTextRequest:
   1.379 +      return actor->DoRequest(aRequest.get_GetSegmentInfoForTextRequest());
   1.380 +    case IPCSmsRequest::TGetSmscAddressRequest:
   1.381 +      return actor->DoRequest(aRequest.get_GetSmscAddressRequest());
   1.382 +    default:
   1.383 +      MOZ_CRASH("Unknown type!");
   1.384 +  }
   1.385 +
   1.386 +  return false;
   1.387 +}
   1.388 +
   1.389 +PSmsRequestParent*
   1.390 +SmsParent::AllocPSmsRequestParent(const IPCSmsRequest& aRequest)
   1.391 +{
   1.392 +  SmsRequestParent* actor = new SmsRequestParent();
   1.393 +  // Add an extra ref for IPDL. Will be released in
   1.394 +  // SmsParent::DeallocPSmsRequestParent().
   1.395 +  actor->AddRef();
   1.396 +
   1.397 +  return actor;
   1.398 +}
   1.399 +
   1.400 +bool
   1.401 +SmsParent::DeallocPSmsRequestParent(PSmsRequestParent* aActor)
   1.402 +{
   1.403 +  // SmsRequestParent is refcounted, must not be freed manually.
   1.404 +  static_cast<SmsRequestParent*>(aActor)->Release();
   1.405 +  return true;
   1.406 +}
   1.407 +
   1.408 +bool
   1.409 +SmsParent::RecvPMobileMessageCursorConstructor(PMobileMessageCursorParent* aActor,
   1.410 +                                               const IPCMobileMessageCursor& aRequest)
   1.411 +{
   1.412 +  MobileMessageCursorParent* actor =
   1.413 +    static_cast<MobileMessageCursorParent*>(aActor);
   1.414 +
   1.415 +  switch (aRequest.type()) {
   1.416 +    case IPCMobileMessageCursor::TCreateMessageCursorRequest:
   1.417 +      return actor->DoRequest(aRequest.get_CreateMessageCursorRequest());
   1.418 +    case IPCMobileMessageCursor::TCreateThreadCursorRequest:
   1.419 +      return actor->DoRequest(aRequest.get_CreateThreadCursorRequest());
   1.420 +    default:
   1.421 +      MOZ_CRASH("Unknown type!");
   1.422 +  }
   1.423 +
   1.424 +  return false;
   1.425 +}
   1.426 +
   1.427 +PMobileMessageCursorParent*
   1.428 +SmsParent::AllocPMobileMessageCursorParent(const IPCMobileMessageCursor& aRequest)
   1.429 +{
   1.430 +  MobileMessageCursorParent* actor = new MobileMessageCursorParent();
   1.431 +  // Add an extra ref for IPDL. Will be released in
   1.432 +  // SmsParent::DeallocPMobileMessageCursorParent().
   1.433 +  actor->AddRef();
   1.434 +
   1.435 +  return actor;
   1.436 +}
   1.437 +
   1.438 +bool
   1.439 +SmsParent::DeallocPMobileMessageCursorParent(PMobileMessageCursorParent* aActor)
   1.440 +{
   1.441 +  // MobileMessageCursorParent is refcounted, must not be freed manually.
   1.442 +  static_cast<MobileMessageCursorParent*>(aActor)->Release();
   1.443 +  return true;
   1.444 +}
   1.445 +
   1.446 +/*******************************************************************************
   1.447 + * SmsRequestParent
   1.448 + ******************************************************************************/
   1.449 +
   1.450 +NS_IMPL_ISUPPORTS(SmsRequestParent, nsIMobileMessageCallback)
   1.451 +
   1.452 +void
   1.453 +SmsRequestParent::ActorDestroy(ActorDestroyReason aWhy)
   1.454 +{
   1.455 +  mActorDestroyed = true;
   1.456 +}
   1.457 +
   1.458 +bool
   1.459 +SmsRequestParent::DoRequest(const SendMessageRequest& aRequest)
   1.460 +{
   1.461 +  switch(aRequest.type()) {
   1.462 +  case SendMessageRequest::TSendSmsMessageRequest: {
   1.463 +      nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
   1.464 +      NS_ENSURE_TRUE(smsService, true);
   1.465 +
   1.466 +      const SendSmsMessageRequest &req = aRequest.get_SendSmsMessageRequest();
   1.467 +      smsService->Send(req.serviceId(), req.number(), req.message(),
   1.468 +                       req.silent(), this);
   1.469 +    }
   1.470 +    break;
   1.471 +  case SendMessageRequest::TSendMmsMessageRequest: {
   1.472 +      nsCOMPtr<nsIMmsService> mmsService = do_GetService(MMS_SERVICE_CONTRACTID);
   1.473 +      NS_ENSURE_TRUE(mmsService, true);
   1.474 +
   1.475 +      // There are cases (see bug 981202) where this is called with no JS on the
   1.476 +      // stack. And since mmsService might be JS-Implemented, we need to pass a
   1.477 +      // jsval to ::Send. Only system code should be looking at the result here,
   1.478 +      // so we just create it in the System-Principaled Junk Scope.
   1.479 +      AutoJSContext cx;
   1.480 +      JSAutoCompartment ac(cx, xpc::GetJunkScope());
   1.481 +      JS::Rooted<JS::Value> params(cx);
   1.482 +      const SendMmsMessageRequest &req = aRequest.get_SendMmsMessageRequest();
   1.483 +      if (!GetParamsFromSendMmsMessageRequest(cx,
   1.484 +                                              req,
   1.485 +                                              params.address())) {
   1.486 +        NS_WARNING("SmsRequestParent: Fail to build MMS params.");
   1.487 +        return true;
   1.488 +      }
   1.489 +      mmsService->Send(req.serviceId(), params, this);
   1.490 +    }
   1.491 +    break;
   1.492 +  default:
   1.493 +    MOZ_CRASH("Unknown type of SendMessageRequest!");
   1.494 +  }
   1.495 +  return true;
   1.496 +}
   1.497 +
   1.498 +bool
   1.499 +SmsRequestParent::DoRequest(const RetrieveMessageRequest& aRequest)
   1.500 +{
   1.501 +  nsresult rv = NS_ERROR_FAILURE;
   1.502 +
   1.503 +  nsCOMPtr<nsIMmsService> mmsService = do_GetService(MMS_SERVICE_CONTRACTID);
   1.504 +  if (mmsService) {
   1.505 +    rv = mmsService->Retrieve(aRequest.messageId(), this);
   1.506 +  }
   1.507 +
   1.508 +  if (NS_FAILED(rv)) {
   1.509 +    return NS_SUCCEEDED(NotifyGetMessageFailed(nsIMobileMessageCallback::INTERNAL_ERROR));
   1.510 +  }
   1.511 +
   1.512 +  return true;
   1.513 +}
   1.514 +
   1.515 +bool
   1.516 +SmsRequestParent::DoRequest(const GetMessageRequest& aRequest)
   1.517 +{
   1.518 +  nsresult rv = NS_ERROR_FAILURE;
   1.519 +
   1.520 +  nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
   1.521 +    do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
   1.522 +  if (dbService) {
   1.523 +    rv = dbService->GetMessageMoz(aRequest.messageId(), this);
   1.524 +  }
   1.525 +
   1.526 +  if (NS_FAILED(rv)) {
   1.527 +    return NS_SUCCEEDED(NotifyGetMessageFailed(nsIMobileMessageCallback::INTERNAL_ERROR));
   1.528 +  }
   1.529 +
   1.530 +  return true;
   1.531 +}
   1.532 +
   1.533 +bool
   1.534 +SmsRequestParent::DoRequest(const GetSmscAddressRequest& aRequest)
   1.535 +{
   1.536 +  nsresult rv = NS_ERROR_FAILURE;
   1.537 +
   1.538 +  nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
   1.539 +  if (smsService) {
   1.540 +    rv = smsService->GetSmscAddress(aRequest.serviceId(), this);
   1.541 +  }
   1.542 +
   1.543 +  if (NS_FAILED(rv)) {
   1.544 +    return NS_SUCCEEDED(NotifyGetSmscAddressFailed(nsIMobileMessageCallback::INTERNAL_ERROR));
   1.545 +  }
   1.546 +
   1.547 +  return true;
   1.548 +}
   1.549 +
   1.550 +bool
   1.551 +SmsRequestParent::DoRequest(const DeleteMessageRequest& aRequest)
   1.552 +{
   1.553 +  nsresult rv = NS_ERROR_FAILURE;
   1.554 +
   1.555 +  nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
   1.556 +    do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
   1.557 +  if (dbService) {
   1.558 +    const InfallibleTArray<int32_t>& messageIds = aRequest.messageIds();
   1.559 +    rv = dbService->DeleteMessage(const_cast<int32_t *>(messageIds.Elements()),
   1.560 +                                  messageIds.Length(), this);
   1.561 +  }
   1.562 +
   1.563 +  if (NS_FAILED(rv)) {
   1.564 +    return NS_SUCCEEDED(NotifyDeleteMessageFailed(nsIMobileMessageCallback::INTERNAL_ERROR));
   1.565 +  }
   1.566 +
   1.567 +  return true;
   1.568 +}
   1.569 +
   1.570 +bool
   1.571 +SmsRequestParent::DoRequest(const MarkMessageReadRequest& aRequest)
   1.572 +{
   1.573 +  nsresult rv = NS_ERROR_FAILURE;
   1.574 +
   1.575 +  nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
   1.576 +    do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
   1.577 +  if (dbService) {
   1.578 +    rv = dbService->MarkMessageRead(aRequest.messageId(), aRequest.value(),
   1.579 +                                    aRequest.sendReadReport(), this);
   1.580 +  }
   1.581 +
   1.582 +  if (NS_FAILED(rv)) {
   1.583 +    return NS_SUCCEEDED(NotifyMarkMessageReadFailed(nsIMobileMessageCallback::INTERNAL_ERROR));
   1.584 +  }
   1.585 +
   1.586 +  return true;
   1.587 +}
   1.588 +
   1.589 +bool
   1.590 +SmsRequestParent::DoRequest(const GetSegmentInfoForTextRequest& aRequest)
   1.591 +{
   1.592 +  nsresult rv = NS_ERROR_FAILURE;
   1.593 +
   1.594 +  nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
   1.595 +  if (smsService) {
   1.596 +    rv = smsService->GetSegmentInfoForText(aRequest.text(), this);
   1.597 +  }
   1.598 +
   1.599 +  if (NS_FAILED(rv)) {
   1.600 +    return NS_SUCCEEDED(NotifyGetSegmentInfoForTextFailed(
   1.601 +                          nsIMobileMessageCallback::INTERNAL_ERROR));
   1.602 +  }
   1.603 +
   1.604 +  return true;
   1.605 +}
   1.606 +
   1.607 +nsresult
   1.608 +SmsRequestParent::SendReply(const MessageReply& aReply)
   1.609 +{
   1.610 +  // The child process could die before this asynchronous notification, in which
   1.611 +  // case ActorDestroy() was called and mActorDestroyed is set to true. Return
   1.612 +  // an error here to avoid sending a message to the dead process.
   1.613 +  NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
   1.614 +
   1.615 +  return Send__delete__(this, aReply) ? NS_OK : NS_ERROR_FAILURE;
   1.616 +}
   1.617 +
   1.618 +// nsIMobileMessageCallback
   1.619 +
   1.620 +NS_IMETHODIMP
   1.621 +SmsRequestParent::NotifyMessageSent(nsISupports *aMessage)
   1.622 +{
   1.623 +  NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
   1.624 +
   1.625 +  nsCOMPtr<nsIDOMMozMmsMessage> mms = do_QueryInterface(aMessage);
   1.626 +  if (mms) {
   1.627 +    MmsMessage *msg = static_cast<MmsMessage*>(mms.get());
   1.628 +    ContentParent *parent = static_cast<ContentParent*>(Manager()->Manager());
   1.629 +    MmsMessageData data;
   1.630 +    if (!msg->GetData(parent, data)) {
   1.631 +      return NS_ERROR_FAILURE;
   1.632 +    }
   1.633 +    return SendReply(ReplyMessageSend(MobileMessageData(data)));
   1.634 +  }
   1.635 +
   1.636 +  nsCOMPtr<nsIDOMMozSmsMessage> sms = do_QueryInterface(aMessage);
   1.637 +  if (sms) {
   1.638 +    SmsMessage* msg = static_cast<SmsMessage*>(sms.get());
   1.639 +    return SendReply(ReplyMessageSend(MobileMessageData(msg->GetData())));
   1.640 +  }
   1.641 +
   1.642 +  return NS_ERROR_FAILURE;
   1.643 +}
   1.644 +
   1.645 +NS_IMETHODIMP
   1.646 +SmsRequestParent::NotifySendMessageFailed(int32_t aError)
   1.647 +{
   1.648 +  return SendReply(ReplyMessageSendFail(aError));
   1.649 +}
   1.650 +
   1.651 +NS_IMETHODIMP
   1.652 +SmsRequestParent::NotifyMessageGot(nsISupports *aMessage)
   1.653 +{
   1.654 +  NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
   1.655 +
   1.656 +  nsCOMPtr<nsIDOMMozMmsMessage> mms = do_QueryInterface(aMessage);
   1.657 +  if (mms) {
   1.658 +    MmsMessage *msg = static_cast<MmsMessage*>(mms.get());
   1.659 +    ContentParent *parent = static_cast<ContentParent*>(Manager()->Manager());
   1.660 +    MmsMessageData data;
   1.661 +    if (!msg->GetData(parent, data)) {
   1.662 +      return NS_ERROR_FAILURE;
   1.663 +    }
   1.664 +    return SendReply(ReplyGetMessage(MobileMessageData(data)));
   1.665 +  }
   1.666 +
   1.667 +  nsCOMPtr<nsIDOMMozSmsMessage> sms = do_QueryInterface(aMessage);
   1.668 +  if (sms) {
   1.669 +    SmsMessage* msg = static_cast<SmsMessage*>(sms.get());
   1.670 +    return SendReply(ReplyGetMessage(MobileMessageData(msg->GetData())));
   1.671 +  }
   1.672 +
   1.673 +  return NS_ERROR_FAILURE;
   1.674 +}
   1.675 +
   1.676 +NS_IMETHODIMP
   1.677 +SmsRequestParent::NotifyGetMessageFailed(int32_t aError)
   1.678 +{
   1.679 +  return SendReply(ReplyGetMessageFail(aError));
   1.680 +}
   1.681 +
   1.682 +NS_IMETHODIMP
   1.683 +SmsRequestParent::NotifyMessageDeleted(bool *aDeleted, uint32_t aSize)
   1.684 +{
   1.685 +  ReplyMessageDelete data;
   1.686 +  data.deleted().AppendElements(aDeleted, aSize);
   1.687 +  return SendReply(data);
   1.688 +}
   1.689 +
   1.690 +NS_IMETHODIMP
   1.691 +SmsRequestParent::NotifyDeleteMessageFailed(int32_t aError)
   1.692 +{
   1.693 +  return SendReply(ReplyMessageDeleteFail(aError));
   1.694 +}
   1.695 +
   1.696 +NS_IMETHODIMP
   1.697 +SmsRequestParent::NotifyMessageMarkedRead(bool aRead)
   1.698 +{
   1.699 +  return SendReply(ReplyMarkeMessageRead(aRead));
   1.700 +}
   1.701 +
   1.702 +NS_IMETHODIMP
   1.703 +SmsRequestParent::NotifyMarkMessageReadFailed(int32_t aError)
   1.704 +{
   1.705 +  return SendReply(ReplyMarkeMessageReadFail(aError));
   1.706 +}
   1.707 +
   1.708 +NS_IMETHODIMP
   1.709 +SmsRequestParent::NotifySegmentInfoForTextGot(nsIDOMMozSmsSegmentInfo *aInfo)
   1.710 +{
   1.711 +  SmsSegmentInfo* info = static_cast<SmsSegmentInfo*>(aInfo);
   1.712 +  return SendReply(ReplyGetSegmentInfoForText(info->GetData()));
   1.713 +}
   1.714 +
   1.715 +NS_IMETHODIMP
   1.716 +SmsRequestParent::NotifyGetSegmentInfoForTextFailed(int32_t aError)
   1.717 +{
   1.718 +  return SendReply(ReplyGetSegmentInfoForTextFail(aError));
   1.719 +}
   1.720 +
   1.721 +NS_IMETHODIMP
   1.722 +SmsRequestParent::NotifyGetSmscAddress(const nsAString& aSmscAddress)
   1.723 +{
   1.724 +  return SendReply(ReplyGetSmscAddress(nsString(aSmscAddress)));
   1.725 +}
   1.726 +
   1.727 +NS_IMETHODIMP
   1.728 +SmsRequestParent::NotifyGetSmscAddressFailed(int32_t aError)
   1.729 +{
   1.730 +  return SendReply(ReplyGetSmscAddressFail(aError));
   1.731 +}
   1.732 +
   1.733 +/*******************************************************************************
   1.734 + * MobileMessageCursorParent
   1.735 + ******************************************************************************/
   1.736 +
   1.737 +NS_IMPL_ISUPPORTS(MobileMessageCursorParent, nsIMobileMessageCursorCallback)
   1.738 +
   1.739 +void
   1.740 +MobileMessageCursorParent::ActorDestroy(ActorDestroyReason aWhy)
   1.741 +{
   1.742 +  // Two possible scenarios here:
   1.743 +  // 1) When parent fails to SendNotifyResult() in NotifyCursorResult(), it's
   1.744 +  //    destroyed without nulling out mContinueCallback.
   1.745 +  // 2) When parent dies normally, mContinueCallback should have been cleared in
   1.746 +  //    NotifyCursorError(), but just ensure this again.
   1.747 +  mContinueCallback = nullptr;
   1.748 +}
   1.749 +
   1.750 +bool
   1.751 +MobileMessageCursorParent::RecvContinue()
   1.752 +{
   1.753 +  MOZ_ASSERT(mContinueCallback);
   1.754 +
   1.755 +  if (NS_FAILED(mContinueCallback->HandleContinue())) {
   1.756 +    return NS_SUCCEEDED(NotifyCursorError(nsIMobileMessageCallback::INTERNAL_ERROR));
   1.757 +  }
   1.758 +
   1.759 +  return true;
   1.760 +}
   1.761 +
   1.762 +bool
   1.763 +MobileMessageCursorParent::DoRequest(const CreateMessageCursorRequest& aRequest)
   1.764 +{
   1.765 +  nsresult rv = NS_ERROR_FAILURE;
   1.766 +
   1.767 +  nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
   1.768 +    do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
   1.769 +  if (dbService) {
   1.770 +    nsCOMPtr<nsIDOMMozSmsFilter> filter = new SmsFilter(aRequest.filter());
   1.771 +    bool reverse = aRequest.reverse();
   1.772 +
   1.773 +    rv = dbService->CreateMessageCursor(filter, reverse, this,
   1.774 +                                        getter_AddRefs(mContinueCallback));
   1.775 +  }
   1.776 +
   1.777 +  if (NS_FAILED(rv)) {
   1.778 +    return NS_SUCCEEDED(NotifyCursorError(nsIMobileMessageCallback::INTERNAL_ERROR));
   1.779 +  }
   1.780 +
   1.781 +  return true;
   1.782 +}
   1.783 +
   1.784 +bool
   1.785 +MobileMessageCursorParent::DoRequest(const CreateThreadCursorRequest& aRequest)
   1.786 +{
   1.787 +  nsresult rv = NS_ERROR_FAILURE;
   1.788 +
   1.789 +  nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
   1.790 +    do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
   1.791 +  if (dbService) {
   1.792 +    rv = dbService->CreateThreadCursor(this,
   1.793 +                                       getter_AddRefs(mContinueCallback));
   1.794 +  }
   1.795 +
   1.796 +  if (NS_FAILED(rv)) {
   1.797 +    return NS_SUCCEEDED(NotifyCursorError(nsIMobileMessageCallback::INTERNAL_ERROR));
   1.798 +  }
   1.799 +
   1.800 +  return true;
   1.801 +}
   1.802 +
   1.803 +// nsIMobileMessageCursorCallback
   1.804 +
   1.805 +NS_IMETHODIMP
   1.806 +MobileMessageCursorParent::NotifyCursorError(int32_t aError)
   1.807 +{
   1.808 +  // The child process could die before this asynchronous notification, in which
   1.809 +  // case ActorDestroy() was called and mContinueCallback is now null. Return an
   1.810 +  // error here to avoid sending a message to the dead process.
   1.811 +  NS_ENSURE_TRUE(mContinueCallback, NS_ERROR_FAILURE);
   1.812 +
   1.813 +  mContinueCallback = nullptr;
   1.814 +
   1.815 +  return Send__delete__(this, aError) ? NS_OK : NS_ERROR_FAILURE;
   1.816 +}
   1.817 +
   1.818 +NS_IMETHODIMP
   1.819 +MobileMessageCursorParent::NotifyCursorResult(nsISupports* aResult)
   1.820 +{
   1.821 +  // The child process could die before this asynchronous notification, in which
   1.822 +  // case ActorDestroy() was called and mContinueCallback is now null. Return an
   1.823 +  // error here to avoid sending a message to the dead process.
   1.824 +  NS_ENSURE_TRUE(mContinueCallback, NS_ERROR_FAILURE);
   1.825 +
   1.826 +  nsCOMPtr<nsIDOMMozSmsMessage> iSms = do_QueryInterface(aResult);
   1.827 +  if (iSms) {
   1.828 +    SmsMessage* message = static_cast<SmsMessage*>(aResult);
   1.829 +    return SendNotifyResult(MobileMessageCursorData(message->GetData()))
   1.830 +      ? NS_OK : NS_ERROR_FAILURE;
   1.831 +  }
   1.832 +
   1.833 +  nsCOMPtr<nsIDOMMozMmsMessage> iMms = do_QueryInterface(aResult);
   1.834 +  if (iMms) {
   1.835 +    MmsMessage* message = static_cast<MmsMessage*>(aResult);
   1.836 +    ContentParent* parent = static_cast<ContentParent*>(Manager()->Manager());
   1.837 +    MmsMessageData data;
   1.838 +    if (!message->GetData(parent, data)) {
   1.839 +      return NS_ERROR_FAILURE;
   1.840 +    }
   1.841 +    return SendNotifyResult(MobileMessageCursorData(data))
   1.842 +      ? NS_OK : NS_ERROR_FAILURE;
   1.843 +  }
   1.844 +
   1.845 +  nsCOMPtr<nsIDOMMozMobileMessageThread> iThread = do_QueryInterface(aResult);
   1.846 +  if (iThread) {
   1.847 +    MobileMessageThread* thread = static_cast<MobileMessageThread*>(aResult);
   1.848 +    return SendNotifyResult(MobileMessageCursorData(thread->GetData()))
   1.849 +      ? NS_OK : NS_ERROR_FAILURE;
   1.850 +  }
   1.851 +
   1.852 +  MOZ_CRASH("Received invalid response parameters!");
   1.853 +}
   1.854 +
   1.855 +NS_IMETHODIMP
   1.856 +MobileMessageCursorParent::NotifyCursorDone()
   1.857 +{
   1.858 +  return NotifyCursorError(nsIMobileMessageCallback::SUCCESS_NO_ERROR);
   1.859 +}
   1.860 +
   1.861 +} // namespace mobilemessage
   1.862 +} // namespace dom
   1.863 +} // namespace mozilla

mercurial