Bug 843452 - Part 2-3: MobileConnection DOM changes for MobileConnectionService interface. r=smaug
authorEdgar Chen <echen@mozilla.com>
Wed, 02 Jul 2014 17:38:23 +0800
changeset 203332 c6896f655e86c8d7a18f5a669bf090de2b564894
parent 203331 3468cd2bbf599071046376339e24b25ea37aab3e
child 203333 df5f41ac3cb9bd244af28098b7994e653263a129
push id48665
push userryanvm@gmail.com
push dateWed, 03 Sep 2014 20:40:15 +0000
treeherdermozilla-inbound@0da762e6868a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs843452
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 843452 - Part 2-3: MobileConnection DOM changes for MobileConnectionService interface. r=smaug
dom/mobileconnection/MobileConnection.cpp
dom/mobileconnection/MobileConnection.h
dom/mobileconnection/MobileConnectionCallback.cpp
dom/mobileconnection/MobileConnectionCallback.h
dom/mobileconnection/moz.build
--- a/dom/mobileconnection/MobileConnection.cpp
+++ b/dom/mobileconnection/MobileConnection.cpp
@@ -1,32 +1,31 @@
 /* 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 "MobileConnection.h"
 
+#include "MobileConnectionCallback.h"
 #include "mozilla/dom/CFStateChangeEvent.h"
 #include "mozilla/dom/DataErrorEvent.h"
 #include "mozilla/dom/MozClirModeEvent.h"
 #include "mozilla/dom/MozEmergencyCbModeEvent.h"
 #include "mozilla/dom/MozOtaStatusEvent.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/dom/USSDReceivedEvent.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "nsIDOMDOMRequest.h"
 #include "nsIPermissionManager.h"
 #include "nsIVariant.h"
 #include "nsJSON.h"
 #include "nsJSUtils.h"
 #include "nsServiceManagerUtils.h"
 
-#define NS_RILCONTENTHELPER_CONTRACTID "@mozilla.org/ril/content-helper;1"
-
 #define CONVERT_STRING_TO_NULLABLE_ENUM(_string, _enumType, _enum)      \
 {                                                                       \
   uint32_t i = 0;                                                       \
   for (const EnumEntry* entry = _enumType##Values::strings;             \
        entry->value;                                                    \
        ++entry, ++i) {                                                  \
     if (_string.EqualsASCII(entry->value)) {                            \
       _enum.SetValue(static_cast<_enumType>(i));                        \
@@ -36,16 +35,17 @@
 
 #define CONVERT_ENUM_TO_STRING(_enumType, _enum, _string)               \
 {                                                                       \
   uint32_t index = uint32_t(_enum);                                     \
   _string.AssignASCII(_enumType##Values::strings[index].value,          \
                       _enumType##Values::strings[index].length);        \
 }
 
+using mozilla::ErrorResult;
 using namespace mozilla::dom;
 
 class MobileConnection::Listener MOZ_FINAL : public nsIMobileConnectionListener
 {
   MobileConnection* mMobileConnection;
 
 public:
   NS_DECL_ISUPPORTS
@@ -72,17 +72,17 @@ private:
 
 NS_IMPL_ISUPPORTS(MobileConnection::Listener, nsIMobileConnectionListener)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(MobileConnection)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MobileConnection,
                                                   DOMEventTargetHelper)
   // Don't traverse mListener because it doesn't keep any reference to
-  // MobileConnection but a raw pointer instead. Neither does mProvider because
+  // MobileConnection but a raw pointer instead. Neither does mService because
   // it's an xpcom service and is only released at shutting down.
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVoice)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mData)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MobileConnection,
                                                 DOMEventTargetHelper)
   tmp->Shutdown();
@@ -100,44 +100,44 @@ NS_IMPL_ADDREF_INHERITED(MobileConnectio
 NS_IMPL_RELEASE_INHERITED(MobileConnection, DOMEventTargetHelper)
 
 MobileConnection::MobileConnection(nsPIDOMWindow* aWindow, uint32_t aClientId)
   : DOMEventTargetHelper(aWindow)
   , mClientId(aClientId)
 {
   SetIsDOMBinding();
 
-  mProvider = do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
+  mService = do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
 
-  // Not being able to acquire the provider isn't fatal since we check
+  // Not being able to acquire the service isn't fatal since we check
   // for it explicitly below.
-  if (!mProvider) {
-    NS_WARNING("Could not acquire nsIMobileConnectionProvider!");
+  if (!mService) {
+    NS_WARNING("Could not acquire nsIMobileConnectionService!");
     return;
   }
 
   mListener = new Listener(this);
   mVoice = new MobileConnectionInfo(GetOwner());
   mData = new MobileConnectionInfo(GetOwner());
 
   if (CheckPermission("mobileconnection")) {
-    DebugOnly<nsresult> rv = mProvider->RegisterMobileConnectionMsg(mClientId, mListener);
+    DebugOnly<nsresult> rv = mService->RegisterListener(mClientId, mListener);
     NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
-                     "Failed registering mobile connection messages with provider");
+                     "Failed registering mobile connection messages with service");
     UpdateVoice();
     UpdateData();
   }
 }
 
 void
 MobileConnection::Shutdown()
 {
   if (mListener) {
-    if (mProvider) {
-      mProvider->UnregisterMobileConnectionMsg(mClientId, mListener);
+    if (mService) {
+      mService->UnregisterListener(mClientId, mListener);
     }
 
     mListener->Disconnect();
     mListener = nullptr;
   }
 }
 
 MobileConnection::~MobileConnection()
@@ -170,61 +170,61 @@ MobileConnection::CheckPermission(const 
   uint32_t permission = nsIPermissionManager::DENY_ACTION;
   permMgr->TestPermissionFromWindow(GetOwner(), aType, &permission);
   return permission == nsIPermissionManager::ALLOW_ACTION;
 }
 
 void
 MobileConnection::UpdateVoice()
 {
-  if (!mProvider) {
+  if (!mService) {
     return;
   }
 
   nsCOMPtr<nsIMobileConnectionInfo> info;
-  mProvider->GetVoiceConnectionInfo(mClientId, getter_AddRefs(info));
+  mService->GetVoiceConnectionInfo(mClientId, getter_AddRefs(info));
   mVoice->Update(info);
 }
 
 void
 MobileConnection::UpdateData()
 {
-  if (!mProvider) {
+  if (!mService) {
     return;
   }
 
   nsCOMPtr<nsIMobileConnectionInfo> info;
-  mProvider->GetDataConnectionInfo(mClientId, getter_AddRefs(info));
+  mService->GetDataConnectionInfo(mClientId, getter_AddRefs(info));
   mData->Update(info);
 }
 
 // WebIDL interface
 
 void
 MobileConnection::GetLastKnownNetwork(nsString& aRetVal) const
 {
   aRetVal.SetIsVoid(true);
 
-  if (!mProvider) {
+  if (!mService) {
     return;
   }
 
-  mProvider->GetLastKnownNetwork(mClientId, aRetVal);
+  mService->GetLastKnownNetwork(mClientId, aRetVal);
 }
 
 void
 MobileConnection::GetLastKnownHomeNetwork(nsString& aRetVal) const
 {
   aRetVal.SetIsVoid(true);
 
-  if (!mProvider) {
+  if (!mService) {
     return;
   }
 
-  mProvider->GetLastKnownHomeNetwork(mClientId, aRetVal);
+  mService->GetLastKnownHomeNetwork(mClientId, aRetVal);
 }
 
 // All fields below require the "mobileconnection" permission.
 
 MobileConnectionInfo*
 MobileConnection::Voice() const
 {
   return mVoice;
@@ -236,66 +236,66 @@ MobileConnection::Data() const
   return mData;
 }
 
 void
 MobileConnection::GetIccId(nsString& aRetVal) const
 {
   aRetVal.SetIsVoid(true);
 
-  if (!mProvider) {
+  if (!mService) {
     return;
   }
 
-  mProvider->GetIccId(mClientId, aRetVal);
+  mService->GetIccId(mClientId, aRetVal);
 }
 
 Nullable<MobileNetworkSelectionMode>
 MobileConnection::GetNetworkSelectionMode() const
 {
   Nullable<MobileNetworkSelectionMode> retVal =
     Nullable<MobileNetworkSelectionMode>();
 
-  if (!mProvider) {
+  if (!mService) {
     return retVal;
   }
 
   nsAutoString mode;
-  mProvider->GetNetworkSelectionMode(mClientId, mode);
+  mService->GetNetworkSelectionMode(mClientId, mode);
   CONVERT_STRING_TO_NULLABLE_ENUM(mode, MobileNetworkSelectionMode, retVal);
 
   return retVal;
 }
 
 Nullable<MobileRadioState>
 MobileConnection::GetRadioState() const
 {
   Nullable<MobileRadioState> retVal = Nullable<MobileRadioState>();
 
-  if (!mProvider) {
+  if (!mService) {
     return retVal;
   }
 
   nsAutoString state;
-  mProvider->GetRadioState(mClientId, state);
+  mService->GetRadioState(mClientId, state);
   CONVERT_STRING_TO_NULLABLE_ENUM(state, MobileRadioState, retVal);
 
   return retVal;
 }
 
 void
 MobileConnection::GetSupportedNetworkTypes(nsTArray<MobileNetworkType>& aTypes) const
 {
-  if (!mProvider) {
+  if (!mService) {
     return;
   }
 
   nsCOMPtr<nsIVariant> variant;
-  mProvider->GetSupportedNetworkTypes(mClientId,
-                                      getter_AddRefs(variant));
+  mService->GetSupportedNetworkTypes(mClientId,
+                                     getter_AddRefs(variant));
 
   uint16_t type;
   nsIID iid;
   uint32_t count;
   void* data;
 
   // Convert the nsIVariant to an array.  We own the resulting buffer and its
   // elements.
@@ -317,253 +317,281 @@ MobileConnection::GetSupportedNetworkTyp
     }
   }
   NS_Free(data);
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::GetNetworks(ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->GetNetworks(mClientId, GetOwner(),
-                                       getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->GetNetworks(mClientId, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SelectNetwork(MobileNetworkInfo& aNetwork, ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SelectNetwork(mClientId, GetOwner(), &aNetwork,
-                                         getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SelectNetwork(mClientId, &aNetwork, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SelectNetworkAutomatically(ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SelectNetworkAutomatically(mClientId, GetOwner(),
-                                                      getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SelectNetworkAutomatically(mClientId,
+                                                     requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SetPreferredNetworkType(MobilePreferredNetworkType& aType,
                                           ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsAutoString type;
   CONVERT_ENUM_TO_STRING(MobilePreferredNetworkType, aType, type);
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SetPreferredNetworkType(mClientId, GetOwner(), type,
-                                                   getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SetPreferredNetworkType(mClientId, type,
+                                                  requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::GetPreferredNetworkType(ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->GetPreferredNetworkType(mClientId, GetOwner(),
-                                                   getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->GetPreferredNetworkType(mClientId, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SetRoamingPreference(MobileRoamingMode& aMode,
                                        ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsAutoString mode;
   CONVERT_ENUM_TO_STRING(MobileRoamingMode, aMode, mode);
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SetRoamingPreference(mClientId, GetOwner(), mode,
-                                                getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SetRoamingPreference(mClientId, mode, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::GetRoamingPreference(ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->GetRoamingPreference(mClientId, GetOwner(),
-                                                getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->GetRoamingPreference(mClientId, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
+    return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SetVoicePrivacyMode(bool aEnabled, ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SetVoicePrivacyMode(mClientId, GetOwner(), aEnabled,
-                                               getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SetVoicePrivacyMode(mClientId, aEnabled,
+                                              requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::GetVoicePrivacyMode(ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->GetVoicePrivacyMode(mClientId, GetOwner(),
-                                               getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->GetVoicePrivacyMode(mClientId, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SendMMI(const nsAString& aMMIString, ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SendMMI(mClientId, GetOwner(), aMMIString,
-                                   getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SendMMI(mClientId, aMMIString, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::CancelMMI(ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->CancelMMI(mClientId, GetOwner(),
-                                     getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->CancelMMI(mClientId, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::GetCallForwardingOption(uint16_t aReason, ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->GetCallForwarding(mClientId, GetOwner(), aReason,
-                                             getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->GetCallForwarding(mClientId, aReason, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SetCallForwardingOption(const MozCallForwardingOptions& aOptions,
                                           ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   AutoJSAPI jsapi;
   if (!NS_WARN_IF(jsapi.Init(GetOwner()))) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
@@ -571,32 +599,34 @@ MobileConnection::SetCallForwardingOptio
 
   JSContext *cx = jsapi.cx();
   JS::Rooted<JS::Value> options(cx);
   if (!ToJSValue(cx, aOptions, &options)) {
     aRv.Throw(NS_ERROR_TYPE_ERR);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SetCallForwarding(mClientId, GetOwner(), options,
-                                             getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SetCallForwarding(mClientId, options, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::GetCallBarringOption(const MozCallBarringOptions& aOptions,
                                        ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   AutoJSAPI jsapi;
   if (!NS_WARN_IF(jsapi.Init(GetOwner()))) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
@@ -604,32 +634,34 @@ MobileConnection::GetCallBarringOption(c
 
   JSContext *cx = jsapi.cx();
   JS::Rooted<JS::Value> options(cx);
   if (!ToJSValue(cx, aOptions, &options)) {
     aRv.Throw(NS_ERROR_TYPE_ERR);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->GetCallBarring(mClientId, GetOwner(), options,
-                                          getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->GetCallBarring(mClientId, options, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SetCallBarringOption(const MozCallBarringOptions& aOptions,
                                        ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   AutoJSAPI jsapi;
   if (!NS_WARN_IF(jsapi.Init(GetOwner()))) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
@@ -637,32 +669,34 @@ MobileConnection::SetCallBarringOption(c
 
   JSContext *cx = jsapi.cx();
   JS::Rooted<JS::Value> options(cx);
   if (!ToJSValue(cx, aOptions, &options)) {
     aRv.Throw(NS_ERROR_TYPE_ERR);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SetCallBarring(mClientId, GetOwner(), options,
-                                          getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SetCallBarring(mClientId, options, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::ChangeCallBarringPassword(const MozCallBarringOptions& aOptions,
                                             ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   AutoJSAPI jsapi;
   if (!NS_WARN_IF(jsapi.Init(GetOwner()))) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
@@ -670,144 +704,157 @@ MobileConnection::ChangeCallBarringPassw
 
   JSContext *cx = jsapi.cx();
   JS::Rooted<JS::Value> options(cx);
   if (!ToJSValue(cx, aOptions, &options)) {
     aRv.Throw(NS_ERROR_TYPE_ERR);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->ChangeCallBarringPassword(mClientId,
-                                                     GetOwner(),
-                                                     options,
-                                                     getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->ChangeCallBarringPassword(mClientId, options,
+                                                    requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::GetCallWaitingOption(ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->GetCallWaiting(mClientId, GetOwner(),
-                                          getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->GetCallWaiting(mClientId, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SetCallWaitingOption(bool aEnabled, ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SetCallWaiting(mClientId, GetOwner(), aEnabled,
-                                          getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SetCallWaiting(mClientId, aEnabled, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::GetCallingLineIdRestriction(ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->GetCallingLineIdRestriction(mClientId, GetOwner(),
-                                                       getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->GetCallingLineIdRestriction(mClientId,
+                                                      requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SetCallingLineIdRestriction(uint16_t aMode,
                                               ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SetCallingLineIdRestriction(mClientId,
-                                                       GetOwner(),
-                                                       aMode,
-                                                       getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SetCallingLineIdRestriction(mClientId, aMode,
+                                                      requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::ExitEmergencyCbMode(ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->ExitEmergencyCbMode(mClientId, GetOwner(),
-                                               getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->ExitEmergencyCbMode(mClientId, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SetRadioEnabled(bool aEnabled, ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SetRadioEnabled(mClientId, GetOwner(), aEnabled,
-                                           getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SetRadioEnabled(mClientId, aEnabled, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 // nsIMobileConnectionListener
 
 NS_IMETHODIMP
 MobileConnection::NotifyVoiceChanged()
 {
   if (!CheckPermission("mobileconnection")) {
@@ -865,22 +912,22 @@ MobileConnection::NotifyDataError(const 
 
   nsRefPtr<DataErrorEvent> 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)
+MobileConnection::NotifyCFStateChanged(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;
@@ -967,8 +1014,26 @@ MobileConnection::NotifyClirModeChanged(
   init.mCancelable = false;
   init.mMode = aMode;
 
   nsRefPtr<MozClirModeEvent> event =
     MozClirModeEvent::Constructor(this, NS_LITERAL_STRING("clirmodechange"), init);
 
   return DispatchTrustedEvent(event);
 }
+
+NS_IMETHODIMP
+MobileConnection::NotifyLastKnownNetworkChanged()
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileConnection::NotifyLastKnownHomeNetworkChanged()
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileConnection::NotifyNetworkSelectionModeChanged()
+{
+  return NS_OK;
+}
--- a/dom/mobileconnection/MobileConnection.h
+++ b/dom/mobileconnection/MobileConnection.h
@@ -6,30 +6,30 @@
 #define mozilla_dom_MobileConnection_h
 
 #include "MobileConnectionInfo.h"
 #include "MobileNetworkInfo.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/dom/DOMRequest.h"
 #include "mozilla/dom/MozMobileConnectionBinding.h"
 #include "nsCycleCollectionParticipant.h"
-#include "nsIMobileConnectionProvider.h"
+#include "nsIMobileConnectionService.h"
 #include "nsWeakPtr.h"
 
 namespace mozilla {
 namespace dom {
 
 class MobileConnection MOZ_FINAL : public DOMEventTargetHelper,
                                    private nsIMobileConnectionListener
 {
   /**
    * Class MobileConnection doesn't actually expose
    * nsIMobileConnectionListener. Instead, it owns an
    * nsIMobileConnectionListener derived instance mListener and passes it to
-   * nsIMobileConnectionProvider. The onreceived events are first delivered to
+   * nsIMobileConnectionService. 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_NSIMOBILECONNECTIONLISTENER
@@ -159,17 +159,17 @@ public:
   IMPL_EVENT_HANDLER(radiostatechange)
   IMPL_EVENT_HANDLER(clirmodechange)
 
 private:
   ~MobileConnection();
 
 private:
   uint32_t mClientId;
-  nsCOMPtr<nsIMobileConnectionProvider> mProvider;
+  nsCOMPtr<nsIMobileConnectionService> mService;
   nsRefPtr<Listener> mListener;
   nsRefPtr<MobileConnectionInfo> mVoice;
   nsRefPtr<MobileConnectionInfo> mData;
 
   bool
   CheckPermission(const char* aType) const;
 
   void
new file mode 100644
--- /dev/null
+++ b/dom/mobileconnection/MobileConnectionCallback.cpp
@@ -0,0 +1,187 @@
+/* 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 "MobileConnectionCallback.h"
+
+#include "DOMMMIError.h"
+#include "mozilla/dom/MobileNetworkInfo.h"
+#include "mozilla/dom/MozMobileConnectionBinding.h"
+#include "mozilla/dom/ToJSValue.h"
+#include "nsJSUtils.h"
+#include "nsServiceManagerUtils.h"
+
+using namespace mozilla::dom;
+
+NS_IMPL_ISUPPORTS(MobileConnectionCallback, nsIMobileConnectionCallback)
+
+MobileConnectionCallback::MobileConnectionCallback(nsPIDOMWindow* aWindow,
+                                                   DOMRequest* aRequest)
+  : mWindow(aWindow)
+  , mRequest(aRequest)
+{
+}
+
+/**
+ * Notify Success.
+ */
+nsresult
+MobileConnectionCallback::NotifySuccess(JS::Handle<JS::Value> aResult)
+{
+  nsCOMPtr<nsIDOMRequestService> rs = do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
+  NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE);
+
+  return rs->FireSuccessAsync(mRequest, aResult);
+}
+
+// nsIMobileConnectionCallback
+
+NS_IMETHODIMP
+MobileConnectionCallback::NotifySuccess()
+{
+  return NotifySuccess(JS::UndefinedHandleValue);
+}
+
+NS_IMETHODIMP
+MobileConnectionCallback::NotifySuccessWithString(const nsAString& aResult)
+{
+  AutoJSAPI jsapi;
+  if (!NS_WARN_IF(jsapi.Init(mWindow))) {
+    return NS_ERROR_FAILURE;
+  }
+
+  JSContext* cx = jsapi.cx();
+  JS::Rooted<JS::Value> jsResult(cx);
+
+  if (!ToJSValue(cx, aResult, &jsResult)) {
+    JS_ClearPendingException(cx);
+    return NS_ERROR_TYPE_ERR;
+  }
+
+  return NotifySuccess(jsResult);
+}
+
+NS_IMETHODIMP
+MobileConnectionCallback::NotifySuccessWithBoolean(bool aResult)
+{
+  return aResult ? NotifySuccess(JS::TrueHandleValue)
+                 : NotifySuccess(JS::FalseHandleValue);
+}
+
+NS_IMETHODIMP
+MobileConnectionCallback::NotifyGetNetworksSuccess(uint32_t aCount,
+                                                   nsIMobileNetworkInfo** aNetworks)
+{
+  nsTArray<nsRefPtr<MobileNetworkInfo>> results;
+  for (uint32_t i = 0; i < aCount; i++)
+  {
+    nsRefPtr<MobileNetworkInfo> networkInfo = new MobileNetworkInfo(mWindow);
+    networkInfo->Update(aNetworks[i]);
+    results.AppendElement(networkInfo);
+  }
+
+  AutoJSAPI jsapi;
+  if (!NS_WARN_IF(jsapi.Init(mWindow))) {
+    return NS_ERROR_FAILURE;
+  }
+
+  JSContext* cx = jsapi.cx();
+  JS::Rooted<JS::Value> jsResult(cx);
+
+  if (!ToJSValue(cx, results, &jsResult)) {
+    JS_ClearPendingException(cx);
+    return NS_ERROR_TYPE_ERR;
+  }
+
+  return NotifySuccess(jsResult);
+}
+
+NS_IMETHODIMP
+MobileConnectionCallback::NotifySendCancelMmiSuccess(JS::Handle<JS::Value> aResult)
+{
+  return NotifySuccess(aResult);
+}
+
+NS_IMETHODIMP
+MobileConnectionCallback::NotifyGetCallForwardingSuccess(JS::Handle<JS::Value> aResults)
+{
+  return NotifySuccess(aResults);
+}
+
+NS_IMETHODIMP
+MobileConnectionCallback::NotifyGetCallBarringSuccess(uint16_t aProgram,
+                                                      bool aEnabled,
+                                                      uint16_t aServiceClass)
+{
+  MozCallBarringOptions result;
+  result.mProgram.Construct().SetValue(aProgram);
+  result.mEnabled.Construct().SetValue(aEnabled);
+  result.mServiceClass.Construct().SetValue(aServiceClass);
+
+  AutoJSAPI jsapi;
+  if (!NS_WARN_IF(jsapi.Init(mWindow))) {
+    return NS_ERROR_FAILURE;
+  }
+
+  JSContext* cx = jsapi.cx();
+  JS::Rooted<JS::Value> jsResult(cx);
+  if (!ToJSValue(cx, result, &jsResult)) {
+    JS_ClearPendingException(cx);
+    return NS_ERROR_TYPE_ERR;
+  }
+
+  return NotifySuccess(jsResult);
+}
+
+NS_IMETHODIMP
+MobileConnectionCallback::NotifyGetClirStatusSuccess(uint16_t aN, uint16_t aM)
+{
+  MozClirStatus result;
+  result.mN.Construct(aN);
+  result.mM.Construct(aM);
+
+  AutoJSAPI jsapi;
+  if (!NS_WARN_IF(jsapi.Init(mWindow))) {
+    return NS_ERROR_FAILURE;
+  }
+
+  JSContext* cx = jsapi.cx();
+  JS::Rooted<JS::Value> jsResult(cx);
+  if (!ToJSValue(cx, result, &jsResult)) {
+    JS_ClearPendingException(cx);
+    return NS_ERROR_TYPE_ERR;
+  }
+
+  return NotifySuccess(jsResult);
+};
+
+NS_IMETHODIMP
+MobileConnectionCallback::NotifyError(const nsAString& aName,
+                                      const nsAString& aMessage,
+                                      const nsAString& aServiceCode,
+                                      uint16_t aInfo,
+                                      uint8_t aArgc)
+{
+  nsCOMPtr<nsIDOMRequestService> rs = do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
+  NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE);
+
+  nsRefPtr<DOMError> error;
+  switch (aArgc) {
+    case 0:
+      return rs->FireErrorAsync(mRequest, aName);
+    case 1:
+      error = new DOMMMIError(mWindow, aName, aMessage, EmptyString(),
+                              Nullable<int16_t>());
+      return rs->FireDetailedError(mRequest, error);
+    case 2:
+      error = new DOMMMIError(mWindow, aName, aMessage, aServiceCode,
+                              Nullable<int16_t>());
+      return rs->FireDetailedError(mRequest, error);
+    case 3:
+      error = new DOMMMIError(mWindow, aName, aMessage, aServiceCode,
+                              Nullable<int16_t>(int16_t(aInfo)));
+      return rs->FireDetailedError(mRequest, error);
+  }
+
+  return NS_ERROR_FAILURE;
+}
new file mode 100644
--- /dev/null
+++ b/dom/mobileconnection/MobileConnectionCallback.h
@@ -0,0 +1,46 @@
+/* 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_MobileConnectionCallback_h
+#define mozilla_dom_MobileConnectionCallback_h
+
+#include "mozilla/dom/DOMRequest.h"
+#include "nsCOMPtr.h"
+#include "nsIMobileConnectionService.h"
+
+namespace mozilla {
+namespace dom {
+
+/**
+ * A callback object for handling asynchronous request/response. This object is
+ * created when an asynchronous request is made and should be destroyed after
+ * Notify*Success/Error is called.
+ * The modules hold the reference of MobileConnectionCallback in OOP mode and
+ * non-OOP mode are different.
+ * - OOP mode: MobileConnectionRequestChild
+ * - non-OOP mode: MobileConnectionGonkService
+ * The reference should be released after Notify*Success/Error is called.
+ */
+class MobileConnectionCallback MOZ_FINAL : public nsIMobileConnectionCallback
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIMOBILECONNECTIONCALLBACK
+
+  MobileConnectionCallback(nsPIDOMWindow* aWindow, DOMRequest* aRequest);
+
+private:
+  ~MobileConnectionCallback() {}
+
+  nsresult
+  NotifySuccess(JS::Handle<JS::Value> aResult);
+
+  nsCOMPtr<nsPIDOMWindow> mWindow;
+  nsRefPtr<DOMRequest> mRequest;
+};
+
+} // name space dom
+} // name space mozilla
+
+#endif // mozilla_dom_MobileConnectionCallback_h
--- a/dom/mobileconnection/moz.build
+++ b/dom/mobileconnection/moz.build
@@ -8,25 +8,27 @@ DIRS += ['interfaces']
 
 MOCHITEST_MANIFESTS += ['tests/mochitest/mochitest.ini']
 
 EXPORTS.mozilla.dom += [
     'DOMMMIError.h',
     'MobileCellInfo.h',
     'MobileConnection.h',
     'MobileConnectionArray.h',
+    'MobileConnectionCallback.h',
     'MobileConnectionInfo.h',
     'MobileNetworkInfo.h',
 ]
 
 SOURCES += [
     'DOMMMIError.cpp',
     'MobileCellInfo.cpp',
     'MobileConnection.cpp',
     'MobileConnectionArray.cpp',
+    'MobileConnectionCallback.cpp',
     'MobileConnectionInfo.cpp',
     'MobileNetworkInfo.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 include('/ipc/chromium/chromium-config.mozbuild')