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