Bug 1063304 - 3.c/3: accommodate other components. r=echen
authorVicamo Yang <vyang@mozilla.com>
Sun, 21 Sep 2014 15:24:43 +0800
changeset 206406 b4c4679975dc0b6eb1ca603b2e8e43d43db1705c
parent 206405 09012bde18272a0cccca68af18c9d6a8848dd91e
child 206407 203a12787decdf34496dbbc692c5e402ea9176b4
push id27526
push usercbook@mozilla.com
push dateMon, 22 Sep 2014 11:06:35 +0000
treeherdermozilla-central@5e704397529b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersechen
bugs1063304
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 1063304 - 3.c/3: accommodate other components. r=echen
dom/bluetooth/BluetoothRilListener.cpp
dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp
dom/bluetooth/bluez/BluetoothHfpManager.cpp
dom/bluetooth2/BluetoothRilListener.cpp
dom/bluetooth2/bluedroid/hfp/BluetoothHfpManager.cpp
dom/bluetooth2/bluez/BluetoothHfpManager.cpp
dom/mobilemessage/gonk/MmsService.js
dom/phonenumberutils/PhoneNumberUtils.jsm
dom/system/NetworkGeolocationProvider.js
dom/system/gonk/GonkGPSGeolocationProvider.cpp
dom/system/gonk/NetworkManager.js
dom/system/gonk/RadioInterfaceLayer.js
services/mobileid/MobileIdentityManager.jsm
--- a/dom/bluetooth/BluetoothRilListener.cpp
+++ b/dom/bluetooth/BluetoothRilListener.cpp
@@ -2,19 +2,21 @@
 /* vim: set ts=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 "BluetoothRilListener.h"
 
 #include "BluetoothHfpManager.h"
+#include "nsIIccProvider.h"
 #include "nsIMobileConnectionInfo.h"
-#include "nsIRadioInterfaceLayer.h"
-#include "nsRadioInterfaceLayer.h"
+#include "nsIMobileConnectionService.h"
+#include "nsITelephonyService.h"
+#include "nsRadioInterfaceLayer.h" // For NS_RILCONTENTHELPER_CONTRACTID.
 #include "nsServiceManagerUtils.h"
 #include "nsString.h"
 
 USING_BLUETOOTH_NAMESPACE
 
 /**
  *  IccListener
  */
@@ -174,21 +176,25 @@ MobileConnectionListener::NotifyNetworkS
 
 bool
 MobileConnectionListener::Listen(bool aStart)
 {
   nsCOMPtr<nsIMobileConnectionService> service =
     do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
   NS_ENSURE_TRUE(service, false);
 
+  nsCOMPtr<nsIMobileConnection> connection;
+  service->GetItemByServiceId(mClientId, getter_AddRefs(connection));
+  NS_ENSURE_TRUE(connection, false);
+
   nsresult rv;
   if (aStart) {
-    rv = service->RegisterListener(mClientId, this);
+    rv = connection->RegisterListener(this);
   } else {
-    rv = service->UnregisterListener(mClientId, this);
+    rv = connection->UnregisterListener(this);
   }
 
   return NS_SUCCEEDED(rv);
 }
 
 /**
  *  TelephonyListener Implementation
  */
