1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/mobilemessage/src/ipc/SmsIPCService.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,340 @@ 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 "mozilla/dom/ContentChild.h" 1.10 +#include "SmsIPCService.h" 1.11 +#include "nsXULAppAPI.h" 1.12 +#include "mozilla/dom/mobilemessage/SmsChild.h" 1.13 +#include "SmsMessage.h" 1.14 +#include "SmsFilter.h" 1.15 +#include "SmsSegmentInfo.h" 1.16 +#include "nsJSUtils.h" 1.17 +#include "nsCxPusher.h" 1.18 +#include "mozilla/dom/MobileMessageManagerBinding.h" 1.19 +#include "mozilla/dom/MozMmsMessageBinding.h" 1.20 +#include "mozilla/dom/BindingUtils.h" 1.21 +#include "mozilla/Preferences.h" 1.22 +#include "nsString.h" 1.23 + 1.24 +using namespace mozilla::dom; 1.25 +using namespace mozilla::dom::mobilemessage; 1.26 + 1.27 +namespace { 1.28 + 1.29 +const char* kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces"; 1.30 +#define kPrefMmsDefaultServiceId "dom.mms.defaultServiceId" 1.31 +#define kPrefSmsDefaultServiceId "dom.sms.defaultServiceId" 1.32 +const char* kObservedPrefs[] = { 1.33 + kPrefMmsDefaultServiceId, 1.34 + kPrefSmsDefaultServiceId, 1.35 + nullptr 1.36 +}; 1.37 + 1.38 +// TODO: Bug 767082 - WebSMS: sSmsChild leaks at shutdown 1.39 +PSmsChild* gSmsChild; 1.40 + 1.41 +PSmsChild* 1.42 +GetSmsChild() 1.43 +{ 1.44 + MOZ_ASSERT(NS_IsMainThread()); 1.45 + 1.46 + if (!gSmsChild) { 1.47 + gSmsChild = ContentChild::GetSingleton()->SendPSmsConstructor(); 1.48 + 1.49 + NS_WARN_IF_FALSE(gSmsChild, 1.50 + "Calling methods on SmsIPCService during shutdown!"); 1.51 + } 1.52 + 1.53 + return gSmsChild; 1.54 +} 1.55 + 1.56 +nsresult 1.57 +SendRequest(const IPCSmsRequest& aRequest, 1.58 + nsIMobileMessageCallback* aRequestReply) 1.59 +{ 1.60 + PSmsChild* smsChild = GetSmsChild(); 1.61 + NS_ENSURE_TRUE(smsChild, NS_ERROR_FAILURE); 1.62 + 1.63 + SmsRequestChild* actor = new SmsRequestChild(aRequestReply); 1.64 + smsChild->SendPSmsRequestConstructor(actor, aRequest); 1.65 + 1.66 + return NS_OK; 1.67 +} 1.68 + 1.69 +nsresult 1.70 +SendCursorRequest(const IPCMobileMessageCursor& aRequest, 1.71 + nsIMobileMessageCursorCallback* aRequestReply, 1.72 + nsICursorContinueCallback** aResult) 1.73 +{ 1.74 + PSmsChild* smsChild = GetSmsChild(); 1.75 + NS_ENSURE_TRUE(smsChild, NS_ERROR_FAILURE); 1.76 + 1.77 + nsRefPtr<MobileMessageCursorChild> actor = 1.78 + new MobileMessageCursorChild(aRequestReply); 1.79 + 1.80 + // Add an extra ref for IPDL. Will be released in 1.81 + // SmsChild::DeallocPMobileMessageCursor(). 1.82 + actor->AddRef(); 1.83 + 1.84 + smsChild->SendPMobileMessageCursorConstructor(actor, aRequest); 1.85 + 1.86 + actor.forget(aResult); 1.87 + return NS_OK; 1.88 +} 1.89 + 1.90 +uint32_t 1.91 +getDefaultServiceId(const char* aPrefKey) 1.92 +{ 1.93 + int32_t id = mozilla::Preferences::GetInt(aPrefKey, 0); 1.94 + int32_t numRil = mozilla::Preferences::GetInt(kPrefRilNumRadioInterfaces, 1); 1.95 + 1.96 + if (id >= numRil || id < 0) { 1.97 + id = 0; 1.98 + } 1.99 + 1.100 + return id; 1.101 +} 1.102 + 1.103 +} // anonymous namespace 1.104 + 1.105 +NS_IMPL_ISUPPORTS(SmsIPCService, 1.106 + nsISmsService, 1.107 + nsIMmsService, 1.108 + nsIMobileMessageDatabaseService, 1.109 + nsIObserver) 1.110 + 1.111 +SmsIPCService::SmsIPCService() 1.112 +{ 1.113 + Preferences::AddStrongObservers(this, kObservedPrefs); 1.114 + mMmsDefaultServiceId = getDefaultServiceId(kPrefMmsDefaultServiceId); 1.115 + mSmsDefaultServiceId = getDefaultServiceId(kPrefSmsDefaultServiceId); 1.116 +} 1.117 + 1.118 +/* 1.119 + * Implementation of nsIObserver. 1.120 + */ 1.121 + 1.122 +NS_IMETHODIMP 1.123 +SmsIPCService::Observe(nsISupports* aSubject, 1.124 + const char* aTopic, 1.125 + const char16_t* aData) 1.126 +{ 1.127 + if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) { 1.128 + nsDependentString data(aData); 1.129 + if (data.EqualsLiteral(kPrefMmsDefaultServiceId)) { 1.130 + mMmsDefaultServiceId = getDefaultServiceId(kPrefMmsDefaultServiceId); 1.131 + } else if (data.EqualsLiteral(kPrefSmsDefaultServiceId)) { 1.132 + mSmsDefaultServiceId = getDefaultServiceId(kPrefSmsDefaultServiceId); 1.133 + } 1.134 + return NS_OK; 1.135 + } 1.136 + 1.137 + MOZ_ASSERT(false, "SmsIPCService got unexpected topic!"); 1.138 + return NS_ERROR_UNEXPECTED; 1.139 +} 1.140 + 1.141 +/* 1.142 + * Implementation of nsISmsService. 1.143 + */ 1.144 + 1.145 +NS_IMETHODIMP 1.146 +SmsIPCService::GetSmsDefaultServiceId(uint32_t* aServiceId) 1.147 +{ 1.148 + *aServiceId = mSmsDefaultServiceId; 1.149 + return NS_OK; 1.150 +} 1.151 + 1.152 +NS_IMETHODIMP 1.153 +SmsIPCService::GetSegmentInfoForText(const nsAString& aText, 1.154 + nsIMobileMessageCallback* aRequest) 1.155 +{ 1.156 + return SendRequest(GetSegmentInfoForTextRequest(nsString(aText)), 1.157 + aRequest); 1.158 +} 1.159 + 1.160 +NS_IMETHODIMP 1.161 +SmsIPCService::GetSmscAddress(uint32_t aServiceId, 1.162 + nsIMobileMessageCallback* aRequest) 1.163 +{ 1.164 + return SendRequest(GetSmscAddressRequest(aServiceId), aRequest); 1.165 +} 1.166 + 1.167 +NS_IMETHODIMP 1.168 +SmsIPCService::Send(uint32_t aServiceId, 1.169 + const nsAString& aNumber, 1.170 + const nsAString& aMessage, 1.171 + bool aSilent, 1.172 + nsIMobileMessageCallback* aRequest) 1.173 +{ 1.174 + return SendRequest(SendMessageRequest(SendSmsMessageRequest(aServiceId, 1.175 + nsString(aNumber), 1.176 + nsString(aMessage), 1.177 + aSilent)), 1.178 + aRequest); 1.179 +} 1.180 + 1.181 +NS_IMETHODIMP 1.182 +SmsIPCService::IsSilentNumber(const nsAString& aNumber, 1.183 + bool* aIsSilent) 1.184 +{ 1.185 + NS_ERROR("We should not be here!"); 1.186 + return NS_ERROR_FAILURE; 1.187 +} 1.188 + 1.189 +NS_IMETHODIMP 1.190 +SmsIPCService::AddSilentNumber(const nsAString& aNumber) 1.191 +{ 1.192 + PSmsChild* smsChild = GetSmsChild(); 1.193 + NS_ENSURE_TRUE(smsChild, NS_ERROR_FAILURE); 1.194 + 1.195 + smsChild->SendAddSilentNumber(nsString(aNumber)); 1.196 + return NS_OK; 1.197 +} 1.198 + 1.199 +NS_IMETHODIMP 1.200 +SmsIPCService::RemoveSilentNumber(const nsAString& aNumber) 1.201 +{ 1.202 + PSmsChild* smsChild = GetSmsChild(); 1.203 + NS_ENSURE_TRUE(smsChild, NS_ERROR_FAILURE); 1.204 + 1.205 + smsChild->SendRemoveSilentNumber(nsString(aNumber)); 1.206 + return NS_OK; 1.207 +} 1.208 + 1.209 +/* 1.210 + * Implementation of nsIMobileMessageDatabaseService. 1.211 + */ 1.212 +NS_IMETHODIMP 1.213 +SmsIPCService::GetMessageMoz(int32_t aMessageId, 1.214 + nsIMobileMessageCallback* aRequest) 1.215 +{ 1.216 + return SendRequest(GetMessageRequest(aMessageId), aRequest); 1.217 +} 1.218 + 1.219 +NS_IMETHODIMP 1.220 +SmsIPCService::DeleteMessage(int32_t *aMessageIds, uint32_t aSize, 1.221 + nsIMobileMessageCallback* aRequest) 1.222 +{ 1.223 + DeleteMessageRequest data; 1.224 + data.messageIds().AppendElements(aMessageIds, aSize); 1.225 + return SendRequest(data, aRequest); 1.226 +} 1.227 + 1.228 +NS_IMETHODIMP 1.229 +SmsIPCService::CreateMessageCursor(nsIDOMMozSmsFilter* aFilter, 1.230 + bool aReverse, 1.231 + nsIMobileMessageCursorCallback* aCursorCallback, 1.232 + nsICursorContinueCallback** aResult) 1.233 +{ 1.234 + const SmsFilterData& data = 1.235 + SmsFilterData(static_cast<SmsFilter*>(aFilter)->GetData()); 1.236 + 1.237 + return SendCursorRequest(CreateMessageCursorRequest(data, aReverse), 1.238 + aCursorCallback, aResult); 1.239 +} 1.240 + 1.241 +NS_IMETHODIMP 1.242 +SmsIPCService::MarkMessageRead(int32_t aMessageId, 1.243 + bool aValue, 1.244 + bool aSendReadReport, 1.245 + nsIMobileMessageCallback* aRequest) 1.246 +{ 1.247 + return SendRequest(MarkMessageReadRequest(aMessageId, aValue, aSendReadReport), aRequest); 1.248 +} 1.249 + 1.250 +NS_IMETHODIMP 1.251 +SmsIPCService::CreateThreadCursor(nsIMobileMessageCursorCallback* aCursorCallback, 1.252 + nsICursorContinueCallback** aResult) 1.253 +{ 1.254 + return SendCursorRequest(CreateThreadCursorRequest(), aCursorCallback, 1.255 + aResult); 1.256 +} 1.257 + 1.258 +bool 1.259 +GetSendMmsMessageRequestFromParams(uint32_t aServiceId, 1.260 + const JS::Value& aParam, 1.261 + SendMmsMessageRequest& request) { 1.262 + if (aParam.isUndefined() || aParam.isNull() || !aParam.isObject()) { 1.263 + return false; 1.264 + } 1.265 + 1.266 + mozilla::AutoJSContext cx; 1.267 + JS::Rooted<JS::Value> param(cx, aParam); 1.268 + RootedDictionary<MmsParameters> params(cx); 1.269 + if (!params.Init(cx, param)) { 1.270 + return false; 1.271 + } 1.272 + 1.273 + // SendMobileMessageRequest.receivers 1.274 + if (!params.mReceivers.WasPassed()) { 1.275 + return false; 1.276 + } 1.277 + request.receivers().AppendElements(params.mReceivers.Value()); 1.278 + 1.279 + // SendMobileMessageRequest.attachments 1.280 + mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton(); 1.281 + 1.282 + if (!params.mAttachments.WasPassed()) { 1.283 + return false; 1.284 + } 1.285 + 1.286 + for (uint32_t i = 0; i < params.mAttachments.Value().Length(); i++) { 1.287 + mozilla::dom::MmsAttachment& attachment = params.mAttachments.Value()[i]; 1.288 + MmsAttachmentData mmsAttachment; 1.289 + mmsAttachment.id().Assign(attachment.mId); 1.290 + mmsAttachment.location().Assign(attachment.mLocation); 1.291 + mmsAttachment.contentChild() = cc->GetOrCreateActorForBlob(attachment.mContent); 1.292 + if (!mmsAttachment.contentChild()) { 1.293 + return false; 1.294 + } 1.295 + request.attachments().AppendElement(mmsAttachment); 1.296 + } 1.297 + 1.298 + request.smil() = params.mSmil; 1.299 + request.subject() = params.mSubject; 1.300 + 1.301 + // Set service ID. 1.302 + request.serviceId() = aServiceId; 1.303 + 1.304 + return true; 1.305 +} 1.306 + 1.307 +/* 1.308 + * Implementation of nsIMmsService. 1.309 + */ 1.310 + 1.311 +NS_IMETHODIMP 1.312 +SmsIPCService::GetMmsDefaultServiceId(uint32_t* aServiceId) 1.313 +{ 1.314 + *aServiceId = mMmsDefaultServiceId; 1.315 + return NS_OK; 1.316 +} 1.317 + 1.318 +NS_IMETHODIMP 1.319 +SmsIPCService::Send(uint32_t aServiceId, 1.320 + JS::Handle<JS::Value> aParameters, 1.321 + nsIMobileMessageCallback *aRequest) 1.322 +{ 1.323 + SendMmsMessageRequest req; 1.324 + if (!GetSendMmsMessageRequestFromParams(aServiceId, aParameters, req)) { 1.325 + return NS_ERROR_INVALID_ARG; 1.326 + } 1.327 + return SendRequest(SendMessageRequest(req), aRequest); 1.328 +} 1.329 + 1.330 +NS_IMETHODIMP 1.331 +SmsIPCService::Retrieve(int32_t aId, nsIMobileMessageCallback *aRequest) 1.332 +{ 1.333 + return SendRequest(RetrieveMessageRequest(aId), aRequest); 1.334 +} 1.335 + 1.336 +NS_IMETHODIMP 1.337 +SmsIPCService::SendReadReport(const nsAString & messageID, 1.338 + const nsAString & toAddress, 1.339 + const nsAString & iccId) 1.340 +{ 1.341 + NS_ERROR("We should not be here!"); 1.342 + return NS_OK; 1.343 +}