Bug 921991 - B2G BT: support multiple sim cards, r=echou
☠☠ backed out by 80fbd6ffab29 ☠ ☠
authorBen Tian <btian@mozilla.com>
Fri, 08 Nov 2013 14:41:12 +0800
changeset 154332 69acb8830b8c68ffb449840b2981c9c86139f077
parent 154331 6001a13330d839b8c113e5ed30f9a7c09b51ad1a
child 154333 fb02b4f4fa659b293757f46cb2f26c63d63a00b3
push id25636
push usercbook@mozilla.com
push dateMon, 11 Nov 2013 11:03:48 +0000
treeherdermozilla-central@cdfd2bcbae95 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersechou
bugs921991
milestone28.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 921991 - B2G BT: support multiple sim cards, r=echou
dom/bluetooth/BluetoothHfpManager.cpp
dom/bluetooth/BluetoothHfpManager.h
dom/bluetooth/BluetoothRilListener.cpp
dom/bluetooth/BluetoothRilListener.h
dom/system/gonk/nsRadioInterfaceLayer.h
--- a/dom/bluetooth/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/BluetoothHfpManager.cpp
@@ -410,17 +410,17 @@ BluetoothHfpManager::Init()
     BT_WARNING("Failed to add observers!");
     return false;
   }
 
   hal::RegisterBatteryObserver(this);
 
 #ifdef MOZ_B2G_RIL
   mListener = new BluetoothRilListener();
