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.

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

mercurial