diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in index 11e0c92ba1e..23243a99013 100644 --- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -166,7 +166,6 @@ @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/mobileconnection/interfaces/moz.build b/dom/mobileconnection/interfaces/moz.build deleted file mode 100644 index 6fd0576dfba..00000000000 --- a/dom/mobileconnection/interfaces/moz.build +++ /dev/null @@ -1,12 +0,0 @@ -# -*- 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/mobileconnection/moz.build b/dom/mobileconnection/moz.build deleted file mode 100644 index 0f03209577a..00000000000 --- a/dom/mobileconnection/moz.build +++ /dev/null @@ -1,7 +0,0 @@ -# -*- 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/moz.build b/dom/moz.build index ce9c373ffb8..20c76a59b8a 100644 --- a/dom/moz.build +++ b/dom/moz.build @@ -95,7 +95,6 @@ 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 ce09a1ccfb6..b17a493a264 100644 --- a/dom/network/interfaces/moz.build +++ b/dom/network/interfaces/moz.build @@ -15,6 +15,12 @@ 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/mobileconnection/interfaces/nsIDOMMobileConnection.idl b/dom/network/interfaces/nsIDOMMobileConnection.idl similarity index 100% rename from dom/mobileconnection/interfaces/nsIDOMMobileConnection.idl rename to dom/network/interfaces/nsIDOMMobileConnection.idl diff --git a/dom/mobileconnection/interfaces/nsIMobileConnectionProvider.idl b/dom/network/interfaces/nsIMobileConnectionProvider.idl similarity index 100% rename from dom/mobileconnection/interfaces/nsIMobileConnectionProvider.idl rename to dom/network/interfaces/nsIMobileConnectionProvider.idl diff --git a/dom/network/src/MobileConnection.cpp b/dom/network/src/MobileConnection.cpp new file mode 100644 index 00000000000..5ed6ae45e9f --- /dev/null +++ b/dom/network/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/network/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::network; + +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/network/src/MobileConnection.h b/dom/network/src/MobileConnection.h new file mode 100644 index 00000000000..398a7e2a5c8 --- /dev/null +++ b/dom/network/src/MobileConnection.h @@ -0,0 +1,60 @@ +/* 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 { +namespace network { + +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 network +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_network_MobileConnection_h diff --git a/dom/network/src/MobileConnectionArray.cpp b/dom/network/src/MobileConnectionArray.cpp new file mode 100644 index 00000000000..0b1abe6466c --- /dev/null +++ b/dom/network/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::network; + +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/network/src/MobileConnectionArray.h b/dom/network/src/MobileConnectionArray.h new file mode 100644 index 00000000000..c1327023830 --- /dev/null +++ b/dom/network/src/MobileConnectionArray.h @@ -0,0 +1,64 @@ +/* -*- 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/network/MobileConnection.h" + +class nsIDOMMozMobileConnection; + +namespace mozilla { +namespace dom { +namespace network { + +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 network +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_network_MobileConnectionArray_h__ diff --git a/dom/network/src/moz.build b/dom/network/src/moz.build index 5e05733ec49..b911e239a71 100644 --- a/dom/network/src/moz.build +++ b/dom/network/src/moz.build @@ -26,6 +26,16 @@ 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', @@ -61,7 +71,7 @@ FAIL_ON_WARNINGS = True include('/ipc/chromium/chromium-config.mozbuild') FINAL_LIBRARY = 'gklayout' - LOCAL_INCLUDES += [ '/dom/events', ] + diff --git a/dom/mobileconnection/tests/marionette/manifest.ini b/dom/network/tests/marionette/manifest.ini similarity index 100% rename from dom/mobileconnection/tests/marionette/manifest.ini rename to dom/network/tests/marionette/manifest.ini diff --git a/dom/mobileconnection/tests/marionette/test_call_barring_change_password.js b/dom/network/tests/marionette/test_call_barring_change_password.js similarity index 100% rename from dom/mobileconnection/tests/marionette/test_call_barring_change_password.js rename to dom/network/tests/marionette/test_call_barring_change_password.js diff --git a/dom/mobileconnection/tests/marionette/test_call_barring_get_option.js b/dom/network/tests/marionette/test_call_barring_get_option.js similarity index 100% rename from dom/mobileconnection/tests/marionette/test_call_barring_get_option.js rename to dom/network/tests/marionette/test_call_barring_get_option.js diff --git a/dom/mobileconnection/tests/marionette/test_call_barring_set_error.js b/dom/network/tests/marionette/test_call_barring_set_error.js similarity index 100% rename from dom/mobileconnection/tests/marionette/test_call_barring_set_error.js rename to dom/network/tests/marionette/test_call_barring_set_error.js diff --git a/dom/mobileconnection/tests/marionette/test_mobile_data_connection.js b/dom/network/tests/marionette/test_mobile_data_connection.js similarity index 100% rename from dom/mobileconnection/tests/marionette/test_mobile_data_connection.js rename to dom/network/tests/marionette/test_mobile_data_connection.js diff --git a/dom/mobileconnection/tests/marionette/test_mobile_data_location.js b/dom/network/tests/marionette/test_mobile_data_location.js similarity index 100% rename from dom/mobileconnection/tests/marionette/test_mobile_data_location.js rename to dom/network/tests/marionette/test_mobile_data_location.js diff --git a/dom/mobileconnection/tests/marionette/test_mobile_data_state.js b/dom/network/tests/marionette/test_mobile_data_state.js similarity index 100% rename from dom/mobileconnection/tests/marionette/test_mobile_data_state.js rename to dom/network/tests/marionette/test_mobile_data_state.js diff --git a/dom/mobileconnection/tests/marionette/test_mobile_last_known_network.js b/dom/network/tests/marionette/test_mobile_last_known_network.js similarity index 100% rename from dom/mobileconnection/tests/marionette/test_mobile_last_known_network.js rename to dom/network/tests/marionette/test_mobile_last_known_network.js diff --git a/dom/mobileconnection/tests/marionette/test_mobile_mmi.js b/dom/network/tests/marionette/test_mobile_mmi.js similarity index 100% rename from dom/mobileconnection/tests/marionette/test_mobile_mmi.js rename to dom/network/tests/marionette/test_mobile_mmi.js diff --git a/dom/mobileconnection/tests/marionette/test_mobile_networks.js b/dom/network/tests/marionette/test_mobile_networks.js similarity index 100% rename from dom/mobileconnection/tests/marionette/test_mobile_networks.js rename to dom/network/tests/marionette/test_mobile_networks.js diff --git a/dom/mobileconnection/tests/marionette/test_mobile_operator_names.js b/dom/network/tests/marionette/test_mobile_operator_names.js similarity index 100% rename from dom/mobileconnection/tests/marionette/test_mobile_operator_names.js rename to dom/network/tests/marionette/test_mobile_operator_names.js diff --git a/dom/mobileconnection/tests/marionette/test_mobile_preferred_network_type.js b/dom/network/tests/marionette/test_mobile_preferred_network_type.js similarity index 100% rename from dom/mobileconnection/tests/marionette/test_mobile_preferred_network_type.js rename to dom/network/tests/marionette/test_mobile_preferred_network_type.js diff --git a/dom/mobileconnection/tests/marionette/test_mobile_preferred_network_type_by_setting.js b/dom/network/tests/marionette/test_mobile_preferred_network_type_by_setting.js similarity index 100% rename from dom/mobileconnection/tests/marionette/test_mobile_preferred_network_type_by_setting.js rename to dom/network/tests/marionette/test_mobile_preferred_network_type_by_setting.js diff --git a/dom/mobileconnection/tests/marionette/test_mobile_roaming_preference.js b/dom/network/tests/marionette/test_mobile_roaming_preference.js similarity index 100% rename from dom/mobileconnection/tests/marionette/test_mobile_roaming_preference.js rename to dom/network/tests/marionette/test_mobile_roaming_preference.js diff --git a/dom/mobileconnection/tests/marionette/test_mobile_set_radio.js b/dom/network/tests/marionette/test_mobile_set_radio.js similarity index 100% rename from dom/mobileconnection/tests/marionette/test_mobile_set_radio.js rename to dom/network/tests/marionette/test_mobile_set_radio.js diff --git a/dom/mobileconnection/tests/marionette/test_mobile_voice_state.js b/dom/network/tests/marionette/test_mobile_voice_state.js similarity index 100% rename from dom/mobileconnection/tests/marionette/test_mobile_voice_state.js rename to dom/network/tests/marionette/test_mobile_voice_state.js diff --git a/testing/marionette/client/marionette/tests/unit-tests.ini b/testing/marionette/client/marionette/tests/unit-tests.ini index b611c77ac2c..b6eddaa23bf 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/mobileconnection/tests/marionette/manifest.ini] +[include:../../../../../dom/network/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]