-  if (!mListener->StartListening()) {
+  if (!mListener->Listen(true)) {
     BT_WARNING("Failed to start listening RIL");
     return false;
   }
 #endif
 
   nsCOMPtr<nsISettingsService> settings =
     do_GetService("@mozilla.org/settingsService;1");
   NS_ENSURE_TRUE(settings, false);
@@ -442,17 +442,17 @@ BluetoothHfpManager::Init()
   mScoSocketStatus = mScoSocket->GetConnectionStatus();
   ListenSco();
   return true;
 }
 
 BluetoothHfpManager::~BluetoothHfpManager()
 {
 #ifdef MOZ_B2G_RIL
-  if (!mListener->StopListening()) {
+  if (!mListener->Listen(false)) {
     BT_WARNING("Failed to stop listening RIL");
   }
   mListener = nullptr;
 #endif
 
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   NS_ENSURE_TRUE_VOID(obs);
 
@@ -581,40 +581,40 @@ BluetoothHfpManager::HandleVolumeChanged
   // Only send volume back when there's a connected headset
   if (IsConnected()) {
     SendCommand("+VGS: ", mCurrentVgs);
   }
 }
 
 #ifdef MOZ_B2G_RIL
 void
-BluetoothHfpManager::HandleVoiceConnectionChanged()
+BluetoothHfpManager::HandleVoiceConnectionChanged(uint32_t aClientId)
 {
   nsCOMPtr<nsIMobileConnectionProvider> connection =
     do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
   NS_ENSURE_TRUE_VOID(connection);
 
   nsCOMPtr<nsIDOMMozMobileConnectionInfo> voiceInfo;
-  // TODO: Bug 921991 - B2G BT: support multiple sim cards
-  connection->GetVoiceConnectionInfo(0, getter_AddRefs(voiceInfo));
+  connection->GetVoiceConnectionInfo(aClientId, getter_AddRefs(voiceInfo));
   NS_ENSURE_TRUE_VOID(voiceInfo);
 
   nsString type;
   voiceInfo->GetType(type);
   mPhoneType = GetPhoneType(type);
 
   bool roaming;
   voiceInfo->GetRoaming(&roaming);
   UpdateCIND(CINDType::ROAM, roaming);
 
-  bool service = false;
   nsString regState;
   voiceInfo->GetState(regState);
-  if (regState.EqualsLiteral("registered")) {
-    service = true;
+  bool service = regState.EqualsLiteral("registered");
+  if (service != sCINDItems[CINDType::SERVICE].value) {
+    // Notify BluetoothRilListener of service change
+    mListener->ServiceChanged(aClientId, service);
   }
   UpdateCIND(CINDType::SERVICE, service);
 
   uint8_t signal;
   JS::Value value;
   voiceInfo->GetRelSignalStrength(&value);
   if (!value.isNumber()) {
     BT_WARNING("Failed to get relSignalStrength in BluetoothHfpManager");
@@ -625,18 +625,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;
-  // TODO: Bug 921991 - B2G BT: support multiple sim cards
-  connection->GetNetworkSelectionMode(0, mode);
+  connection->GetNetworkSelectionMode(aClientId, mode);
   if (mode.EqualsLiteral("manual")) {
     mNetworkSelectionMode = 1;
   } else {
     mNetworkSelectionMode = 0;
   }
 
   nsCOMPtr<nsIDOMMozMobileNetworkInfo> network;
   voiceInfo->GetNetwork(getter_AddRefs(network));
@@ -653,25 +652,24 @@ BluetoothHfpManager::HandleVoiceConnecti
   // Please see Bug 871366 for more information.
   if (mOperatorName.Length() > 16) {
     BT_WARNING("The operator name was longer than 16 characters. We cut it.");
     mOperatorName.Left(mOperatorName, 16);
   }
 }
 
 void
-BluetoothHfpManager::HandleIccInfoChanged()
+BluetoothHfpManager::HandleIccInfoChanged(uint32_t aClientId)
 {
   nsCOMPtr<nsIIccProvider> icc =
     do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
   NS_ENSURE_TRUE_VOID(icc);
 
   nsCOMPtr<nsIDOMMozIccInfo> iccInfo;
-  // TODO: Bug 921991 - B2G BT: support multiple sim cards
-  icc->GetIccInfo(0, getter_AddRefs(iccInfo));
+  icc->GetIccInfo(aClientId, getter_AddRefs(iccInfo));
   NS_ENSURE_TRUE_VOID(iccInfo);
 
   nsCOMPtr<nsIDOMMozGsmIccInfo> gsmIccInfo = do_QueryInterface(iccInfo);
   NS_ENSURE_TRUE_VOID(gsmIccInfo);
   gsmIccInfo->GetMsisdn(mMsisdn);
 }
 #endif // MOZ_B2G_RIL
 
--- a/dom/bluetooth/BluetoothHfpManager.h
+++ b/dom/bluetooth/BluetoothHfpManager.h
@@ -116,18 +116,18 @@ public:
 
 #ifdef MOZ_B2G_RIL
   /**
    * @param aSend A boolean indicates whether we need to notify headset or not
    */
   void HandleCallStateChanged(uint32_t aCallIndex, uint16_t aCallState,
                               const nsAString& aError, const nsAString& aNumber,
                               const bool aIsOutgoing, bool aSend);
-  void HandleIccInfoChanged();
-  void HandleVoiceConnectionChanged();
+  void HandleIccInfoChanged(uint32_t aClientId);
+  void HandleVoiceConnectionChanged(uint32_t aClientId);
 #endif
 
   bool IsConnected();
   bool IsScoConnected();
 
 #ifdef MOZ_B2G_RIL
   // CDMA-specific functions
   void UpdateSecondNumber(const nsAString& aNumber);
--- a/dom/bluetooth/BluetoothRilListener.cpp
+++ b/dom/bluetooth/BluetoothRilListener.cpp
@@ -2,46 +2,34 @@
 /* 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 "nsIMobileConnectionProvider.h"
-#include "nsITelephonyProvider.h"
+#include "nsIDOMMobileConnection.h"
+#include "nsIRadioInterfaceLayer.h"
 #include "nsRadioInterfaceLayer.h"
 #include "nsServiceManagerUtils.h"
 #include "nsString.h"
 
 USING_BLUETOOTH_NAMESPACE
 
-namespace {
-
 /**
  *  IccListener
  */
-class IccListener : public nsIIccListener
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIICCLISTENER
-
-  IccListener() { }
-};
-
 NS_IMPL_ISUPPORTS1(IccListener, nsIIccListener)
 
 NS_IMETHODIMP
 IccListener::NotifyIccInfoChanged()
 {
   BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
-  hfp->HandleIccInfoChanged();
+  hfp->HandleIccInfoChanged(mOwner->mClientId);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 IccListener::NotifyStkCommand(const nsAString & aMessage)
 {
   return NS_OK;
@@ -54,35 +42,49 @@ IccListener::NotifyStkSessionEnd()
 }
 
 NS_IMETHODIMP
 IccListener::NotifyCardStateChanged()
 {
   return NS_OK;
 }
 
+bool
+IccListener::Listen(bool aStart)
+{
+  nsCOMPtr<nsIIccProvider> provider =
+    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
+  NS_ENSURE_TRUE(provider, false);
+
+  nsresult rv;
+  if (aStart) {
+    rv = provider->RegisterIccMsg(mOwner->mClientId, this);
+  } else {
+    rv = provider->UnregisterIccMsg(mOwner->mClientId, this);
+  }
+
+  return NS_SUCCEEDED(rv);
+}
+
+void
+IccListener::SetOwner(BluetoothRilListener *aOwner)
+{
+  mOwner = aOwner;
+}
+
 /**
  *  MobileConnectionListener
  */
-class MobileConnectionListener : public nsIMobileConnectionListener
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIMOBILECONNECTIONLISTENER
-
-  MobileConnectionListener() { }
-};
-
 NS_IMPL_ISUPPORTS1(MobileConnectionListener, nsIMobileConnectionListener)
 
 NS_IMETHODIMP
 MobileConnectionListener::NotifyVoiceChanged()
 {
   BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
-  hfp->HandleVoiceConnectionChanged();
+  hfp->HandleVoiceConnectionChanged(mClientId);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MobileConnectionListener::NotifyDataChanged()
 {
   return NS_OK;
@@ -126,30 +128,36 @@ MobileConnectionListener::NotifyOtaStatu
 }
 
 NS_IMETHODIMP
 MobileConnectionListener::NotifyIccChanged()
 {
   return NS_OK;
 }
 
+bool
+MobileConnectionListener::Listen(bool aStart)
+{
+  nsCOMPtr<nsIMobileConnectionProvider> provider =
+    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
+  NS_ENSURE_TRUE(provider, false);
+
+  nsresult rv;
+  if (aStart) {
+    rv = provider->RegisterMobileConnectionMsg(mClientId, this);
+  } else {
+    rv = provider->UnregisterMobileConnectionMsg(mClientId, this);
+  }
+
+  return NS_SUCCEEDED(rv);
+}
+
 /**
  *  TelephonyListener Implementation
- *
- *  TODO: Bug 921991 - B2G BT: support multiple sim cards
  */
-class TelephonyListener : public nsITelephonyListener
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSITELEPHONYLISTENER
-
-  TelephonyListener() { }
-};
-
 NS_IMPL_ISUPPORTS1(TelephonyListener, nsITelephonyListener)
 
 NS_IMETHODIMP
 TelephonyListener::CallStateChanged(uint32_t aServiceId,
                                     uint32_t aCallIndex,
                                     uint16_t aCallState,
                                     const nsAString& aNumber,
                                     bool aIsActive,
@@ -238,122 +246,149 @@ TelephonyListener::NotifyCdmaCallWaiting
                                          const nsAString& aNumber)
 {
   BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
   hfp->UpdateSecondNumber(aNumber);
 
   return NS_OK;
 }
 
-} // anonymous namespace
+bool
+TelephonyListener::Listen(bool aStart)
+{
+  nsCOMPtr<nsITelephonyProvider> provider =
+    do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
+  NS_ENSURE_TRUE(provider, false);
+
+  nsresult rv;
+  if (aStart) {
+    rv = provider->RegisterListener(this);
+  } else {
+    rv = provider->UnregisterListener(this);
+  }
+
+  return NS_SUCCEEDED(rv);
+}
 
 /**
  *  BluetoothRilListener
  */
 BluetoothRilListener::BluetoothRilListener()
 {
-  mIccListener = new IccListener();
-  mMobileConnectionListener = new MobileConnectionListener();
-  mTelephonyListener = new TelephonyListener();
+  // Query number of total clients (sim slots)
+  uint32_t numOfClients;
+  nsCOMPtr<nsIRadioInterfaceLayer> radioInterfaceLayer =
+    do_GetService(NS_RADIOINTERFACELAYER_CONTRACTID);
+  NS_ENSURE_TRUE_VOID(radioInterfaceLayer);
+
+  radioInterfaceLayer->GetNumRadioInterfaces(&numOfClients);
+
+  // Init MobileConnectionListener array and IccInfoListener
+  for (uint32_t i = 0; i < numOfClients; i++) {
+    MobileConnectionListener listener(i);
+    mMobileConnListeners.AppendElement(listener);
+  }
+  mIccListener.SetOwner(this);
+
+  // Probe for available client
+  SelectClient();
 }
 
 bool
-BluetoothRilListener::StartListening()
+BluetoothRilListener::Listen(bool aStart)
 {
-  NS_ENSURE_TRUE(StartIccListening(), false);
-  NS_ENSURE_TRUE(StartMobileConnectionListening(), false);
-  NS_ENSURE_TRUE(StartTelephonyListening(), false);
+  NS_ENSURE_TRUE(ListenMobileConnAndIccInfo(aStart), false);
+  NS_ENSURE_TRUE(mTelephonyListener.Listen(aStart), false);
 
   return true;
 }
 
-bool
-BluetoothRilListener::StopListening()
+void
+BluetoothRilListener::SelectClient()
 {
-  NS_ENSURE_TRUE(StopIccListening(), false);
-  NS_ENSURE_TRUE(StopMobileConnectionListening(), false);
-  NS_ENSURE_TRUE(StopTelephonyListening(), false);
+  // Reset mClientId
+  mClientId = mMobileConnListeners.Length();
+
+  nsCOMPtr<nsIMobileConnectionProvider> connection =
+    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
+  NS_ENSURE_TRUE_VOID(connection);
+
+  uint32_t i;
+  for (i = 0; i < mMobileConnListeners.Length(); i++) {
+    nsCOMPtr<nsIDOMMozMobileConnectionInfo> voiceInfo;
+    connection->GetVoiceConnectionInfo(i, getter_AddRefs(voiceInfo));
+    if (!voiceInfo) {
+      BT_WARNING("%s: Failed to get voice connection info", __FUNCTION__);
+      continue;
+    }
 
-  return true;
+    nsString regState;
+    voiceInfo->GetState(regState);
+    if (regState.EqualsLiteral("registered")) {
+      // Found available client
+      mClientId = i;
+      return;
+    }
+  }
+}
+
+void
+BluetoothRilListener::ServiceChanged(uint32_t aClientId, bool aRegistered)
+{
+  // Stop listening
+  ListenMobileConnAndIccInfo(false);
+
+  /**
+   * aRegistered:
+   * - TRUE:  service becomes registered. We were listening to all clients
+   *          and one of them becomes available. Select it to listen.
+   * - FALSE: service becomes un-registered. The client we were listening
+   *          becomes unavailable. Select another registered one to listen.
+   */
+  if (aRegistered) {
+    mClientId = aClientId;
+  } else {
+    SelectClient();
+  }
+
+  // Restart listening
+  ListenMobileConnAndIccInfo(true);
+
+  BT_LOGR("%s: %d client %d. new mClientId %d", __FUNCTION__, aRegistered, aClientId,
+    (mClientId < mMobileConnListeners.Length()) ? mClientId : -1);
 }
 
 void
 BluetoothRilListener::EnumerateCalls()
 {
   nsCOMPtr<nsITelephonyProvider> provider =
     do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
   NS_ENSURE_TRUE_VOID(provider);
 
-  provider->EnumerateCalls(mTelephonyListener);
-}
-
-// private
-bool
-BluetoothRilListener::StartIccListening()
-{
-  nsCOMPtr<nsIIccProvider> provider =
-    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
-  NS_ENSURE_TRUE(provider, false);
+  nsCOMPtr<nsITelephonyListener> listener(
+    do_QueryInterface(&mTelephonyListener));
 
-  // TODO: Bug 921991 - B2G BT: support multiple sim cards
-  nsresult rv = provider->RegisterIccMsg(0, mIccListener);
-  return NS_SUCCEEDED(rv);
-}
-
-bool
-BluetoothRilListener::StopIccListening()
-{
-  nsCOMPtr<nsIIccProvider> provider =
-    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
-  NS_ENSURE_TRUE(provider, false);
-
-  // TODO: Bug 921991 - B2G BT: support multiple sim cards
-  nsresult rv = provider->UnregisterIccMsg(0, mIccListener);
-  return NS_SUCCEEDED(rv);
+  provider->EnumerateCalls(listener);
 }
 
 bool
-BluetoothRilListener::StartMobileConnectionListening()
+BluetoothRilListener::ListenMobileConnAndIccInfo(bool aStart)
 {
-  nsCOMPtr<nsIMobileConnectionProvider> provider =
-    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
-  NS_ENSURE_TRUE(provider, false);
-
-  // TODO: Bug 921991 - B2G BT: support multiple sim cards
-  nsresult rv = provider->
-                  RegisterMobileConnectionMsg(0, mMobileConnectionListener);
-  return NS_SUCCEEDED(rv);
-}
-
-bool
-BluetoothRilListener::StopMobileConnectionListening()
-{
-  nsCOMPtr<nsIMobileConnectionProvider> provider =
-    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
-  NS_ENSURE_TRUE(provider, false);
+  /**
+   * mClientId < number of total clients:
+   *   The client with mClientId is available. Start/Stop listening
+   *   mobile connection and icc info of this client only.
+   *
+   * mClientId >= number of total clients:
+   *   All clients are unavailable. Start/Stop listening mobile
+   *   connections of all clients.
+   */
+  if (mClientId < mMobileConnListeners.Length()) {
+    NS_ENSURE_TRUE(mMobileConnListeners[mClientId].Listen(aStart), false);
+    NS_ENSURE_TRUE(mIccListener.Listen(aStart), false);
+  } else {
+    for (uint32_t i = 0; i < mMobileConnListeners.Length(); i++) {
+      NS_ENSURE_TRUE(mMobileConnListeners[i].Listen(aStart), false);
+    }
+  }
 
-  // TODO: Bug 921991 - B2G BT: support multiple sim cards
-  nsresult rv = provider->
-                  UnregisterMobileConnectionMsg(0, mMobileConnectionListener);
-  return NS_SUCCEEDED(rv);
+  return true;
 }
-
-bool
-BluetoothRilListener::StartTelephonyListening()
-{
-  nsCOMPtr<nsITelephonyProvider> provider =
-    do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
-  NS_ENSURE_TRUE(provider, false);
-
-  nsresult rv = provider->RegisterListener(mTelephonyListener);
-  return NS_SUCCEEDED(rv);
-}
-
-bool
-BluetoothRilListener::StopTelephonyListening()
-{
-  nsCOMPtr<nsITelephonyProvider> provider =
-    do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
-  NS_ENSURE_TRUE(provider, false);
-
-  nsresult rv = provider->UnregisterListener(mTelephonyListener);
-  return NS_SUCCEEDED(rv);
-}
--- a/dom/bluetooth/BluetoothRilListener.h
+++ b/dom/bluetooth/BluetoothRilListener.h
@@ -4,44 +4,121 @@
  * 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_bluetooth_bluetoothrillistener_h__
 #define mozilla_dom_bluetooth_bluetoothrillistener_h__
 
 #include "BluetoothCommon.h"
 
-#include "nsCOMPtr.h"
-
-class nsIIccListener;
-class nsIMobileConnectionListener;
-class nsITelephonyListener;
+#include "nsIIccProvider.h"
+#include "nsIMobileConnectionProvider.h"
+#include "nsITelephonyProvider.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
+class BluetoothRilListener;
+
+class IccListener : public nsIIccListener
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIICCLISTENER
+
+  IccListener() { }
+
+  bool Listen(bool aStart);
+  void SetOwner(BluetoothRilListener *aOwner);
+
+private:
+  BluetoothRilListener* mOwner;
+};
+
+class MobileConnectionListener : public nsIMobileConnectionListener
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIMOBILECONNECTIONLISTENER
+
+  MobileConnectionListener(uint32_t aClientId)
+  : mClientId(aClientId) { }
+
+  bool Listen(bool aStart);
+
+private:
+  uint32_t mClientId;
+};
+
+class TelephonyListener : public nsITelephonyListener
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSITELEPHONYLISTENER
+
+  TelephonyListener() { }
+
+  bool Listen(bool aStart);
+};
+
 class BluetoothRilListener
 {
 public:
   BluetoothRilListener();
 
-  bool StartListening();
-  bool StopListening();
+  /**
+   * Start/Stop listening.
+   *
+   * @param aStart [in] whether to start/stop listening
+   */
+  bool Listen(bool aStart);
 
+  /**
+   * Be informed that certain client's service has changed.
+   *
+   * @param aClientId   [in] the client id with service change
+   * @param aRegistered [in] whether changed service is registered
+   */
+  void ServiceChanged(uint32_t aClientId, bool aRegistered);
+
+  /**
+   * Enumerate current calls.
+   */
   void EnumerateCalls();
 
+  /**
+   * The id of client that mobile connection and icc info listeners
+   * are listening to.
+   *
+   * mClientId equals to number of total clients (array length of
+   * mobile connection listeners) if there is no available client to listen.
+   */
+  uint32_t mClientId;
+
 private:
-  bool StartIccListening();
-  bool StopIccListening();
-
-  bool StartMobileConnectionListening();
-  bool StopMobileConnectionListening();
+  /**
+   * Start/Stop listening of mobile connection and icc info.
+   *
+   * @param aStart [in] whether to start/stop listening
+   */
+  bool ListenMobileConnAndIccInfo(bool aStart);
 
-  bool StartTelephonyListening();
-  bool StopTelephonyListening();
+  /**
+   * Select available client to listen and assign mClientId.
+   *
+   * mClientId is assigned to number of total clients (array length of
+   * mobile connection listeners) if there is no available client to listen.
+   */
+  void SelectClient();
 
-  nsCOMPtr<nsIIccListener> mIccListener;
-  nsCOMPtr<nsIMobileConnectionListener> mMobileConnectionListener;
-  nsCOMPtr<nsITelephonyListener> mTelephonyListener;
+  /**
+   * Array of mobile connection listeners.
+   *
+   * The length equals to number of total clients.
+   */
+  nsTArray<MobileConnectionListener> mMobileConnListeners;
+
+  IccListener mIccListener;
+  TelephonyListener mTelephonyListener;
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif
--- a/dom/system/gonk/nsRadioInterfaceLayer.h
+++ b/dom/system/gonk/nsRadioInterfaceLayer.h
@@ -6,9 +6,11 @@
 
 #define NS_RADIOINTERFACELAYER_CID \
     { 0x2d831c8d, 0x6017, 0x435b, \
       { 0xa8, 0x0c, 0xe5, 0xd4, 0x22, 0x81, 0x0c, 0xea } }
 
 #define NS_RILCONTENTHELPER_CID \
     { 0x472816e1, 0x1fd6, 0x4405, \
       { 0x99, 0x6c, 0x80, 0x6f, 0x9e, 0xa6, 0x81, 0x74 } }
+
+#define NS_RADIOINTERFACELAYER_CONTRACTID "@mozilla.org/ril;1"
 #define NS_RILCONTENTHELPER_CONTRACTID "@mozilla.org/ril/content-helper;1"