@@ -324,27 +330,27 @@ TelephonyListener::Listen(bool aStart)
   return NS_SUCCEEDED(rv);
 }
 
 /**
  *  BluetoothRilListener
  */
 BluetoothRilListener::BluetoothRilListener()
 {
-  // Query number of total clients (sim slots)
-  uint32_t numOfClients;
-  nsCOMPtr<nsIRadioInterfaceLayer> radioInterfaceLayer =
-    do_GetService(NS_RADIOINTERFACELAYER_CONTRACTID);
-  NS_ENSURE_TRUE_VOID(radioInterfaceLayer);
+  nsCOMPtr<nsIMobileConnectionService> service =
+    do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
+  NS_ENSURE_TRUE_VOID(service);
 
-  radioInterfaceLayer->GetNumRadioInterfaces(&numOfClients);
-
-  // Init MobileConnectionListener array and IccInfoListener
-  for (uint32_t i = 0; i < numOfClients; i++) {
-    mMobileConnListeners.AppendElement(new MobileConnectionListener(i));
+  // Query number of total clients (sim slots)
+  uint32_t numItems = 0;
+  if (NS_SUCCEEDED(service->GetNumItems(&numItems))) {
+    // Init MobileConnectionListener array and IccInfoListener
+    for (uint32_t i = 0; i < numItems; i++) {
+      mMobileConnListeners.AppendElement(new MobileConnectionListener(i));
+    }
   }
 
   mTelephonyListener = new TelephonyListener();
   mIccListener = new IccListener();
   mIccListener->SetOwner(this);
 
   // Probe for available client
   SelectClient();
@@ -370,18 +376,25 @@ BluetoothRilListener::SelectClient()
   // Reset mClientId
   mClientId = mMobileConnListeners.Length();
 
   nsCOMPtr<nsIMobileConnectionService> service =
     do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
   NS_ENSURE_TRUE_VOID(service);
 
   for (uint32_t i = 0; i < mMobileConnListeners.Length(); i++) {
+    nsCOMPtr<nsIMobileConnection> connection;
+    service->GetItemByServiceId(i, getter_AddRefs(connection));
+    if (!connection) {
+      BT_WARNING("%s: Failed to get mobile connection", __FUNCTION__);
+      continue;
+    }
+
     nsCOMPtr<nsIMobileConnectionInfo> voiceInfo;
-    service->GetVoiceConnectionInfo(i, getter_AddRefs(voiceInfo));
+    connection->GetVoice(getter_AddRefs(voiceInfo));
     if (!voiceInfo) {
       BT_WARNING("%s: Failed to get voice connection info", __FUNCTION__);
       continue;
     }
 
     nsString regState;
     voiceInfo->GetState(regState);
     if (regState.EqualsLiteral("registered")) {
--- a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp
@@ -607,22 +607,26 @@ BluetoothHfpManager::HandleVolumeChanged
     sBluetoothHfpInterface->VolumeControl(HFP_VOLUME_TYPE_SPEAKER, mCurrentVgs,
                                           new VolumeControlResultHandler());
   }
 }
 
 void
 BluetoothHfpManager::HandleVoiceConnectionChanged(uint32_t aClientId)
 {
-  nsCOMPtr<nsIMobileConnectionService> connection =
+  nsCOMPtr<nsIMobileConnectionService> mcService =
     do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
+  NS_ENSURE_TRUE_VOID(mcService);
+
+  nsCOMPtr<nsIMobileConnection> connection;
+  mcService->GetItemByServiceId(aClientId, getter_AddRefs(connection));
   NS_ENSURE_TRUE_VOID(connection);
 
   nsCOMPtr<nsIMobileConnectionInfo> voiceInfo;
-  connection->GetVoiceConnectionInfo(aClientId, getter_AddRefs(voiceInfo));
+  connection->GetVoice(getter_AddRefs(voiceInfo));
   NS_ENSURE_TRUE_VOID(voiceInfo);
 
   nsString type;
   voiceInfo->GetType(type);
   mPhoneType = GetPhoneType(type);
 
   // Roam
   bool roaming;
--- a/dom/bluetooth/bluez/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothHfpManager.cpp
@@ -601,22 +601,26 @@ BluetoothHfpManager::HandleVolumeChanged
     SendCommand(RESPONSE_VGS, mCurrentVgs);
   }
 }
 
 #ifdef MOZ_B2G_RIL
 void
 BluetoothHfpManager::HandleVoiceConnectionChanged(uint32_t aClientId)
 {
-  nsCOMPtr<nsIMobileConnectionService> connection =
+  nsCOMPtr<nsIMobileConnectionService> mcService =
     do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
+  NS_ENSURE_TRUE_VOID(mcService);
+
+  nsCOMPtr<nsIMobileConnection> connection;
+  mcService->GetItemByServiceId(aClientId, getter_AddRefs(connection));
   NS_ENSURE_TRUE_VOID(connection);
 
   nsCOMPtr<nsIMobileConnectionInfo> voiceInfo;
-  connection->GetVoiceConnectionInfo(aClientId, getter_AddRefs(voiceInfo));
+  connection->GetVoice(getter_AddRefs(voiceInfo));
   NS_ENSURE_TRUE_VOID(voiceInfo);
 
   nsString type;
   voiceInfo->GetType(type);
   mPhoneType = GetPhoneType(type);
 
   bool roaming;
   voiceInfo->GetRoaming(&roaming);
@@ -641,17 +645,17 @@ BluetoothHfpManager::HandleVoiceConnecti
 
   /**
    * Possible return values for mode are:
    * - null (unknown): set mNetworkSelectionMode to 0 (auto)
    * - automatic: set mNetworkSelectionMode to 0 (auto)
    * - manual: set mNetworkSelectionMode to 1 (manual)
    */
   nsString mode;
-  connection->GetNetworkSelectionMode(aClientId, mode);
+  connection->GetNetworkSelectionMode(mode);
   if (mode.EqualsLiteral("manual")) {
     mNetworkSelectionMode = 1;
   } else {
     mNetworkSelectionMode = 0;
   }
 
   nsCOMPtr<nsIMobileNetworkInfo> network;
   voiceInfo->GetNetwork(getter_AddRefs(network));
--- a/dom/bluetooth2/BluetoothRilListener.cpp
+++ b/dom/bluetooth2/BluetoothRilListener.cpp
@@ -2,19 +2,21 @@
 /* vim: set ts=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 "BluetoothRilListener.h"
 
 #include "BluetoothHfpManager.h"
+#include "nsIIccProvider.h"
 #include "nsIMobileConnectionInfo.h"
-#include "nsIRadioInterfaceLayer.h"
-#include "nsRadioInterfaceLayer.h"
+#include "nsIMobileConnectionService.h"
+#include "nsITelephonyService.h"
+#include "nsRadioInterfaceLayer.h" // For NS_RILCONTENTHELPER_CONTRACTID.
 #include "nsServiceManagerUtils.h"
 #include "nsString.h"
 
 USING_BLUETOOTH_NAMESPACE
 
 /**
  *  IccListener
  */
@@ -174,21 +176,25 @@ MobileConnectionListener::NotifyNetworkS
 
 bool
 MobileConnectionListener::Listen(bool aStart)
 {
   nsCOMPtr<nsIMobileConnectionService> service =
     do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
   NS_ENSURE_TRUE(service, false);
 
+  nsCOMPtr<nsIMobileConnection> connection;
+  mcService->GetItemByServiceId(mClientId, getter_AddRefs(connection));
+  NS_ENSURE_TRUE(connection, false);
+
   nsresult rv;
   if (aStart) {
-    rv = service->RegisterListener(mClientId, this);
+    rv = connection->RegisterListener(this);
   } else {
-    rv = service->UnregisterListener(mClientId, this);
+    rv = connection->UnregisterListener(this);
   }
 
   return NS_SUCCEEDED(rv);
 }
 
 /**
  *  TelephonyListener Implementation
  */
@@ -324,27 +330,27 @@ TelephonyListener::Listen(bool aStart)
   return NS_SUCCEEDED(rv);
 }
 
 /**
  *  BluetoothRilListener
  */
 BluetoothRilListener::BluetoothRilListener()
 {
-  // Query number of total clients (sim slots)
-  uint32_t numOfClients;
-  nsCOMPtr<nsIRadioInterfaceLayer> radioInterfaceLayer =
-    do_GetService(NS_RADIOINTERFACELAYER_CONTRACTID);
-  NS_ENSURE_TRUE_VOID(radioInterfaceLayer);
+  nsCOMPtr<nsIMobileConnectionService> service =
+    do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
+  NS_ENSURE_TRUE_VOID(service);
 
-  radioInterfaceLayer->GetNumRadioInterfaces(&numOfClients);
-
-  // Init MobileConnectionListener array and IccInfoListener
-  for (uint32_t i = 0; i < numOfClients; i++) {
-    mMobileConnListeners.AppendElement(new MobileConnectionListener(i));
+  // Query number of total clients (sim slots)
+  uint32_t numItems = 0;
+  if (NS_SUCCEEDED(service->GetNumItems(&numItems))) {
+    // Init MobileConnectionListener array and IccInfoListener
+    for (uint32_t i = 0; i < numItems; i++) {
+      mMobileConnListeners.AppendElement(new MobileConnectionListener(i));
+    }
   }
 
   mTelephonyListener = new TelephonyListener();
   mIccListener = new IccListener();
   mIccListener->SetOwner(this);
 
   // Probe for available client
   SelectClient();
@@ -370,18 +376,25 @@ BluetoothRilListener::SelectClient()
   // Reset mClientId
   mClientId = mMobileConnListeners.Length();
 
   nsCOMPtr<nsIMobileConnectionService> service =
     do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
   NS_ENSURE_TRUE_VOID(service);
 
   for (uint32_t i = 0; i < mMobileConnListeners.Length(); i++) {
+    nsCOMPtr<nsIMobileConnection> connection;
+    service->GetItemByServiceId(i, getter_AddRefs(connection));
+    if (!connection) {
+      BT_WARNING("%s: Failed to get mobile connection", __FUNCTION__);
+      continue;
+    }
+
     nsCOMPtr<nsIMobileConnectionInfo> voiceInfo;
-    service->GetVoiceConnectionInfo(i, getter_AddRefs(voiceInfo));
+    connection->GetVoice(getter_AddRefs(voiceInfo));
     if (!voiceInfo) {
       BT_WARNING("%s: Failed to get voice connection info", __FUNCTION__);
       continue;
     }
 
     nsString regState;
     voiceInfo->GetState(regState);
     if (regState.EqualsLiteral("registered")) {
--- a/dom/bluetooth2/bluedroid/hfp/BluetoothHfpManager.cpp
+++ b/dom/bluetooth2/bluedroid/hfp/BluetoothHfpManager.cpp
@@ -610,22 +610,26 @@ BluetoothHfpManager::HandleVolumeChanged
     sBluetoothHfpInterface->VolumeControl(HFP_VOLUME_TYPE_SPEAKER, mCurrentVgs,
                                           new VolumeControlResultHandler());
   }
 }
 
 void
 BluetoothHfpManager::HandleVoiceConnectionChanged(uint32_t aClientId)
 {
-  nsCOMPtr<nsIMobileConnectionService> connection =
+  nsCOMPtr<nsIMobileConnectionService> mcService =
     do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
+  NS_ENSURE_TRUE_VOID(mcService);
+
+  nsCOMPtr<nsIMobileConnection> connection;
+  mcService->GetItemByServiceId(aClientId, getter_AddRefs(connection));
   NS_ENSURE_TRUE_VOID(connection);
 
   nsCOMPtr<nsIMobileConnectionInfo> voiceInfo;
-  connection->GetVoiceConnectionInfo(aClientId, getter_AddRefs(voiceInfo));
+  connection->GetVoice(getter_AddRefs(voiceInfo));
   NS_ENSURE_TRUE_VOID(voiceInfo);
 
   nsString type;
   voiceInfo->GetType(type);
   mPhoneType = GetPhoneType(type);
 
   // Roam
   bool roaming;
--- a/dom/bluetooth2/bluez/BluetoothHfpManager.cpp
+++ b/dom/bluetooth2/bluez/BluetoothHfpManager.cpp
@@ -601,22 +601,26 @@ BluetoothHfpManager::HandleVolumeChanged
     SendCommand(RESPONSE_VGS, mCurrentVgs);
   }
 }
 
 #ifdef MOZ_B2G_RIL
 void
 BluetoothHfpManager::HandleVoiceConnectionChanged(uint32_t aClientId)
 {
-  nsCOMPtr<nsIMobileConnectionService> connection =
+  nsCOMPtr<nsIMobileConnectionService> mcService =
     do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
+  NS_ENSURE_TRUE_VOID(mcService);
+
+  nsCOMPtr<nsIMobileConnection> connection;
+  mcService->GetItemByServiceId(aClientId, getter_AddRefs(connection));
   NS_ENSURE_TRUE_VOID(connection);
 
   nsCOMPtr<nsIMobileConnectionInfo> voiceInfo;
-  connection->GetVoiceConnectionInfo(aClientId, getter_AddRefs(voiceInfo));
+  connection->GetVoice(getter_AddRefs(voiceInfo));
   NS_ENSURE_TRUE_VOID(voiceInfo);
 
   nsString type;
   voiceInfo->GetType(type);
   mPhoneType = GetPhoneType(type);
 
   bool roaming;
   voiceInfo->GetRoaming(&roaming);
@@ -641,17 +645,17 @@ BluetoothHfpManager::HandleVoiceConnecti
 
   /**
    * Possible return values for mode are:
    * - null (unknown): set mNetworkSelectionMode to 0 (auto)
    * - automatic: set mNetworkSelectionMode to 0 (auto)
    * - manual: set mNetworkSelectionMode to 1 (manual)
    */
   nsString mode;
-  connection->GetNetworkSelectionMode(aClientId, mode);
+  connection->GetNetworkSelectionMode(mode);
   if (mode.EqualsLiteral("manual")) {
     mNetworkSelectionMode = 1;
   } else {
     mNetworkSelectionMode = 0;
   }
 
   nsCOMPtr<nsIMobileNetworkInfo> network;
   voiceInfo->GetNetwork(getter_AddRefs(network));
--- a/dom/mobilemessage/gonk/MmsService.js
+++ b/dom/mobilemessage/gonk/MmsService.js
@@ -323,18 +323,19 @@ MmsConnection.prototype = {
   },
 
   /**
    * Return the roaming status of voice call.
    *
    * @return true if voice call is roaming.
    */
   isVoiceRoaming: function() {
-    let voice = gMobileConnectionService.getVoiceConnectionInfo(this.serviceId);
-    let isRoaming = voice.roaming;
+    let connection =
+      gMobileConnectionService.getItemByServiceId(this.serviceId);
+    let isRoaming = connection && connection.voice && connection.voice.roaming;
     if (DEBUG) debug("isVoiceRoaming = " + isRoaming);
     return isRoaming;
   },
 
   /**
    * Get phone number from iccInfo.
    *
    * If the icc card is gsm card, the phone number is in msisdn.
--- a/dom/phonenumberutils/PhoneNumberUtils.jsm
+++ b/dom/phonenumberutils/PhoneNumberUtils.jsm
@@ -49,17 +49,18 @@ this.PhoneNumberUtils = {
     // In Multi-sim, there is more than one client in 
     // iccProvider/mobileConnectionProvider. Each client represents a
     // icc/mobileConnection service. To maintain the backward compatibility with
     // single sim, we always use client 0 for now. Adding support for multiple
     // sim will be addressed in bug 926740, if needed.
     let clientId = 0;
 
     // Get network mcc
-    let voice = mobileConnection.getVoiceConnectionInfo(clientId);
+    let connection = mobileConnection.getItemByServiceId(clientId);
+    let voice = connection && connection.voice;
     if (voice && voice.network && voice.network.mcc) {
       mcc = voice.network.mcc;
     }
 
     // Get SIM mcc
     let iccInfo = icc.getIccInfo(clientId);
     if (!mcc && iccInfo && iccInfo.mcc) {
       mcc = iccInfo.mcc;
--- a/dom/system/NetworkGeolocationProvider.js
+++ b/dom/system/NetworkGeolocationProvider.js
@@ -407,24 +407,24 @@ WifiGeoPositionProvider.prototype = {
   getMobileInfo: function() {
     LOG("getMobileInfo called");
     try {
       let radioService = Cc["@mozilla.org/ril;1"]
                     .getService(Ci.nsIRadioInterfaceLayer);
       let service = Cc["@mozilla.org/mobileconnection/mobileconnectionservice;1"]
                     .getService(Ci.nsIMobileConnectionService);
 
-      let numInterfaces = radioService.numRadioInterfaces;
       let result = [];
-      for (let i = 0; i < numInterfaces; i++) {
-        LOG("Looking for SIM in slot:" + i + " of " + numInterfaces);
-        let voice = service.getVoiceConnectionInfo(i);
-        let cell = voice.cell;
-        let type = voice.type;
-        let network = voice.network;
+      for (let i = 0; i < service.length; i++) {
+        LOG("Looking for SIM in slot:" + i + " of " + service.length);
+        let connection = service.getItemByServiceId(i);
+        let voice = connection && connection.voice;
+        let cell = voice && voice.cell;
+        let type = voice && voice.type;
+        let network = voice && voice.network;
 
         if (network && cell && type) {
           if (type === "gsm" || type === "gprs" || type === "edge") {
             type = "gsm";
           } else {
             type = "wcdma";
           }
           result.push({ radio: type,
--- a/dom/system/gonk/GonkGPSGeolocationProvider.cpp
+++ b/dom/system/gonk/GonkGPSGeolocationProvider.cpp
@@ -518,20 +518,24 @@ GonkGPSGeolocationProvider::SetReference
 
     nsCOMPtr<nsIMobileConnectionService> service =
       do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
     if (!service) {
       NS_WARNING("Cannot get MobileConnectionService");
       return;
     }
 
-    nsCOMPtr<nsIMobileConnectionInfo> voice;
+    nsCOMPtr<nsIMobileConnection> connection;
     // TODO: Bug 878748 - B2G GPS: acquire correct RadioInterface instance in
     // MultiSIM configuration
-    service->GetVoiceConnectionInfo(0 /* Client Id */, getter_AddRefs(voice));
+    service->GetItemByServiceId(0 /* Client Id */, getter_AddRefs(connection));
+    NS_ENSURE_TRUE_VOID(connection);
+
+    nsCOMPtr<nsIMobileConnectionInfo> voice;
+    connection->GetVoice(getter_AddRefs(voice));
     if (voice) {
       nsCOMPtr<nsIMobileCellInfo> cell;
       voice->GetCell(getter_AddRefs(cell));
       if (cell) {
         int32_t lac;
         int64_t cid;
 
         cell->GetGsmLocationAreaCode(&lac);
@@ -942,26 +946,38 @@ GonkGPSGeolocationProvider::Observe(nsIS
       int32_t state;
       int32_t type;
       iface->GetState(&state);
       iface->GetType(&type);
       bool connected = (state == nsINetworkInterface::NETWORK_STATE_CONNECTED);
       bool roaming = false;
       int gpsNetworkType = ConvertToGpsNetworkType(type);
       if (gpsNetworkType >= 0) {
-        nsCOMPtr<nsIMobileConnectionService> service =
-          do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
-        if (rilface && service) {
-          nsCOMPtr<nsIMobileConnectionInfo> voice;
-          // TODO: Bug 878748 - B2G GPS: acquire correct RadioInterface instance in
-          // MultiSIM configuration
-          service->GetVoiceConnectionInfo(0 /* Client Id */, getter_AddRefs(voice));
-          if (voice) {
-            voice->GetRoaming(&roaming);
-          }
+        if (rilface) {
+          do {
+            nsCOMPtr<nsIMobileConnectionService> service =
+              do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
+            if (!service) {
+              break;
+            }
+
+            nsCOMPtr<nsIMobileConnection> connection;
+            // TODO: Bug 878748 - B2G GPS: acquire correct RadioInterface instance in
+            // MultiSIM configuration
+            service->GetItemByServiceId(0 /* Client Id */, getter_AddRefs(connection));
+            if (!connection) {
+              break;
+            }
+
+            nsCOMPtr<nsIMobileConnectionInfo> voice;
+            connection->GetVoice(getter_AddRefs(voice));
+            if (voice) {
+              voice->GetRoaming(&roaming);
+            }
+          } while (0);
         }
         mAGpsRilInterface->update_network_state(
           connected,
           gpsNetworkType,
           roaming,
           /* extra_info = */ nullptr);
       }
     }
--- a/dom/system/gonk/NetworkManager.js
+++ b/dom/system/gonk/NetworkManager.js
@@ -854,17 +854,19 @@ NetworkManager.prototype = {
       }
     }
   },
 
   dunRetryTimes: 0,
   dunRetryTimer: Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer),
   setupDunConnection: function() {
     this.dunRetryTimer.cancel();
-    let data = gMobileConnectionService.getDataConnectionInfo(this._dataDefaultServiceId);
+    let connection =
+      gMobileConnectionService.getItemByServiceId(this._dataDefaultServiceId);
+    let data = connection && connection.data;
     if (data && data.state === "registered") {
       this.dunRetryTimes = 0;
       ril.setupDataCallByType("dun");
       this.dunConnectTimer.cancel();
       this.dunConnectTimer.
         initWithCallback(this.onDunConnectTimerTimeout.bind(this),
                          MOBILE_DUN_CONNECT_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT);
       return;
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -579,41 +579,41 @@ XPCOMUtils.defineLazyGetter(this, "gRadi
       numCards = numCards == null ? this._getNumCards() : numCards;
       if (clientId === HW_DEFAULT_CLIENT_ID && numCards === 0) {
         return true;
       }
 
       return false;
     },
 
-    _isValidStateForSetRadioEnabled: function(clientId) {
-      let radioState = gMobileConnectionService.getRadioState(clientId);
+    _isValidStateForSetRadioEnabled: function(radioState) {
       return radioState == RIL.GECKO_RADIOSTATE_ENABLED ||
              radioState == RIL.GECKO_RADIOSTATE_DISABLED;
     },
 
-    _isDummyForSetRadioEnabled: function(clientId, data) {
-      let radioState = gMobileConnectionService.getRadioState(clientId);
+    _isDummyForSetRadioEnabled: function(radioState, data) {
       return (radioState == RIL.GECKO_RADIOSTATE_ENABLED && data.enabled) ||
              (radioState == RIL.GECKO_RADIOSTATE_DISABLED && !data.enabled);
     },
 
     _handleMessage: function(message) {
       if (DEBUG) debug("RadioControl: handleMessage: " + JSON.stringify(message));
       let clientId = message.clientId || 0;
-      let radioInterface = _ril.getRadioInterface(clientId);
-
-      if (!this._isValidStateForSetRadioEnabled(clientId)) {
+      let connection =
+        gMobileConnectionService.getItemByServiceId(clientId);
+      let radioState = connection && connection.radioState;
+
+      if (!this._isValidStateForSetRadioEnabled(radioState)) {
         message.data.errorMsg = "InvalidStateError";
         message.callback(message.data);
         this._processNextMessage();
         return;
       }
 
-      if (this._isDummyForSetRadioEnabled(clientId, message.data)) {
+      if (this._isDummyForSetRadioEnabled(radioState, message.data)) {
         message.callback(message.data);
         this._processNextMessage();
         return;
       }
 
       if (message.data.enabled) {
         if (this._isRadioAbleToEnableAtClient(clientId)) {
           this._setRadioEnabledInternal(message);
@@ -1397,19 +1397,22 @@ DataConnectionHandler.prototype = {
     let networkInterface = this.dataNetworkInterfaces.get("default");
     if (!networkInterface) {
       if (DEBUG) {
         this.debug("No network interface for default data.");
       }
       return;
     }
 
+    let connection =
+      gMobileConnectionService.getItemByServiceId(this.clientId);
+
     // This check avoids data call connection if the radio is not ready
     // yet after toggling off airplane mode.
-    let radioState = gMobileConnectionService.getRadioState(this.clientId);
+    let radioState = connection && connection.radioState;
     if (radioState != RIL.GECKO_RADIOSTATE_ENABLED) {
       if (DEBUG) {
         this.debug("RIL is not ready for data connection: radio's not ready");
       }
       return;
     }
 
     // We only watch at "ril.data.enabled" flag changes for connecting or
@@ -1419,20 +1422,22 @@ DataConnectionHandler.prototype = {
     // the new values and reconnect the data call.
     if (this.dataCallSettings.oldEnabled === this.dataCallSettings.enabled) {
       if (DEBUG) {
         this.debug("No changes for ril.data.enabled flag. Nothing to do.");
       }
       return;
     }
 
-    let dataInfo = gMobileConnectionService.getDataConnectionInfo(this.clientId);
+    let dataInfo = connection && connection.data;
     let isRegistered =
+      dataInfo &&
       dataInfo.state == RIL.GECKO_MOBILE_CONNECTION_STATE_REGISTERED;
     let haveDataConnection =
+      dataInfo &&
       dataInfo.type != RIL.GECKO_MOBILE_CONNECTION_STATE_UNKNOWN;
     if (!isRegistered || !haveDataConnection) {
       if (DEBUG) {
         this.debug("RIL is not ready for data connection: Phone's not " +
                    "registered or doesn't have data connection.");
       }
       return;
     }
@@ -1482,19 +1487,17 @@ DataConnectionHandler.prototype = {
       }
       return;
     }
     if (this._pendingApnSettings) {
       if (DEBUG) this.debug("We're changing apn settings, ignore any changes.");
       return;
     }
 
-    if (gRadioEnabledController.isDeactivatingDataCalls() ||
-        radioState == RIL.GECKO_RADIOSTATE_ENABLING ||
-        radioState == RIL.GECKO_RADIOSTATE_DISABLING) {
+    if (gRadioEnabledController.isDeactivatingDataCalls()) {
       // We're changing the radio power currently, ignore any changes.
       return;
     }
 
     if (DEBUG) {
       this.debug("Data call settings: connect data call.");
     }
     networkInterface.connect();
@@ -3697,25 +3700,28 @@ RadioInterface.prototype = {
         Services.obs.notifyObservers(domMessage, kSmsFailedObserverTopic, null);
         return;
       }
 
       if (!silent) {
         Services.obs.notifyObservers(domMessage, kSmsSendingObserverTopic, null);
       }
 
+      let connection =
+        gMobileConnectionService.getItemByServiceId(this.clientId);
       // If the radio is disabled or the SIM card is not ready, just directly
       // return with the corresponding error code.
       let errorCode;
-      let radioState = gMobileConnectionService.getRadioState(this.clientId);
+      let radioState = connection && connection.radioState;
       if (!PhoneNumberUtils.isPlainPhoneNumber(options.number)) {
         if (DEBUG) this.debug("Error! Address is invalid when sending SMS: " +
                               options.number);
         errorCode = Ci.nsIMobileMessageCallback.INVALID_ADDRESS_ERROR;
-      } else if (radioState == RIL.GECKO_RADIOSTATE_DISABLED) {
+      } else if (radioState == null ||
+                 radioState == RIL.GECKO_RADIOSTATE_DISABLED) {
         if (DEBUG) this.debug("Error! Radio is disabled when sending SMS.");
         errorCode = Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR;
       } else if (this.rilContext.cardState != "ready") {
         if (DEBUG) this.debug("Error! SIM card is not ready when sending SMS.");
         errorCode = Ci.nsIMobileMessageCallback.NO_SIM_CARD_ERROR;
       }
       if (errorCode) {
         if (silent) {
@@ -4209,19 +4215,21 @@ DataCall.prototype = {
   },
 
   setup: function() {
     if (DEBUG) {
       this.debug("Going to set up data connection with APN " +
                  this.apnProfile.apn);
     }
 
-    let radioInterface = this.gRIL.getRadioInterface(this.clientId);
-    let dataInfo = gMobileConnectionService.getDataConnectionInfo(this.clientId);
-    if (dataInfo.state != RIL.GECKO_MOBILE_CONNECTION_STATE_REGISTERED ||
+    let connection =
+      gMobileConnectionService.getItemByServiceId(this.clientId);
+    let dataInfo = connection && connection.data;
+    if (dataInfo == null ||
+        dataInfo.state != RIL.GECKO_MOBILE_CONNECTION_STATE_REGISTERED ||
         dataInfo.type == RIL.GECKO_MOBILE_CONNECTION_STATE_UNKNOWN) {
       return;
     }
 
     let radioTechType = dataInfo.type;
     let radioTechnology = RIL.GECKO_RADIO_TECH.indexOf(radioTechType);
     let authType = RIL.RIL_DATACALL_AUTH_TO_GECKO.indexOf(this.apnProfile.authtype);
     // Use the default authType if the value in database is invalid.
@@ -4240,16 +4248,18 @@ DataCall.prototype = {
       if (RIL.RIL_DATACALL_PDP_TYPES.indexOf(pdpType) < 0) {
         if (DEBUG) {
           this.debug("Invalid pdpType '" + pdpType + "', using '" +
                      RIL.GECKO_DATACALL_PDP_TYPE_DEFAULT + "'");
         }
         pdpType = RIL.GECKO_DATACALL_PDP_TYPE_DEFAULT;
       }
     }
+
+    let radioInterface = this.gRIL.getRadioInterface(this.clientId);
     radioInterface.sendWorkerMessage("setupDataCall", {
       radioTech: radioTechnology,
       apn: this.apnProfile.apn,
       user: this.apnProfile.user,
       passwd: this.apnProfile.password,
       chappap: authType,
       pdptype: pdpType
     });
--- a/services/mobileid/MobileIdentityManager.jsm
+++ b/services/mobileid/MobileIdentityManager.jsm
@@ -122,38 +122,41 @@ this.MobileIdentityManager = {
         continue;
       }
       let info = rilContext.iccInfo;
       if (!info) {
         log.warn("No ICC info");
         continue;
       }
 
-      let voice = mobileConnectionService.getVoiceConnectionInfo(i);
-      let data = mobileConnectionService.getDataConnectionInfo(i);
+      let connection = mobileConnectionService.getItemByServiceId(i);
+      let voice = connection && connection.voice;
+      let data = connection && connection.data;
       let operator = null;
-      if (voice.network &&
+      if (voice &&
+          voice.network &&
           voice.network.shortName &&
           voice.network.shortName.length) {
         operator = voice.network.shortName;
-      } else if (data.network &&
+      } else if (data &&
+                 data.network &&
                  data.network.shortName &&
                  data.network.shortName.length) {
         operator = data.network.shortName;
       }
 
       this._iccInfo.push({
         iccId: info.iccid,
         mcc: info.mcc,
         mnc: info.mnc,
         // GSM SIMs may have MSISDN while CDMA SIMs may have MDN
         msisdn: info.msisdn || info.mdn || null,
         operator: operator,
         serviceId: i,
-        roaming: voice.roaming
+        roaming: voice && voice.roaming
       });
     }
 
     return this._iccInfo;
 #endif
     return null;
   },