diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index cea3eda870a..5f6a7de48cf 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -12,7 +12,7 @@
-
+
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 0d13dbfdbf1..b933854ba1f 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -11,7 +11,7 @@
-
+
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index cea3eda870a..5f6a7de48cf 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -12,7 +12,7 @@
-
+
diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index b0de69e6861..f6132fa938a 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
{
- "revision": "18bd82325a82f5b9a3a4b976e213515cd3e5866b",
+ "revision": "f1421b9d57e81c3823a32eb02e6ab6e3c74b12f1",
"repo_path": "/integration/gaia-central"
}
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index 97a212e1142..aff5e5440d0 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -11,7 +11,7 @@
-
+
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index e0477b31603..6ce825a8e39 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -10,7 +10,7 @@
-
+
diff --git a/b2g/config/inari/sources.xml b/b2g/config/inari/sources.xml
index b91d60ca92f..c481a2890e7 100644
--- a/b2g/config/inari/sources.xml
+++ b/b2g/config/inari/sources.xml
@@ -12,7 +12,7 @@
-
+
diff --git a/b2g/config/leo/sources.xml b/b2g/config/leo/sources.xml
index a3bbf36cce6..e94f10bcce5 100644
--- a/b2g/config/leo/sources.xml
+++ b/b2g/config/leo/sources.xml
@@ -11,7 +11,7 @@
-
+
diff --git a/b2g/config/mako/sources.xml b/b2g/config/mako/sources.xml
index 63dc9c0d9a6..fea7e75d1fb 100644
--- a/b2g/config/mako/sources.xml
+++ b/b2g/config/mako/sources.xml
@@ -11,7 +11,7 @@
-
+
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index c478353d9d2..eeee432afae 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -11,7 +11,7 @@
-
+
diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in
index 23243a99013..11e0c92ba1e 100644
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -166,6 +166,7 @@
@BINPATH@/components/dom_icc.xpt
@BINPATH@/components/dom_cellbroadcast.xpt
@BINPATH@/components/dom_wappush.xpt
+@BINPATH@/components/dom_mobileconnection.xpt
#endif
#ifdef MOZ_B2G_BT
@BINPATH@/components/dom_bluetooth.xpt
diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp
index fdeb15e5f3e..ca407c68310 100644
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -40,7 +40,7 @@
#ifdef MOZ_B2G_RIL
#include "mozilla/dom/IccManager.h"
#include "mozilla/dom/CellBroadcast.h"
-#include "mozilla/dom/network/MobileConnectionArray.h"
+#include "mozilla/dom/MobileConnectionArray.h"
#include "mozilla/dom/Voicemail.h"
#endif
#include "nsIIdleObserver.h"
@@ -1180,7 +1180,7 @@ Navigator::GetMozTelephony(ErrorResult& aRv)
#ifdef MOZ_B2G_RIL
-network::MobileConnectionArray*
+MobileConnectionArray*
Navigator::GetMozMobileConnections(ErrorResult& aRv)
{
if (!mMobileConnections) {
@@ -1188,7 +1188,7 @@ Navigator::GetMozMobileConnections(ErrorResult& aRv)
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
- mMobileConnections = new network::MobileConnectionArray(mWindow);
+ mMobileConnections = new MobileConnectionArray(mWindow);
}
return mMobileConnections;
diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h
index 5b55bb7dbac..c70cd5b312f 100644
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -72,9 +72,6 @@ class MozGetUserMediaDevicesSuccessCallback;
namespace network {
class Connection;
-#ifdef MOZ_B2G_RIL
-class MobileConnectionArray;
-#endif
} // namespace Connection;
#ifdef MOZ_B2G_BT
@@ -86,6 +83,7 @@ class BluetoothManager;
#ifdef MOZ_B2G_RIL
class CellBroadcast;
class IccManager;
+class MobileConnectionArray;
class Voicemail;
#endif
@@ -202,7 +200,7 @@ public:
ErrorResult& aRv);
bool MozHasPendingMessage(const nsAString& aType, ErrorResult& aRv);
#ifdef MOZ_B2G_RIL
- network::MobileConnectionArray* GetMozMobileConnections(ErrorResult& aRv);
+ MobileConnectionArray* GetMozMobileConnections(ErrorResult& aRv);
CellBroadcast* GetMozCellBroadcast(ErrorResult& aRv);
Voicemail* GetMozVoicemail(ErrorResult& aRv);
nsIDOMMozIccManager* GetMozIccManager(ErrorResult& aRv);
@@ -318,7 +316,7 @@ private:
nsRefPtr mTelephony;
nsRefPtr mConnection;
#ifdef MOZ_B2G_RIL
- nsRefPtr mMobileConnections;
+ nsRefPtr mMobileConnections;
nsRefPtr mCellBroadcast;
nsRefPtr mIccManager;
nsRefPtr mVoicemail;
diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf
index 30db53931f6..48b15dae4de 100644
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -809,7 +809,7 @@ DOMInterfaces = {
},
'MozMobileConnectionArray': {
- 'nativeType': 'mozilla::dom::network::MobileConnectionArray',
+ 'nativeType': 'mozilla::dom::MobileConnectionArray',
'resultNotAddRefed': [ 'item' ]
},
diff --git a/dom/mobileconnection/interfaces/moz.build b/dom/mobileconnection/interfaces/moz.build
new file mode 100644
index 00000000000..6fd0576dfba
--- /dev/null
+++ b/dom/mobileconnection/interfaces/moz.build
@@ -0,0 +1,12 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+XPIDL_SOURCES += [
+ 'nsIDOMMobileConnection.idl',
+ 'nsIMobileConnectionProvider.idl',
+]
+
+XPIDL_MODULE = 'dom_mobileconnection'
diff --git a/dom/network/interfaces/nsIDOMMobileConnection.idl b/dom/mobileconnection/interfaces/nsIDOMMobileConnection.idl
similarity index 100%
rename from dom/network/interfaces/nsIDOMMobileConnection.idl
rename to dom/mobileconnection/interfaces/nsIDOMMobileConnection.idl
diff --git a/dom/network/interfaces/nsIMobileConnectionProvider.idl b/dom/mobileconnection/interfaces/nsIMobileConnectionProvider.idl
similarity index 100%
rename from dom/network/interfaces/nsIMobileConnectionProvider.idl
rename to dom/mobileconnection/interfaces/nsIMobileConnectionProvider.idl
diff --git a/dom/mobileconnection/moz.build b/dom/mobileconnection/moz.build
new file mode 100644
index 00000000000..0f03209577a
--- /dev/null
+++ b/dom/mobileconnection/moz.build
@@ -0,0 +1,7 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+PARALLEL_DIRS += ['interfaces', 'src']
diff --git a/dom/mobileconnection/src/MobileConnection.cpp b/dom/mobileconnection/src/MobileConnection.cpp
new file mode 100644
index 00000000000..929db84ed56
--- /dev/null
+++ b/dom/mobileconnection/src/MobileConnection.cpp
@@ -0,0 +1,738 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/dom/MobileConnection.h"
+
+#include "GeneratedEvents.h"
+#include "mozilla/dom/CFStateChangeEvent.h"
+#include "mozilla/dom/DataErrorEvent.h"
+#include "mozilla/dom/MozEmergencyCbModeEvent.h"
+#include "mozilla/dom/MozOtaStatusEvent.h"
+#include "mozilla/dom/USSDReceivedEvent.h"
+#include "mozilla/Preferences.h"
+#include "nsDOMEvent.h"
+#include "nsIDOMClassInfo.h"
+#include "nsIDOMDOMRequest.h"
+#include "nsIPermissionManager.h"
+#include "nsIVariant.h"
+
+#include "nsJSUtils.h"
+#include "nsJSON.h"
+#include "mozilla/Services.h"
+
+#define NS_RILCONTENTHELPER_CONTRACTID "@mozilla.org/ril/content-helper;1"
+
+using namespace mozilla::dom;
+
+class MobileConnection::Listener MOZ_FINAL : public nsIMobileConnectionListener
+{
+ MobileConnection* mMobileConnection;
+
+public:
+ NS_DECL_ISUPPORTS
+ NS_FORWARD_SAFE_NSIMOBILECONNECTIONLISTENER(mMobileConnection)
+
+ Listener(MobileConnection* aMobileConnection)
+ : mMobileConnection(aMobileConnection)
+ {
+ MOZ_ASSERT(mMobileConnection);
+ }
+
+ void Disconnect()
+ {
+ MOZ_ASSERT(mMobileConnection);
+ mMobileConnection = nullptr;
+ }
+};
+
+NS_IMPL_ISUPPORTS1(MobileConnection::Listener, nsIMobileConnectionListener)
+
+DOMCI_DATA(MozMobileConnection, MobileConnection)
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(MobileConnection)
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MobileConnection,
+ nsDOMEventTargetHelper)
+ // Don't traverse mListener because it doesn't keep any reference to
+ // MobileConnection but a raw pointer instead. Neither does mProvider because
+ // it's an xpcom service and is only released at shutting down.
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MobileConnection,
+ nsDOMEventTargetHelper)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MobileConnection)
+ NS_INTERFACE_MAP_ENTRY(nsIDOMMozMobileConnection)
+ NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozMobileConnection)
+NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
+
+NS_IMPL_ADDREF_INHERITED(MobileConnection, nsDOMEventTargetHelper)
+NS_IMPL_RELEASE_INHERITED(MobileConnection, nsDOMEventTargetHelper)
+
+NS_IMPL_EVENT_HANDLER(MobileConnection, voicechange)
+NS_IMPL_EVENT_HANDLER(MobileConnection, datachange)
+NS_IMPL_EVENT_HANDLER(MobileConnection, ussdreceived)
+NS_IMPL_EVENT_HANDLER(MobileConnection, dataerror)
+NS_IMPL_EVENT_HANDLER(MobileConnection, cfstatechange)
+NS_IMPL_EVENT_HANDLER(MobileConnection, emergencycbmodechange)
+NS_IMPL_EVENT_HANDLER(MobileConnection, otastatuschange)
+NS_IMPL_EVENT_HANDLER(MobileConnection, iccchange)
+NS_IMPL_EVENT_HANDLER(MobileConnection, radiostatechange)
+
+MobileConnection::MobileConnection(uint32_t aClientId)
+: mClientId(aClientId)
+{
+ mProvider = do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
+ mWindow = nullptr;
+
+ // Not being able to acquire the provider isn't fatal since we check
+ // for it explicitly below.
+ if (!mProvider) {
+ NS_WARNING("Could not acquire nsIMobileConnectionProvider!");
+ return;
+ }
+}
+
+void
+MobileConnection::Init(nsPIDOMWindow* aWindow)
+{
+ BindToOwner(aWindow);
+
+ mWindow = do_GetWeakReference(aWindow);
+ mListener = new Listener(this);
+
+ if (CheckPermission("mobileconnection")) {
+ DebugOnly rv = mProvider->RegisterMobileConnectionMsg(mClientId, mListener);
+ NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
+ "Failed registering mobile connection messages with provider");
+
+ printf_stderr("MobileConnection initialized");
+ }
+}
+
+void
+MobileConnection::Shutdown()
+{
+ if (mProvider && mListener) {
+ mListener->Disconnect();
+ mProvider->UnregisterMobileConnectionMsg(mClientId, mListener);
+ mProvider = nullptr;
+ mListener = nullptr;
+ }
+}
+
+// nsIDOMMozMobileConnection
+
+NS_IMETHODIMP
+MobileConnection::GetLastKnownNetwork(nsAString& aNetwork)
+{
+ aNetwork.SetIsVoid(true);
+
+ if (!CheckPermission("mobilenetwork")) {
+ return NS_OK;
+ }
+
+ return mProvider->GetLastKnownNetwork(mClientId, aNetwork);
+}
+
+NS_IMETHODIMP
+MobileConnection::GetLastKnownHomeNetwork(nsAString& aNetwork)
+{
+ aNetwork.SetIsVoid(true);
+
+ if (!CheckPermission("mobilenetwork")) {
+ return NS_OK;
+ }
+
+ return mProvider->GetLastKnownHomeNetwork(mClientId, aNetwork);
+}
+
+// All fields below require the "mobileconnection" permission.
+
+bool
+MobileConnection::CheckPermission(const char* aType)
+{
+ nsCOMPtr window = do_QueryReferent(mWindow);
+ NS_ENSURE_TRUE(window, false);
+
+ nsCOMPtr permMgr =
+ do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
+ NS_ENSURE_TRUE(permMgr, false);
+
+ uint32_t permission = nsIPermissionManager::DENY_ACTION;
+ permMgr->TestPermissionFromWindow(window, aType, &permission);
+ return permission == nsIPermissionManager::ALLOW_ACTION;
+}
+
+NS_IMETHODIMP
+MobileConnection::GetVoice(nsIDOMMozMobileConnectionInfo** aVoice)
+{
+ *aVoice = nullptr;
+
+ if (!mProvider || !CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+ return mProvider->GetVoiceConnectionInfo(mClientId, aVoice);
+}
+
+NS_IMETHODIMP
+MobileConnection::GetData(nsIDOMMozMobileConnectionInfo** aData)
+{
+ *aData = nullptr;
+
+ if (!mProvider || !CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+ return mProvider->GetDataConnectionInfo(mClientId, aData);
+}
+
+NS_IMETHODIMP
+MobileConnection::GetIccId(nsAString& aIccId)
+{
+ aIccId.SetIsVoid(true);
+
+ if (!mProvider || !CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+ return mProvider->GetIccId(mClientId, aIccId);
+}
+
+NS_IMETHODIMP
+MobileConnection::GetNetworkSelectionMode(nsAString& aNetworkSelectionMode)
+{
+ aNetworkSelectionMode.SetIsVoid(true);
+
+ if (!mProvider || !CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+ return mProvider->GetNetworkSelectionMode(mClientId, aNetworkSelectionMode);
+}
+
+NS_IMETHODIMP
+MobileConnection::GetRadioState(nsAString& aRadioState)
+{
+ aRadioState.SetIsVoid(true);
+
+ if (!mProvider || !CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+ return mProvider->GetRadioState(mClientId, aRadioState);
+}
+
+NS_IMETHODIMP
+MobileConnection::GetSupportedNetworkTypes(nsIVariant** aSupportedNetworkTypes)
+{
+ *aSupportedNetworkTypes = nullptr;
+
+ if (!mProvider || !CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ return mProvider->GetSupportedNetworkTypes(mClientId, aSupportedNetworkTypes);
+}
+
+NS_IMETHODIMP
+MobileConnection::GetNetworks(nsIDOMDOMRequest** aRequest)
+{
+ *aRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->GetNetworks(mClientId, GetOwner(), aRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::SelectNetwork(nsIDOMMozMobileNetworkInfo* aNetwork, nsIDOMDOMRequest** aRequest)
+{
+ *aRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->SelectNetwork(mClientId, GetOwner(), aNetwork, aRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::SelectNetworkAutomatically(nsIDOMDOMRequest** aRequest)
+{
+ *aRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->SelectNetworkAutomatically(mClientId, GetOwner(), aRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::SetPreferredNetworkType(const nsAString& aType,
+ nsIDOMDOMRequest** aDomRequest)
+{
+ *aDomRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->SetPreferredNetworkType(mClientId, GetOwner(), aType, aDomRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::GetPreferredNetworkType(nsIDOMDOMRequest** aDomRequest)
+{
+ *aDomRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->GetPreferredNetworkType(mClientId, GetOwner(), aDomRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::SetRoamingPreference(const nsAString& aMode, nsIDOMDOMRequest** aDomRequest)
+{
+ *aDomRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->SetRoamingPreference(mClientId, GetOwner(), aMode, aDomRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::GetRoamingPreference(nsIDOMDOMRequest** aDomRequest)
+{
+ *aDomRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->GetRoamingPreference(mClientId, GetOwner(), aDomRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::SetVoicePrivacyMode(bool aEnabled, nsIDOMDOMRequest** aDomRequest)
+{
+ *aDomRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->SetVoicePrivacyMode(mClientId, GetOwner(), aEnabled, aDomRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::GetVoicePrivacyMode(nsIDOMDOMRequest** aDomRequest)
+{
+ *aDomRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->GetVoicePrivacyMode(mClientId, GetOwner(), aDomRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::SendMMI(const nsAString& aMMIString,
+ nsIDOMDOMRequest** aRequest)
+{
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->SendMMI(mClientId, GetOwner(), aMMIString, aRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::CancelMMI(nsIDOMDOMRequest** aRequest)
+{
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->CancelMMI(mClientId, GetOwner(),aRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::GetCallForwardingOption(uint16_t aReason,
+ nsIDOMDOMRequest** aRequest)
+{
+ *aRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->GetCallForwardingOption(mClientId, GetOwner(), aReason, aRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::SetCallForwardingOption(nsIDOMMozMobileCFInfo* aCFInfo,
+ nsIDOMDOMRequest** aRequest)
+{
+ *aRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->SetCallForwardingOption(mClientId, GetOwner(), aCFInfo, aRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::GetCallBarringOption(JS::Handle aOption,
+ nsIDOMDOMRequest** aRequest)
+{
+ *aRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->GetCallBarringOption(mClientId, GetOwner(), aOption, aRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::SetCallBarringOption(JS::Handle aOption,
+ nsIDOMDOMRequest** aRequest)
+{
+ *aRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->SetCallBarringOption(mClientId, GetOwner(), aOption, aRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::ChangeCallBarringPassword(JS::Handle aInfo,
+ nsIDOMDOMRequest** aRequest)
+{
+ *aRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->ChangeCallBarringPassword(mClientId, GetOwner(), aInfo, aRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::GetCallWaitingOption(nsIDOMDOMRequest** aRequest)
+{
+ *aRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->GetCallWaitingOption(mClientId, GetOwner(), aRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::SetCallWaitingOption(bool aEnabled,
+ nsIDOMDOMRequest** aRequest)
+{
+ *aRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->SetCallWaitingOption(mClientId, GetOwner(), aEnabled, aRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::GetCallingLineIdRestriction(nsIDOMDOMRequest** aRequest)
+{
+ *aRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->GetCallingLineIdRestriction(mClientId, GetOwner(), aRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::SetCallingLineIdRestriction(unsigned short aClirMode,
+ nsIDOMDOMRequest** aRequest)
+{
+ *aRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->SetCallingLineIdRestriction(mClientId, GetOwner(), aClirMode, aRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::ExitEmergencyCbMode(nsIDOMDOMRequest** aRequest)
+{
+ *aRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->ExitEmergencyCbMode(mClientId, GetOwner(), aRequest);
+}
+
+NS_IMETHODIMP
+MobileConnection::SetRadioEnabled(bool aEnabled,
+ nsIDOMDOMRequest** aRequest)
+{
+ *aRequest = nullptr;
+
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ if (!mProvider) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mProvider->SetRadioEnabled(mClientId, GetOwner(), aEnabled, aRequest);
+}
+
+// nsIMobileConnectionListener
+
+NS_IMETHODIMP
+MobileConnection::NotifyVoiceChanged()
+{
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ return DispatchTrustedEvent(NS_LITERAL_STRING("voicechange"));
+}
+
+NS_IMETHODIMP
+MobileConnection::NotifyDataChanged()
+{
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ return DispatchTrustedEvent(NS_LITERAL_STRING("datachange"));
+}
+
+NS_IMETHODIMP
+MobileConnection::NotifyUssdReceived(const nsAString& aMessage,
+ bool aSessionEnded)
+{
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ USSDReceivedEventInit init;
+ init.mBubbles = false;
+ init.mCancelable = false;
+ init.mMessage = aMessage;
+ init.mSessionEnded = aSessionEnded;
+
+ nsRefPtr event =
+ USSDReceivedEvent::Constructor(this, NS_LITERAL_STRING("ussdreceived"), init);
+
+ return DispatchTrustedEvent(event);
+}
+
+NS_IMETHODIMP
+MobileConnection::NotifyDataError(const nsAString& aMessage)
+{
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ DataErrorEventInit init;
+ init.mBubbles = false;
+ init.mCancelable = false;
+ init.mMessage = aMessage;
+
+ nsRefPtr event =
+ DataErrorEvent::Constructor(this, NS_LITERAL_STRING("dataerror"), init);
+
+ return DispatchTrustedEvent(event);
+}
+
+NS_IMETHODIMP
+MobileConnection::NotifyCFStateChange(bool aSuccess,
+ unsigned short aAction,
+ unsigned short aReason,
+ const nsAString& aNumber,
+ unsigned short aSeconds,
+ unsigned short aServiceClass)
+{
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ CFStateChangeEventInit init;
+ init.mBubbles = false;
+ init.mCancelable = false;
+ init.mSuccess = aSuccess;
+ init.mAction = aAction;
+ init.mReason = aReason;
+ init.mNumber = aNumber;
+ init.mTimeSeconds = aSeconds;
+ init.mServiceClass = aServiceClass;
+
+ nsRefPtr event =
+ CFStateChangeEvent::Constructor(this, NS_LITERAL_STRING("cfstatechange"), init);
+
+ return DispatchTrustedEvent(event);
+}
+
+NS_IMETHODIMP
+MobileConnection::NotifyEmergencyCbModeChanged(bool aActive,
+ uint32_t aTimeoutMs)
+{
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ MozEmergencyCbModeEventInit init;
+ init.mBubbles = false;
+ init.mCancelable = false;
+ init.mActive = aActive;
+ init.mTimeoutMs = aTimeoutMs;
+
+ nsRefPtr event =
+ MozEmergencyCbModeEvent::Constructor(this, NS_LITERAL_STRING("emergencycbmodechange"), init);
+
+ return DispatchTrustedEvent(event);
+}
+
+NS_IMETHODIMP
+MobileConnection::NotifyOtaStatusChanged(const nsAString& aStatus)
+{
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ MozOtaStatusEventInit init;
+ init.mBubbles = false;
+ init.mCancelable = false;
+ init.mStatus = aStatus;
+
+ nsRefPtr event =
+ MozOtaStatusEvent::Constructor(this, NS_LITERAL_STRING("otastatuschange"), init);
+
+ return DispatchTrustedEvent(event);
+}
+
+NS_IMETHODIMP
+MobileConnection::NotifyIccChanged()
+{
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ return DispatchTrustedEvent(NS_LITERAL_STRING("iccchange"));
+}
+
+NS_IMETHODIMP
+MobileConnection::NotifyRadioStateChanged()
+{
+ if (!CheckPermission("mobileconnection")) {
+ return NS_OK;
+ }
+
+ return DispatchTrustedEvent(NS_LITERAL_STRING("radiostatechange"));
+}
diff --git a/dom/mobileconnection/src/MobileConnection.h b/dom/mobileconnection/src/MobileConnection.h
new file mode 100644
index 00000000000..72c5483e5b8
--- /dev/null
+++ b/dom/mobileconnection/src/MobileConnection.h
@@ -0,0 +1,58 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_network_MobileConnection_h
+#define mozilla_dom_network_MobileConnection_h
+
+#include "nsIDOMMobileConnection.h"
+#include "nsIMobileConnectionProvider.h"
+#include "nsDOMEventTargetHelper.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsWeakPtr.h"
+
+namespace mozilla {
+namespace dom {
+
+class MobileConnection : public nsDOMEventTargetHelper
+ , public nsIDOMMozMobileConnection
+{
+ /**
+ * Class MobileConnection doesn't actually inherit
+ * nsIMobileConnectionListener. Instead, it owns an
+ * nsIMobileConnectionListener derived instance mListener and passes it to
+ * nsIMobileConnectionProvider. The onreceived events are first delivered to
+ * mListener and then forwarded to its owner, MobileConnection. See also bug
+ * 775997 comment #51.
+ */
+ class Listener;
+
+public:
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_NSIDOMMOZMOBILECONNECTION
+ NS_DECL_NSIMOBILECONNECTIONLISTENER
+
+ NS_REALLY_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper)
+
+ MobileConnection(uint32_t aClientId);
+
+ void Init(nsPIDOMWindow *aWindow);
+ void Shutdown();
+
+ NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MobileConnection,
+ nsDOMEventTargetHelper)
+
+private:
+ nsCOMPtr mProvider;
+ nsRefPtr mListener;
+ nsWeakPtr mWindow;
+
+ uint32_t mClientId;
+
+ bool CheckPermission(const char* aType);
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_network_MobileConnection_h
diff --git a/dom/mobileconnection/src/MobileConnectionArray.cpp b/dom/mobileconnection/src/MobileConnectionArray.cpp
new file mode 100644
index 00000000000..38f898fa980
--- /dev/null
+++ b/dom/mobileconnection/src/MobileConnectionArray.cpp
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "MobileConnectionArray.h"
+#include "mozilla/dom/MozMobileConnectionArrayBinding.h"
+#include "mozilla/Preferences.h"
+
+using namespace mozilla::dom;
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(MobileConnectionArray)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(MobileConnectionArray)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
+ // Notify our mobile connections that we're going away.
+ tmp->DropConnections();
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(MobileConnectionArray)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMobileConnections)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(MobileConnectionArray)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(MobileConnectionArray)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(MobileConnectionArray)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MobileConnectionArray)
+ NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+MobileConnectionArray::MobileConnectionArray(nsPIDOMWindow* aWindow)
+: mWindow(aWindow), mInitialized(false)
+{
+ uint32_t numRil = mozilla::Preferences::GetUint("ril.numRadioInterfaces", 1);
+ MOZ_ASSERT(numRil > 0);
+
+ bool ret = mMobileConnections.SetLength(numRil);
+ MOZ_ASSERT(ret);
+
+ SetIsDOMBinding();
+}
+
+MobileConnectionArray::~MobileConnectionArray()
+{
+ DropConnections();
+}
+
+void
+MobileConnectionArray::Init()
+{
+ mInitialized = true;
+
+ for (uint32_t id = 0; id < mMobileConnections.Length(); id++) {
+ nsRefPtr mobileConnection = new MobileConnection(id);
+ mobileConnection->Init(mWindow);
+ mMobileConnections[id] = mobileConnection;
+ }
+}
+
+void
+MobileConnectionArray::DropConnections()
+{
+ if (mInitialized) {
+ for (uint32_t i = 0; i < mMobileConnections.Length(); i++) {
+ mMobileConnections[i]->Shutdown();
+ }
+ }
+
+ mMobileConnections.Clear();
+}
+
+nsPIDOMWindow*
+MobileConnectionArray::GetParentObject() const
+{
+ MOZ_ASSERT(mWindow);
+ return mWindow;
+}
+
+JSObject*
+MobileConnectionArray::WrapObject(JSContext* aCx, JS::Handle aScope)
+{
+ return MozMobileConnectionArrayBinding::Wrap(aCx, aScope, this);
+}
+
+nsIDOMMozMobileConnection*
+MobileConnectionArray::Item(uint32_t aIndex)
+{
+ bool unused;
+ return IndexedGetter(aIndex, unused);
+}
+
+uint32_t
+MobileConnectionArray::Length() const
+{
+ return mMobileConnections.Length();
+}
+
+nsIDOMMozMobileConnection*
+MobileConnectionArray::IndexedGetter(uint32_t aIndex, bool& aFound)
+{
+ if (!mInitialized) {
+ Init();
+ }
+
+ aFound = false;
+ aFound = aIndex < mMobileConnections.Length();
+
+ return aFound ? mMobileConnections[aIndex] : nullptr;
+}
diff --git a/dom/mobileconnection/src/MobileConnectionArray.h b/dom/mobileconnection/src/MobileConnectionArray.h
new file mode 100644
index 00000000000..09691c7d981
--- /dev/null
+++ b/dom/mobileconnection/src/MobileConnectionArray.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_network_MobileConnectionArray_h__
+#define mozilla_dom_network_MobileConnectionArray_h__
+
+#include "nsWrapperCache.h"
+#include "mozilla/dom/MobileConnection.h"
+
+class nsIDOMMozMobileConnection;
+
+namespace mozilla {
+namespace dom {
+
+class MobileConnectionArray MOZ_FINAL : public nsISupports,
+ public nsWrapperCache
+{
+public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MobileConnectionArray)
+
+ MobileConnectionArray(nsPIDOMWindow* aWindow);
+
+ nsPIDOMWindow*
+ GetParentObject() const;
+
+ // WrapperCache
+ virtual JSObject*
+ WrapObject(JSContext* aCx, JS::Handle aScope) MOZ_OVERRIDE;
+
+ // WebIDL
+ nsIDOMMozMobileConnection*
+ Item(uint32_t aIndex);
+
+ uint32_t
+ Length() const;
+
+ nsIDOMMozMobileConnection*
+ IndexedGetter(uint32_t aIndex, bool& aFound);
+
+private:
+ ~MobileConnectionArray();
+
+ void
+ Init();
+
+ void
+ DropConnections();
+
+ bool mInitialized;
+
+ nsCOMPtr mWindow;
+ nsTArray> mMobileConnections;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_network_MobileConnectionArray_h__
diff --git a/dom/mobileconnection/src/moz.build b/dom/mobileconnection/src/moz.build
new file mode 100644
index 00000000000..e0355cf452b
--- /dev/null
+++ b/dom/mobileconnection/src/moz.build
@@ -0,0 +1,25 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+EXPORTS.mozilla.dom += [
+ 'MobileConnection.h',
+ 'MobileConnectionArray.h',
+]
+
+SOURCES += [
+ 'MobileConnection.cpp',
+ 'MobileConnectionArray.cpp',
+]
+
+FAIL_ON_WARNINGS = True
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
+FINAL_LIBRARY = 'gklayout'
+
+LOCAL_INCLUDES += [
+ '/dom/events',
+]
diff --git a/dom/network/tests/marionette/manifest.ini b/dom/mobileconnection/tests/marionette/manifest.ini
similarity index 95%
rename from dom/network/tests/marionette/manifest.ini
rename to dom/mobileconnection/tests/marionette/manifest.ini
index dd877eef056..1740c9ab41e 100644
--- a/dom/network/tests/marionette/manifest.ini
+++ b/dom/mobileconnection/tests/marionette/manifest.ini
@@ -20,4 +20,5 @@ disabled = Bug 808783
[test_call_barring_change_password.js]
[test_mobile_set_radio.js]
[test_mobile_last_known_network.js]
+[test_mobile_icc_change.js]
[test_mobile_connections_array_uninitialized.js]
diff --git a/dom/network/tests/marionette/test_call_barring_change_password.js b/dom/mobileconnection/tests/marionette/test_call_barring_change_password.js
similarity index 100%
rename from dom/network/tests/marionette/test_call_barring_change_password.js
rename to dom/mobileconnection/tests/marionette/test_call_barring_change_password.js
diff --git a/dom/network/tests/marionette/test_call_barring_get_option.js b/dom/mobileconnection/tests/marionette/test_call_barring_get_option.js
similarity index 100%
rename from dom/network/tests/marionette/test_call_barring_get_option.js
rename to dom/mobileconnection/tests/marionette/test_call_barring_get_option.js
diff --git a/dom/network/tests/marionette/test_call_barring_set_error.js b/dom/mobileconnection/tests/marionette/test_call_barring_set_error.js
similarity index 100%
rename from dom/network/tests/marionette/test_call_barring_set_error.js
rename to dom/mobileconnection/tests/marionette/test_call_barring_set_error.js
diff --git a/dom/network/tests/marionette/test_mobile_connections_array_uninitialized.js b/dom/mobileconnection/tests/marionette/test_mobile_connections_array_uninitialized.js
similarity index 100%
rename from dom/network/tests/marionette/test_mobile_connections_array_uninitialized.js
rename to dom/mobileconnection/tests/marionette/test_mobile_connections_array_uninitialized.js
diff --git a/dom/network/tests/marionette/test_mobile_data_connection.js b/dom/mobileconnection/tests/marionette/test_mobile_data_connection.js
similarity index 100%
rename from dom/network/tests/marionette/test_mobile_data_connection.js
rename to dom/mobileconnection/tests/marionette/test_mobile_data_connection.js
diff --git a/dom/network/tests/marionette/test_mobile_data_location.js b/dom/mobileconnection/tests/marionette/test_mobile_data_location.js
similarity index 100%
rename from dom/network/tests/marionette/test_mobile_data_location.js
rename to dom/mobileconnection/tests/marionette/test_mobile_data_location.js
diff --git a/dom/network/tests/marionette/test_mobile_data_state.js b/dom/mobileconnection/tests/marionette/test_mobile_data_state.js
similarity index 100%
rename from dom/network/tests/marionette/test_mobile_data_state.js
rename to dom/mobileconnection/tests/marionette/test_mobile_data_state.js
diff --git a/dom/mobileconnection/tests/marionette/test_mobile_icc_change.js b/dom/mobileconnection/tests/marionette/test_mobile_icc_change.js
new file mode 100644
index 00000000000..b93b9272e37
--- /dev/null
+++ b/dom/mobileconnection/tests/marionette/test_mobile_icc_change.js
@@ -0,0 +1,84 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 30000;
+
+SpecialPowers.addPermission("mobileconnection", true, document);
+
+// Permission changes can't change existing Navigator.prototype
+// objects, so grab our objects from a new Navigator
+let ifr = document.createElement("iframe");
+let connection;
+ifr.onload = function() {
+ connection = ifr.contentWindow.navigator.mozMobileConnections[0];
+ ok(connection instanceof ifr.contentWindow.MozMobileConnection,
+ "connection is instanceof " + connection.constructor);
+
+ // The emulator's hard coded iccid value.
+ // See it here {B2G_HOME}/external/qemu/telephony/sim_card.c.
+ is(connection.iccId, 89014103211118510720);
+
+ runNextTest();
+};
+document.body.appendChild(ifr);
+
+function waitForIccChange(callback) {
+ connection.addEventListener("iccchange", function handler() {
+ connection.removeEventListener("iccchange", handler);
+ callback();
+ });
+}
+
+function setRadioEnabled(enabled) {
+ let request = connection.setRadioEnabled(enabled);
+
+ request.onsuccess = function onsuccess() {
+ log('setRadioEnabled: ' + enabled);
+ };
+
+ request.onerror = function onerror() {
+ ok(false, "setRadioEnabled should be ok");
+ };
+}
+
+function testIccChangeOnRadioPowerOff() {
+ // Turn off radio
+ setRadioEnabled(false);
+
+ waitForIccChange(function() {
+ is(connection.iccId, null);
+ runNextTest();
+ });
+}
+
+function testIccChangeOnRadioPowerOn() {
+ // Turn on radio
+ setRadioEnabled(true);
+
+ waitForIccChange(function() {
+ // The emulator's hard coded iccid value.
+ is(connection.iccId, 89014103211118510720);
+ runNextTest();
+ });
+}
+
+let tests = [
+ testIccChangeOnRadioPowerOff,
+ testIccChangeOnRadioPowerOn
+];
+
+function runNextTest() {
+ let test = tests.shift();
+ if (!test) {
+ cleanUp();
+ return;
+ }
+
+ test();
+}
+
+function cleanUp() {
+ SpecialPowers.removePermission("mobileconnection", document);
+
+ finish();
+}
diff --git a/dom/network/tests/marionette/test_mobile_last_known_network.js b/dom/mobileconnection/tests/marionette/test_mobile_last_known_network.js
similarity index 100%
rename from dom/network/tests/marionette/test_mobile_last_known_network.js
rename to dom/mobileconnection/tests/marionette/test_mobile_last_known_network.js
diff --git a/dom/network/tests/marionette/test_mobile_mmi.js b/dom/mobileconnection/tests/marionette/test_mobile_mmi.js
similarity index 100%
rename from dom/network/tests/marionette/test_mobile_mmi.js
rename to dom/mobileconnection/tests/marionette/test_mobile_mmi.js
diff --git a/dom/network/tests/marionette/test_mobile_networks.js b/dom/mobileconnection/tests/marionette/test_mobile_networks.js
similarity index 100%
rename from dom/network/tests/marionette/test_mobile_networks.js
rename to dom/mobileconnection/tests/marionette/test_mobile_networks.js
diff --git a/dom/network/tests/marionette/test_mobile_operator_names.js b/dom/mobileconnection/tests/marionette/test_mobile_operator_names.js
similarity index 100%
rename from dom/network/tests/marionette/test_mobile_operator_names.js
rename to dom/mobileconnection/tests/marionette/test_mobile_operator_names.js
diff --git a/dom/network/tests/marionette/test_mobile_preferred_network_type.js b/dom/mobileconnection/tests/marionette/test_mobile_preferred_network_type.js
similarity index 100%
rename from dom/network/tests/marionette/test_mobile_preferred_network_type.js
rename to dom/mobileconnection/tests/marionette/test_mobile_preferred_network_type.js
diff --git a/dom/network/tests/marionette/test_mobile_preferred_network_type_by_setting.js b/dom/mobileconnection/tests/marionette/test_mobile_preferred_network_type_by_setting.js
similarity index 100%
rename from dom/network/tests/marionette/test_mobile_preferred_network_type_by_setting.js
rename to dom/mobileconnection/tests/marionette/test_mobile_preferred_network_type_by_setting.js
diff --git a/dom/network/tests/marionette/test_mobile_roaming_preference.js b/dom/mobileconnection/tests/marionette/test_mobile_roaming_preference.js
similarity index 100%
rename from dom/network/tests/marionette/test_mobile_roaming_preference.js
rename to dom/mobileconnection/tests/marionette/test_mobile_roaming_preference.js
diff --git a/dom/network/tests/marionette/test_mobile_set_radio.js b/dom/mobileconnection/tests/marionette/test_mobile_set_radio.js
similarity index 100%
rename from dom/network/tests/marionette/test_mobile_set_radio.js
rename to dom/mobileconnection/tests/marionette/test_mobile_set_radio.js
diff --git a/dom/network/tests/marionette/test_mobile_voice_state.js b/dom/mobileconnection/tests/marionette/test_mobile_voice_state.js
similarity index 100%
rename from dom/network/tests/marionette/test_mobile_voice_state.js
rename to dom/mobileconnection/tests/marionette/test_mobile_voice_state.js
diff --git a/dom/moz.build b/dom/moz.build
index 20c76a59b8a..ce9c373ffb8 100644
--- a/dom/moz.build
+++ b/dom/moz.build
@@ -95,6 +95,7 @@ if CONFIG['MOZ_B2G_RIL']:
PARALLEL_DIRS += [
'icc',
'cellbroadcast',
+ 'mobileconnection',
'voicemail',
'wappush',
]
diff --git a/dom/network/interfaces/moz.build b/dom/network/interfaces/moz.build
index b17a493a264..ce09a1ccfb6 100644
--- a/dom/network/interfaces/moz.build
+++ b/dom/network/interfaces/moz.build
@@ -15,12 +15,6 @@ XPIDL_SOURCES += [
'nsIUDPSocketChild.idl',
]
-if CONFIG['MOZ_B2G_RIL']:
- XPIDL_SOURCES += [
- 'nsIDOMMobileConnection.idl',
- 'nsIMobileConnectionProvider.idl',
- ]
-
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
XPIDL_SOURCES += [
'nsIDOMNetworkStats.idl',
diff --git a/dom/network/src/moz.build b/dom/network/src/moz.build
index b911e239a71..5e05733ec49 100644
--- a/dom/network/src/moz.build
+++ b/dom/network/src/moz.build
@@ -26,16 +26,6 @@ UNIFIED_SOURCES += [
'UDPSocketParent.cpp',
]
-if CONFIG['MOZ_B2G_RIL']:
- EXPORTS.mozilla.dom.network += [
- 'MobileConnection.h',
- 'MobileConnectionArray.h',
- ]
- UNIFIED_SOURCES += [
- 'MobileConnection.cpp',
- 'MobileConnectionArray.cpp',
- ]
-
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
EXTRA_JS_MODULES = [
'NetworkStatsDB.jsm',
@@ -71,7 +61,7 @@ FAIL_ON_WARNINGS = True
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'gklayout'
+
LOCAL_INCLUDES += [
'/dom/events',
]
-
diff --git a/testing/marionette/client/marionette/tests/unit-tests.ini b/testing/marionette/client/marionette/tests/unit-tests.ini
index b6eddaa23bf..b611c77ac2c 100644
--- a/testing/marionette/client/marionette/tests/unit-tests.ini
+++ b/testing/marionette/client/marionette/tests/unit-tests.ini
@@ -20,7 +20,7 @@ skip = false
[include:../../../../../dom/voicemail/test/marionette/manifest.ini]
[include:../../../../../dom/battery/test/marionette/manifest.ini]
[include:../../../../../dom/mobilemessage/tests/marionette/manifest.ini]
-[include:../../../../../dom/network/tests/marionette/manifest.ini]
+[include:../../../../../dom/mobileconnection/tests/marionette/manifest.ini]
[include:../../../../../dom/system/gonk/tests/marionette/manifest.ini]
[include:../../../../../dom/icc/tests/marionette/manifest.ini]
[include:../../../../../dom/system/tests/marionette/manifest.ini]
diff --git a/widget/gonk/nsWindow.cpp b/widget/gonk/nsWindow.cpp
index da19993af4d..490e42bbfbe 100644
--- a/widget/gonk/nsWindow.cpp
+++ b/widget/gonk/nsWindow.cpp
@@ -68,6 +68,7 @@ static nsIntRect sVirtualBounds;
static nsRefPtr sGLContext;
static nsTArray sTopWindows;
+static nsWindow *gWindowToRedraw = nullptr;
static nsWindow *gFocusedWindow = nullptr;
static bool sFramebufferOpen;
static bool sUsingOMTC;
@@ -184,24 +185,20 @@ nsWindow::DoDraw(void)
return;
}
- if (sTopWindows.IsEmpty()) {
+ if (!gWindowToRedraw) {
LOG(" no window to draw, bailing");
return;
}
- nsWindow *targetWindow = (nsWindow *)sTopWindows[0];
- while (targetWindow->GetLastChild())
- targetWindow = (nsWindow *)targetWindow->GetLastChild();
+ nsIntRegion region = gWindowToRedraw->mDirtyRegion;
+ gWindowToRedraw->mDirtyRegion.SetEmpty();
- nsIntRegion region = sTopWindows[0]->mDirtyRegion;
- sTopWindows[0]->mDirtyRegion.SetEmpty();
-
- nsIWidgetListener* listener = targetWindow->GetWidgetListener();
+ nsIWidgetListener* listener = gWindowToRedraw->GetWidgetListener();
if (listener) {
- listener->WillPaintWindow(targetWindow);
+ listener->WillPaintWindow(gWindowToRedraw);
}
- LayerManager* lm = targetWindow->GetLayerManager();
+ LayerManager* lm = gWindowToRedraw->GetLayerManager();
if (mozilla::layers::LAYERS_CLIENT == lm->GetBackendType()) {
// No need to do anything, the compositor will handle drawing
} else if (mozilla::layers::LAYERS_BASIC == lm->GetBackendType()) {
@@ -220,12 +217,12 @@ nsWindow::DoDraw(void)
// No double-buffering needed.
AutoLayerManagerSetup setupLayerManager(
- targetWindow, ctx, mozilla::layers::BUFFER_NONE,
+ gWindowToRedraw, ctx, mozilla::layers::BUFFER_NONE,
ScreenRotation(EffectiveScreenRotation()));
- listener = targetWindow->GetWidgetListener();
+ listener = gWindowToRedraw->GetWidgetListener();
if (listener) {
- listener->PaintWindow(targetWindow, region);
+ listener->PaintWindow(gWindowToRedraw, region);
}
}
@@ -237,7 +234,7 @@ nsWindow::DoDraw(void)
NS_RUNTIMEABORT("Unexpected layer manager type");
}
- listener = targetWindow->GetWidgetListener();
+ listener = gWindowToRedraw->GetWidgetListener();
if (listener) {
listener->DidPaintWindow();
}
@@ -284,10 +281,11 @@ nsWindow::Create(nsIWidget *aParent,
mBounds = aRect;
- mParent = (nsWindow *)aParent;
+ nsWindow *parent = (nsWindow *)aNativeParent;
+ mParent = parent;
mVisible = false;
- if (!aParent) {
+ if (!aNativeParent) {
mBounds = sVirtualBounds;
}
@@ -305,6 +303,8 @@ nsWindow::Destroy(void)
{
mOnDestroyCalled = true;
sTopWindows.RemoveElement(this);
+ if (this == gWindowToRedraw)
+ gWindowToRedraw = nullptr;
if (this == gFocusedWindow)
gFocusedWindow = nullptr;
nsBaseWidget::OnDestroy();
@@ -381,8 +381,8 @@ nsWindow::Resize(double aX,
if (mWidgetListener)
mWidgetListener->WindowResized(this, mBounds.width, mBounds.height);
- if (aRepaint)
- Invalidate(sVirtualBounds);
+ if (aRepaint && gWindowToRedraw)
+ gWindowToRedraw->Invalidate(sVirtualBounds);
return NS_OK;
}
@@ -418,13 +418,14 @@ nsWindow::ConfigureChildren(const nsTArray&)
NS_IMETHODIMP
nsWindow::Invalidate(const nsIntRect &aRect)
{
- nsWindow *top = mParent;
- while (top && top->mParent)
- top = top->mParent;
- if (top != sTopWindows[0] && this != sTopWindows[0])
+ nsWindow *parent = mParent;
+ while (parent && parent != sTopWindows[0])
+ parent = parent->mParent;
+ if (parent != sTopWindows[0])
return NS_OK;
mDirtyRegion.Or(mDirtyRegion, aRect);
+ gWindowToRedraw = this;
gDrawRequest = true;
mozilla::NotifyEvent();
return NS_OK;
@@ -452,6 +453,8 @@ nsWindow::GetNativeData(uint32_t aDataType)
switch (aDataType) {
case NS_NATIVE_WINDOW:
return GetGonkDisplay()->GetNativeWindow();
+ case NS_NATIVE_WIDGET:
+ return this;
}
return nullptr;
}
@@ -763,12 +766,12 @@ nsScreenGonk::SetRotation(uint32_t aRotation)
sVirtualBounds = gScreenBounds;
}
- nsAppShell::NotifyScreenRotation();
-
for (unsigned int i = 0; i < sTopWindows.Length(); i++)
sTopWindows[i]->Resize(sVirtualBounds.width,
sVirtualBounds.height,
- true);
+ !i);
+
+ nsAppShell::NotifyScreenRotation();
return NS_OK;
}