Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "mozilla/dom/MobileConnection.h"
7 #include "GeneratedEvents.h"
8 #include "mozilla/dom/CFStateChangeEvent.h"
9 #include "mozilla/dom/DataErrorEvent.h"
10 #include "mozilla/dom/MozEmergencyCbModeEvent.h"
11 #include "mozilla/dom/MozOtaStatusEvent.h"
12 #include "mozilla/dom/USSDReceivedEvent.h"
13 #include "mozilla/Preferences.h"
14 #include "nsIDOMClassInfo.h"
15 #include "nsIDOMDOMRequest.h"
16 #include "nsIPermissionManager.h"
17 #include "nsIVariant.h"
19 #include "nsJSUtils.h"
20 #include "nsJSON.h"
21 #include "mozilla/Services.h"
23 #define NS_RILCONTENTHELPER_CONTRACTID "@mozilla.org/ril/content-helper;1"
25 using namespace mozilla::dom;
27 class MobileConnection::Listener MOZ_FINAL : public nsIMobileConnectionListener
28 {
29 MobileConnection* mMobileConnection;
31 public:
32 NS_DECL_ISUPPORTS
33 NS_FORWARD_SAFE_NSIMOBILECONNECTIONLISTENER(mMobileConnection)
35 Listener(MobileConnection* aMobileConnection)
36 : mMobileConnection(aMobileConnection)
37 {
38 MOZ_ASSERT(mMobileConnection);
39 }
41 void Disconnect()
42 {
43 MOZ_ASSERT(mMobileConnection);
44 mMobileConnection = nullptr;
45 }
46 };
48 NS_IMPL_ISUPPORTS(MobileConnection::Listener, nsIMobileConnectionListener)
50 DOMCI_DATA(MozMobileConnection, MobileConnection)
52 NS_IMPL_CYCLE_COLLECTION_CLASS(MobileConnection)
54 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MobileConnection,
55 DOMEventTargetHelper)
56 // Don't traverse mListener because it doesn't keep any reference to
57 // MobileConnection but a raw pointer instead. Neither does mProvider because
58 // it's an xpcom service and is only released at shutting down.
59 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
61 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MobileConnection,
62 DOMEventTargetHelper)
63 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
65 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MobileConnection)
66 NS_INTERFACE_MAP_ENTRY(nsIDOMMozMobileConnection)
67 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozMobileConnection)
68 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
70 NS_IMPL_ADDREF_INHERITED(MobileConnection, DOMEventTargetHelper)
71 NS_IMPL_RELEASE_INHERITED(MobileConnection, DOMEventTargetHelper)
73 NS_IMPL_EVENT_HANDLER(MobileConnection, voicechange)
74 NS_IMPL_EVENT_HANDLER(MobileConnection, datachange)
75 NS_IMPL_EVENT_HANDLER(MobileConnection, ussdreceived)
76 NS_IMPL_EVENT_HANDLER(MobileConnection, dataerror)
77 NS_IMPL_EVENT_HANDLER(MobileConnection, cfstatechange)
78 NS_IMPL_EVENT_HANDLER(MobileConnection, emergencycbmodechange)
79 NS_IMPL_EVENT_HANDLER(MobileConnection, otastatuschange)
80 NS_IMPL_EVENT_HANDLER(MobileConnection, iccchange)
81 NS_IMPL_EVENT_HANDLER(MobileConnection, radiostatechange)
83 MobileConnection::MobileConnection(uint32_t aClientId)
84 : mClientId(aClientId)
85 {
86 mProvider = do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
87 mWindow = nullptr;
89 // Not being able to acquire the provider isn't fatal since we check
90 // for it explicitly below.
91 if (!mProvider) {
92 NS_WARNING("Could not acquire nsIMobileConnectionProvider!");
93 return;
94 }
95 }
97 void
98 MobileConnection::Init(nsPIDOMWindow* aWindow)
99 {
100 BindToOwner(aWindow);
102 mWindow = do_GetWeakReference(aWindow);
103 mListener = new Listener(this);
105 if (CheckPermission("mobileconnection")) {
106 DebugOnly<nsresult> rv = mProvider->RegisterMobileConnectionMsg(mClientId, mListener);
107 NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
108 "Failed registering mobile connection messages with provider");
109 }
110 }
112 void
113 MobileConnection::Shutdown()
114 {
115 if (mProvider && mListener) {
116 mListener->Disconnect();
117 mProvider->UnregisterMobileConnectionMsg(mClientId, mListener);
118 mProvider = nullptr;
119 mListener = nullptr;
120 }
121 }
123 // nsIDOMMozMobileConnection
125 NS_IMETHODIMP
126 MobileConnection::GetLastKnownNetwork(nsAString& aNetwork)
127 {
128 aNetwork.SetIsVoid(true);
130 if (!CheckPermission("mobilenetwork")) {
131 return NS_OK;
132 }
134 return mProvider->GetLastKnownNetwork(mClientId, aNetwork);
135 }
137 NS_IMETHODIMP
138 MobileConnection::GetLastKnownHomeNetwork(nsAString& aNetwork)
139 {
140 aNetwork.SetIsVoid(true);
142 if (!CheckPermission("mobilenetwork")) {
143 return NS_OK;
144 }
146 return mProvider->GetLastKnownHomeNetwork(mClientId, aNetwork);
147 }
149 // All fields below require the "mobileconnection" permission.
151 bool
152 MobileConnection::CheckPermission(const char* aType)
153 {
154 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
155 NS_ENSURE_TRUE(window, false);
157 nsCOMPtr<nsIPermissionManager> permMgr =
158 do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
159 NS_ENSURE_TRUE(permMgr, false);
161 uint32_t permission = nsIPermissionManager::DENY_ACTION;
162 permMgr->TestPermissionFromWindow(window, aType, &permission);
163 return permission == nsIPermissionManager::ALLOW_ACTION;
164 }
166 NS_IMETHODIMP
167 MobileConnection::GetVoice(nsIDOMMozMobileConnectionInfo** aVoice)
168 {
169 *aVoice = nullptr;
171 if (!mProvider || !CheckPermission("mobileconnection")) {
172 return NS_OK;
173 }
174 return mProvider->GetVoiceConnectionInfo(mClientId, aVoice);
175 }
177 NS_IMETHODIMP
178 MobileConnection::GetData(nsIDOMMozMobileConnectionInfo** aData)
179 {
180 *aData = nullptr;
182 if (!mProvider || !CheckPermission("mobileconnection")) {
183 return NS_OK;
184 }
185 return mProvider->GetDataConnectionInfo(mClientId, aData);
186 }
188 NS_IMETHODIMP
189 MobileConnection::GetIccId(nsAString& aIccId)
190 {
191 aIccId.SetIsVoid(true);
193 if (!mProvider || !CheckPermission("mobileconnection")) {
194 return NS_OK;
195 }
196 return mProvider->GetIccId(mClientId, aIccId);
197 }
199 NS_IMETHODIMP
200 MobileConnection::GetNetworkSelectionMode(nsAString& aNetworkSelectionMode)
201 {
202 aNetworkSelectionMode.SetIsVoid(true);
204 if (!mProvider || !CheckPermission("mobileconnection")) {
205 return NS_OK;
206 }
207 return mProvider->GetNetworkSelectionMode(mClientId, aNetworkSelectionMode);
208 }
210 NS_IMETHODIMP
211 MobileConnection::GetRadioState(nsAString& aRadioState)
212 {
213 aRadioState.SetIsVoid(true);
215 if (!mProvider || !CheckPermission("mobileconnection")) {
216 return NS_OK;
217 }
218 return mProvider->GetRadioState(mClientId, aRadioState);
219 }
221 NS_IMETHODIMP
222 MobileConnection::GetSupportedNetworkTypes(nsIVariant** aSupportedNetworkTypes)
223 {
224 *aSupportedNetworkTypes = nullptr;
226 if (!mProvider || !CheckPermission("mobileconnection")) {
227 return NS_OK;
228 }
230 return mProvider->GetSupportedNetworkTypes(mClientId, aSupportedNetworkTypes);
231 }
233 NS_IMETHODIMP
234 MobileConnection::GetNetworks(nsIDOMDOMRequest** aRequest)
235 {
236 *aRequest = nullptr;
238 if (!CheckPermission("mobileconnection")) {
239 return NS_OK;
240 }
242 if (!mProvider) {
243 return NS_ERROR_FAILURE;
244 }
246 return mProvider->GetNetworks(mClientId, GetOwner(), aRequest);
247 }
249 NS_IMETHODIMP
250 MobileConnection::SelectNetwork(nsIDOMMozMobileNetworkInfo* aNetwork, nsIDOMDOMRequest** aRequest)
251 {
252 *aRequest = nullptr;
254 if (!CheckPermission("mobileconnection")) {
255 return NS_OK;
256 }
258 if (!mProvider) {
259 return NS_ERROR_FAILURE;
260 }
262 return mProvider->SelectNetwork(mClientId, GetOwner(), aNetwork, aRequest);
263 }
265 NS_IMETHODIMP
266 MobileConnection::SelectNetworkAutomatically(nsIDOMDOMRequest** aRequest)
267 {
268 *aRequest = nullptr;
270 if (!CheckPermission("mobileconnection")) {
271 return NS_OK;
272 }
274 if (!mProvider) {
275 return NS_ERROR_FAILURE;
276 }
278 return mProvider->SelectNetworkAutomatically(mClientId, GetOwner(), aRequest);
279 }
281 NS_IMETHODIMP
282 MobileConnection::SetPreferredNetworkType(const nsAString& aType,
283 nsIDOMDOMRequest** aDomRequest)
284 {
285 *aDomRequest = nullptr;
287 if (!CheckPermission("mobileconnection")) {
288 return NS_OK;
289 }
291 if (!mProvider) {
292 return NS_ERROR_FAILURE;
293 }
295 return mProvider->SetPreferredNetworkType(mClientId, GetOwner(), aType, aDomRequest);
296 }
298 NS_IMETHODIMP
299 MobileConnection::GetPreferredNetworkType(nsIDOMDOMRequest** aDomRequest)
300 {
301 *aDomRequest = nullptr;
303 if (!CheckPermission("mobileconnection")) {
304 return NS_OK;
305 }
307 if (!mProvider) {
308 return NS_ERROR_FAILURE;
309 }
311 return mProvider->GetPreferredNetworkType(mClientId, GetOwner(), aDomRequest);
312 }
314 NS_IMETHODIMP
315 MobileConnection::SetRoamingPreference(const nsAString& aMode, nsIDOMDOMRequest** aDomRequest)
316 {
317 *aDomRequest = nullptr;
319 if (!CheckPermission("mobileconnection")) {
320 return NS_OK;
321 }
323 if (!mProvider) {
324 return NS_ERROR_FAILURE;
325 }
327 return mProvider->SetRoamingPreference(mClientId, GetOwner(), aMode, aDomRequest);
328 }
330 NS_IMETHODIMP
331 MobileConnection::GetRoamingPreference(nsIDOMDOMRequest** aDomRequest)
332 {
333 *aDomRequest = nullptr;
335 if (!CheckPermission("mobileconnection")) {
336 return NS_OK;
337 }
339 if (!mProvider) {
340 return NS_ERROR_FAILURE;
341 }
343 return mProvider->GetRoamingPreference(mClientId, GetOwner(), aDomRequest);
344 }
346 NS_IMETHODIMP
347 MobileConnection::SetVoicePrivacyMode(bool aEnabled, nsIDOMDOMRequest** aDomRequest)
348 {
349 *aDomRequest = nullptr;
351 if (!CheckPermission("mobileconnection")) {
352 return NS_OK;
353 }
355 if (!mProvider) {
356 return NS_ERROR_FAILURE;
357 }
359 return mProvider->SetVoicePrivacyMode(mClientId, GetOwner(), aEnabled, aDomRequest);
360 }
362 NS_IMETHODIMP
363 MobileConnection::GetVoicePrivacyMode(nsIDOMDOMRequest** aDomRequest)
364 {
365 *aDomRequest = nullptr;
367 if (!CheckPermission("mobileconnection")) {
368 return NS_OK;
369 }
371 if (!mProvider) {
372 return NS_ERROR_FAILURE;
373 }
375 return mProvider->GetVoicePrivacyMode(mClientId, GetOwner(), aDomRequest);
376 }
378 NS_IMETHODIMP
379 MobileConnection::SendMMI(const nsAString& aMMIString,
380 nsIDOMDOMRequest** aRequest)
381 {
382 if (!CheckPermission("mobileconnection")) {
383 return NS_OK;
384 }
386 if (!mProvider) {
387 return NS_ERROR_FAILURE;
388 }
390 return mProvider->SendMMI(mClientId, GetOwner(), aMMIString, aRequest);
391 }
393 NS_IMETHODIMP
394 MobileConnection::CancelMMI(nsIDOMDOMRequest** aRequest)
395 {
396 if (!CheckPermission("mobileconnection")) {
397 return NS_OK;
398 }
400 if (!mProvider) {
401 return NS_ERROR_FAILURE;
402 }
404 return mProvider->CancelMMI(mClientId, GetOwner(),aRequest);
405 }
407 NS_IMETHODIMP
408 MobileConnection::GetCallForwardingOption(uint16_t aReason,
409 nsIDOMDOMRequest** aRequest)
410 {
411 *aRequest = nullptr;
413 if (!CheckPermission("mobileconnection")) {
414 return NS_OK;
415 }
417 if (!mProvider) {
418 return NS_ERROR_FAILURE;
419 }
421 return mProvider->GetCallForwardingOption(mClientId, GetOwner(), aReason, aRequest);
422 }
424 NS_IMETHODIMP
425 MobileConnection::SetCallForwardingOption(nsIDOMMozMobileCFInfo* aCFInfo,
426 nsIDOMDOMRequest** aRequest)
427 {
428 *aRequest = nullptr;
430 if (!CheckPermission("mobileconnection")) {
431 return NS_OK;
432 }
434 if (!mProvider) {
435 return NS_ERROR_FAILURE;
436 }
438 return mProvider->SetCallForwardingOption(mClientId, GetOwner(), aCFInfo, aRequest);
439 }
441 NS_IMETHODIMP
442 MobileConnection::GetCallBarringOption(JS::Handle<JS::Value> aOption,
443 nsIDOMDOMRequest** aRequest)
444 {
445 *aRequest = nullptr;
447 if (!CheckPermission("mobileconnection")) {
448 return NS_OK;
449 }
451 if (!mProvider) {
452 return NS_ERROR_FAILURE;
453 }
455 return mProvider->GetCallBarringOption(mClientId, GetOwner(), aOption, aRequest);
456 }
458 NS_IMETHODIMP
459 MobileConnection::SetCallBarringOption(JS::Handle<JS::Value> aOption,
460 nsIDOMDOMRequest** aRequest)
461 {
462 *aRequest = nullptr;
464 if (!CheckPermission("mobileconnection")) {
465 return NS_OK;
466 }
468 if (!mProvider) {
469 return NS_ERROR_FAILURE;
470 }
472 return mProvider->SetCallBarringOption(mClientId, GetOwner(), aOption, aRequest);
473 }
475 NS_IMETHODIMP
476 MobileConnection::ChangeCallBarringPassword(JS::Handle<JS::Value> aInfo,
477 nsIDOMDOMRequest** aRequest)
478 {
479 *aRequest = nullptr;
481 if (!CheckPermission("mobileconnection")) {
482 return NS_OK;
483 }
485 if (!mProvider) {
486 return NS_ERROR_FAILURE;
487 }
489 return mProvider->ChangeCallBarringPassword(mClientId, GetOwner(), aInfo, aRequest);
490 }
492 NS_IMETHODIMP
493 MobileConnection::GetCallWaitingOption(nsIDOMDOMRequest** aRequest)
494 {
495 *aRequest = nullptr;
497 if (!CheckPermission("mobileconnection")) {
498 return NS_OK;
499 }
501 if (!mProvider) {
502 return NS_ERROR_FAILURE;
503 }
505 return mProvider->GetCallWaitingOption(mClientId, GetOwner(), aRequest);
506 }
508 NS_IMETHODIMP
509 MobileConnection::SetCallWaitingOption(bool aEnabled,
510 nsIDOMDOMRequest** aRequest)
511 {
512 *aRequest = nullptr;
514 if (!CheckPermission("mobileconnection")) {
515 return NS_OK;
516 }
518 if (!mProvider) {
519 return NS_ERROR_FAILURE;
520 }
522 return mProvider->SetCallWaitingOption(mClientId, GetOwner(), aEnabled, aRequest);
523 }
525 NS_IMETHODIMP
526 MobileConnection::GetCallingLineIdRestriction(nsIDOMDOMRequest** aRequest)
527 {
528 *aRequest = nullptr;
530 if (!CheckPermission("mobileconnection")) {
531 return NS_OK;
532 }
534 if (!mProvider) {
535 return NS_ERROR_FAILURE;
536 }
538 return mProvider->GetCallingLineIdRestriction(mClientId, GetOwner(), aRequest);
539 }
541 NS_IMETHODIMP
542 MobileConnection::SetCallingLineIdRestriction(unsigned short aClirMode,
543 nsIDOMDOMRequest** aRequest)
544 {
545 *aRequest = nullptr;
547 if (!CheckPermission("mobileconnection")) {
548 return NS_OK;
549 }
551 if (!mProvider) {
552 return NS_ERROR_FAILURE;
553 }
555 return mProvider->SetCallingLineIdRestriction(mClientId, GetOwner(), aClirMode, aRequest);
556 }
558 NS_IMETHODIMP
559 MobileConnection::ExitEmergencyCbMode(nsIDOMDOMRequest** aRequest)
560 {
561 *aRequest = nullptr;
563 if (!CheckPermission("mobileconnection")) {
564 return NS_OK;
565 }
567 if (!mProvider) {
568 return NS_ERROR_FAILURE;
569 }
571 return mProvider->ExitEmergencyCbMode(mClientId, GetOwner(), aRequest);
572 }
574 NS_IMETHODIMP
575 MobileConnection::SetRadioEnabled(bool aEnabled,
576 nsIDOMDOMRequest** aRequest)
577 {
578 *aRequest = nullptr;
580 if (!CheckPermission("mobileconnection")) {
581 return NS_OK;
582 }
584 if (!mProvider) {
585 return NS_ERROR_FAILURE;
586 }
588 return mProvider->SetRadioEnabled(mClientId, GetOwner(), aEnabled, aRequest);
589 }
591 // nsIMobileConnectionListener
593 NS_IMETHODIMP
594 MobileConnection::NotifyVoiceChanged()
595 {
596 if (!CheckPermission("mobileconnection")) {
597 return NS_OK;
598 }
600 return DispatchTrustedEvent(NS_LITERAL_STRING("voicechange"));
601 }
603 NS_IMETHODIMP
604 MobileConnection::NotifyDataChanged()
605 {
606 if (!CheckPermission("mobileconnection")) {
607 return NS_OK;
608 }
610 return DispatchTrustedEvent(NS_LITERAL_STRING("datachange"));
611 }
613 NS_IMETHODIMP
614 MobileConnection::NotifyUssdReceived(const nsAString& aMessage,
615 bool aSessionEnded)
616 {
617 if (!CheckPermission("mobileconnection")) {
618 return NS_OK;
619 }
621 USSDReceivedEventInit init;
622 init.mBubbles = false;
623 init.mCancelable = false;
624 init.mMessage = aMessage;
625 init.mSessionEnded = aSessionEnded;
627 nsRefPtr<USSDReceivedEvent> event =
628 USSDReceivedEvent::Constructor(this, NS_LITERAL_STRING("ussdreceived"), init);
630 return DispatchTrustedEvent(event);
631 }
633 NS_IMETHODIMP
634 MobileConnection::NotifyDataError(const nsAString& aMessage)
635 {
636 if (!CheckPermission("mobileconnection")) {
637 return NS_OK;
638 }
640 DataErrorEventInit init;
641 init.mBubbles = false;
642 init.mCancelable = false;
643 init.mMessage = aMessage;
645 nsRefPtr<DataErrorEvent> event =
646 DataErrorEvent::Constructor(this, NS_LITERAL_STRING("dataerror"), init);
648 return DispatchTrustedEvent(event);
649 }
651 NS_IMETHODIMP
652 MobileConnection::NotifyCFStateChange(bool aSuccess,
653 unsigned short aAction,
654 unsigned short aReason,
655 const nsAString& aNumber,
656 unsigned short aSeconds,
657 unsigned short aServiceClass)
658 {
659 if (!CheckPermission("mobileconnection")) {
660 return NS_OK;
661 }
663 CFStateChangeEventInit init;
664 init.mBubbles = false;
665 init.mCancelable = false;
666 init.mSuccess = aSuccess;
667 init.mAction = aAction;
668 init.mReason = aReason;
669 init.mNumber = aNumber;
670 init.mTimeSeconds = aSeconds;
671 init.mServiceClass = aServiceClass;
673 nsRefPtr<CFStateChangeEvent> event =
674 CFStateChangeEvent::Constructor(this, NS_LITERAL_STRING("cfstatechange"), init);
676 return DispatchTrustedEvent(event);
677 }
679 NS_IMETHODIMP
680 MobileConnection::NotifyEmergencyCbModeChanged(bool aActive,
681 uint32_t aTimeoutMs)
682 {
683 if (!CheckPermission("mobileconnection")) {
684 return NS_OK;
685 }
687 MozEmergencyCbModeEventInit init;
688 init.mBubbles = false;
689 init.mCancelable = false;
690 init.mActive = aActive;
691 init.mTimeoutMs = aTimeoutMs;
693 nsRefPtr<MozEmergencyCbModeEvent> event =
694 MozEmergencyCbModeEvent::Constructor(this, NS_LITERAL_STRING("emergencycbmodechange"), init);
696 return DispatchTrustedEvent(event);
697 }
699 NS_IMETHODIMP
700 MobileConnection::NotifyOtaStatusChanged(const nsAString& aStatus)
701 {
702 if (!CheckPermission("mobileconnection")) {
703 return NS_OK;
704 }
706 MozOtaStatusEventInit init;
707 init.mBubbles = false;
708 init.mCancelable = false;
709 init.mStatus = aStatus;
711 nsRefPtr<MozOtaStatusEvent> event =
712 MozOtaStatusEvent::Constructor(this, NS_LITERAL_STRING("otastatuschange"), init);
714 return DispatchTrustedEvent(event);
715 }
717 NS_IMETHODIMP
718 MobileConnection::NotifyIccChanged()
719 {
720 if (!CheckPermission("mobileconnection")) {
721 return NS_OK;
722 }
724 return DispatchTrustedEvent(NS_LITERAL_STRING("iccchange"));
725 }
727 NS_IMETHODIMP
728 MobileConnection::NotifyRadioStateChanged()
729 {
730 if (!CheckPermission("mobileconnection")) {
731 return NS_OK;
732 }
734 return DispatchTrustedEvent(NS_LITERAL_STRING("radiostatechange"));
735 }