Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/dom/ContentChild.h"
7 #include "SmsIPCService.h"
8 #include "nsXULAppAPI.h"
9 #include "mozilla/dom/mobilemessage/SmsChild.h"
10 #include "SmsMessage.h"
11 #include "SmsFilter.h"
12 #include "SmsSegmentInfo.h"
13 #include "nsJSUtils.h"
14 #include "nsCxPusher.h"
15 #include "mozilla/dom/MobileMessageManagerBinding.h"
16 #include "mozilla/dom/MozMmsMessageBinding.h"
17 #include "mozilla/dom/BindingUtils.h"
18 #include "mozilla/Preferences.h"
19 #include "nsString.h"
21 using namespace mozilla::dom;
22 using namespace mozilla::dom::mobilemessage;
24 namespace {
26 const char* kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces";
27 #define kPrefMmsDefaultServiceId "dom.mms.defaultServiceId"
28 #define kPrefSmsDefaultServiceId "dom.sms.defaultServiceId"
29 const char* kObservedPrefs[] = {
30 kPrefMmsDefaultServiceId,
31 kPrefSmsDefaultServiceId,
32 nullptr
33 };
35 // TODO: Bug 767082 - WebSMS: sSmsChild leaks at shutdown
36 PSmsChild* gSmsChild;
38 PSmsChild*
39 GetSmsChild()
40 {
41 MOZ_ASSERT(NS_IsMainThread());
43 if (!gSmsChild) {
44 gSmsChild = ContentChild::GetSingleton()->SendPSmsConstructor();
46 NS_WARN_IF_FALSE(gSmsChild,
47 "Calling methods on SmsIPCService during shutdown!");
48 }
50 return gSmsChild;
51 }
53 nsresult
54 SendRequest(const IPCSmsRequest& aRequest,
55 nsIMobileMessageCallback* aRequestReply)
56 {
57 PSmsChild* smsChild = GetSmsChild();
58 NS_ENSURE_TRUE(smsChild, NS_ERROR_FAILURE);
60 SmsRequestChild* actor = new SmsRequestChild(aRequestReply);
61 smsChild->SendPSmsRequestConstructor(actor, aRequest);
63 return NS_OK;
64 }
66 nsresult
67 SendCursorRequest(const IPCMobileMessageCursor& aRequest,
68 nsIMobileMessageCursorCallback* aRequestReply,
69 nsICursorContinueCallback** aResult)
70 {
71 PSmsChild* smsChild = GetSmsChild();
72 NS_ENSURE_TRUE(smsChild, NS_ERROR_FAILURE);
74 nsRefPtr<MobileMessageCursorChild> actor =
75 new MobileMessageCursorChild(aRequestReply);
77 // Add an extra ref for IPDL. Will be released in
78 // SmsChild::DeallocPMobileMessageCursor().
79 actor->AddRef();
81 smsChild->SendPMobileMessageCursorConstructor(actor, aRequest);
83 actor.forget(aResult);
84 return NS_OK;
85 }
87 uint32_t
88 getDefaultServiceId(const char* aPrefKey)
89 {
90 int32_t id = mozilla::Preferences::GetInt(aPrefKey, 0);
91 int32_t numRil = mozilla::Preferences::GetInt(kPrefRilNumRadioInterfaces, 1);
93 if (id >= numRil || id < 0) {
94 id = 0;
95 }
97 return id;
98 }
100 } // anonymous namespace
102 NS_IMPL_ISUPPORTS(SmsIPCService,
103 nsISmsService,
104 nsIMmsService,
105 nsIMobileMessageDatabaseService,
106 nsIObserver)
108 SmsIPCService::SmsIPCService()
109 {
110 Preferences::AddStrongObservers(this, kObservedPrefs);
111 mMmsDefaultServiceId = getDefaultServiceId(kPrefMmsDefaultServiceId);
112 mSmsDefaultServiceId = getDefaultServiceId(kPrefSmsDefaultServiceId);
113 }
115 /*
116 * Implementation of nsIObserver.
117 */
119 NS_IMETHODIMP
120 SmsIPCService::Observe(nsISupports* aSubject,
121 const char* aTopic,
122 const char16_t* aData)
123 {
124 if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
125 nsDependentString data(aData);
126 if (data.EqualsLiteral(kPrefMmsDefaultServiceId)) {
127 mMmsDefaultServiceId = getDefaultServiceId(kPrefMmsDefaultServiceId);
128 } else if (data.EqualsLiteral(kPrefSmsDefaultServiceId)) {
129 mSmsDefaultServiceId = getDefaultServiceId(kPrefSmsDefaultServiceId);
130 }
131 return NS_OK;
132 }
134 MOZ_ASSERT(false, "SmsIPCService got unexpected topic!");
135 return NS_ERROR_UNEXPECTED;
136 }
138 /*
139 * Implementation of nsISmsService.
140 */
142 NS_IMETHODIMP
143 SmsIPCService::GetSmsDefaultServiceId(uint32_t* aServiceId)
144 {
145 *aServiceId = mSmsDefaultServiceId;
146 return NS_OK;
147 }
149 NS_IMETHODIMP
150 SmsIPCService::GetSegmentInfoForText(const nsAString& aText,
151 nsIMobileMessageCallback* aRequest)
152 {
153 return SendRequest(GetSegmentInfoForTextRequest(nsString(aText)),
154 aRequest);
155 }
157 NS_IMETHODIMP
158 SmsIPCService::GetSmscAddress(uint32_t aServiceId,
159 nsIMobileMessageCallback* aRequest)
160 {
161 return SendRequest(GetSmscAddressRequest(aServiceId), aRequest);
162 }
164 NS_IMETHODIMP
165 SmsIPCService::Send(uint32_t aServiceId,
166 const nsAString& aNumber,
167 const nsAString& aMessage,
168 bool aSilent,
169 nsIMobileMessageCallback* aRequest)
170 {
171 return SendRequest(SendMessageRequest(SendSmsMessageRequest(aServiceId,
172 nsString(aNumber),
173 nsString(aMessage),
174 aSilent)),
175 aRequest);
176 }
178 NS_IMETHODIMP
179 SmsIPCService::IsSilentNumber(const nsAString& aNumber,
180 bool* aIsSilent)
181 {
182 NS_ERROR("We should not be here!");
183 return NS_ERROR_FAILURE;
184 }
186 NS_IMETHODIMP
187 SmsIPCService::AddSilentNumber(const nsAString& aNumber)
188 {
189 PSmsChild* smsChild = GetSmsChild();
190 NS_ENSURE_TRUE(smsChild, NS_ERROR_FAILURE);
192 smsChild->SendAddSilentNumber(nsString(aNumber));
193 return NS_OK;
194 }
196 NS_IMETHODIMP
197 SmsIPCService::RemoveSilentNumber(const nsAString& aNumber)
198 {
199 PSmsChild* smsChild = GetSmsChild();
200 NS_ENSURE_TRUE(smsChild, NS_ERROR_FAILURE);
202 smsChild->SendRemoveSilentNumber(nsString(aNumber));
203 return NS_OK;
204 }
206 /*
207 * Implementation of nsIMobileMessageDatabaseService.
208 */
209 NS_IMETHODIMP
210 SmsIPCService::GetMessageMoz(int32_t aMessageId,
211 nsIMobileMessageCallback* aRequest)
212 {
213 return SendRequest(GetMessageRequest(aMessageId), aRequest);
214 }
216 NS_IMETHODIMP
217 SmsIPCService::DeleteMessage(int32_t *aMessageIds, uint32_t aSize,
218 nsIMobileMessageCallback* aRequest)
219 {
220 DeleteMessageRequest data;
221 data.messageIds().AppendElements(aMessageIds, aSize);
222 return SendRequest(data, aRequest);
223 }
225 NS_IMETHODIMP
226 SmsIPCService::CreateMessageCursor(nsIDOMMozSmsFilter* aFilter,
227 bool aReverse,
228 nsIMobileMessageCursorCallback* aCursorCallback,
229 nsICursorContinueCallback** aResult)
230 {
231 const SmsFilterData& data =
232 SmsFilterData(static_cast<SmsFilter*>(aFilter)->GetData());
234 return SendCursorRequest(CreateMessageCursorRequest(data, aReverse),
235 aCursorCallback, aResult);
236 }
238 NS_IMETHODIMP
239 SmsIPCService::MarkMessageRead(int32_t aMessageId,
240 bool aValue,
241 bool aSendReadReport,
242 nsIMobileMessageCallback* aRequest)
243 {
244 return SendRequest(MarkMessageReadRequest(aMessageId, aValue, aSendReadReport), aRequest);
245 }
247 NS_IMETHODIMP
248 SmsIPCService::CreateThreadCursor(nsIMobileMessageCursorCallback* aCursorCallback,
249 nsICursorContinueCallback** aResult)
250 {
251 return SendCursorRequest(CreateThreadCursorRequest(), aCursorCallback,
252 aResult);
253 }
255 bool
256 GetSendMmsMessageRequestFromParams(uint32_t aServiceId,
257 const JS::Value& aParam,
258 SendMmsMessageRequest& request) {
259 if (aParam.isUndefined() || aParam.isNull() || !aParam.isObject()) {
260 return false;
261 }
263 mozilla::AutoJSContext cx;
264 JS::Rooted<JS::Value> param(cx, aParam);
265 RootedDictionary<MmsParameters> params(cx);
266 if (!params.Init(cx, param)) {
267 return false;
268 }
270 // SendMobileMessageRequest.receivers
271 if (!params.mReceivers.WasPassed()) {
272 return false;
273 }
274 request.receivers().AppendElements(params.mReceivers.Value());
276 // SendMobileMessageRequest.attachments
277 mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();
279 if (!params.mAttachments.WasPassed()) {
280 return false;
281 }
283 for (uint32_t i = 0; i < params.mAttachments.Value().Length(); i++) {
284 mozilla::dom::MmsAttachment& attachment = params.mAttachments.Value()[i];
285 MmsAttachmentData mmsAttachment;
286 mmsAttachment.id().Assign(attachment.mId);
287 mmsAttachment.location().Assign(attachment.mLocation);
288 mmsAttachment.contentChild() = cc->GetOrCreateActorForBlob(attachment.mContent);
289 if (!mmsAttachment.contentChild()) {
290 return false;
291 }
292 request.attachments().AppendElement(mmsAttachment);
293 }
295 request.smil() = params.mSmil;
296 request.subject() = params.mSubject;
298 // Set service ID.
299 request.serviceId() = aServiceId;
301 return true;
302 }
304 /*
305 * Implementation of nsIMmsService.
306 */
308 NS_IMETHODIMP
309 SmsIPCService::GetMmsDefaultServiceId(uint32_t* aServiceId)
310 {
311 *aServiceId = mMmsDefaultServiceId;
312 return NS_OK;
313 }
315 NS_IMETHODIMP
316 SmsIPCService::Send(uint32_t aServiceId,
317 JS::Handle<JS::Value> aParameters,
318 nsIMobileMessageCallback *aRequest)
319 {
320 SendMmsMessageRequest req;
321 if (!GetSendMmsMessageRequestFromParams(aServiceId, aParameters, req)) {
322 return NS_ERROR_INVALID_ARG;
323 }
324 return SendRequest(SendMessageRequest(req), aRequest);
325 }
327 NS_IMETHODIMP
328 SmsIPCService::Retrieve(int32_t aId, nsIMobileMessageCallback *aRequest)
329 {
330 return SendRequest(RetrieveMessageRequest(aId), aRequest);
331 }
333 NS_IMETHODIMP
334 SmsIPCService::SendReadReport(const nsAString & messageID,
335 const nsAString & toAddress,
336 const nsAString & iccId)
337 {
338 NS_ERROR("We should not be here!");
339 return NS_OK;
340 }