Bug 821636 - No subscriber number information in Bluetooth Handsfree. r=echou, a=blocking-basecamp
authorGina Yeh <gyeh@mozilla.com>
Mon, 17 Dec 2012 17:44:32 +0800
changeset 118920 c2281eb93c354e58bee35e535ae9eb9051162449
parent 118919 bde2bb5f6cb2a0a332019dba699389a0285e8035
child 118921 796e971014dcdda37a0121b0bf687a55974d33fe
push id2984
push userryanvm@gmail.com
push dateTue, 18 Dec 2012 03:08:28 +0000
treeherdermozilla-aurora@68ae24dc739c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersechou, blocking-basecamp
bugs821636
milestone19.0a2
Bug 821636 - No subscriber number information in Bluetooth Handsfree. r=echou, a=blocking-basecamp
dom/bluetooth/BluetoothHfpManager.cpp
dom/bluetooth/BluetoothHfpManager.h
--- a/dom/bluetooth/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/BluetoothHfpManager.cpp
@@ -9,29 +9,35 @@
 #include "BluetoothHfpManager.h"
 
 #include "BluetoothReplyRunnable.h"
 #include "BluetoothScoManager.h"
 #include "BluetoothService.h"
 #include "BluetoothUtils.h"
 #include "BluetoothUuid.h"
 
+#include "MobileConnection.h"
 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
 #include "nsContentUtils.h"
 #include "nsIAudioManager.h"
 #include "nsIObserverService.h"
 #include "nsISettingsService.h"
 #include "nsIRadioInterfaceLayer.h"
 
 #include <unistd.h> /* usleep() */
 
+#define AUDIO_VOLUME_BT_SCO "audio.volume.bt_sco"
 #define MOZSETTINGS_CHANGED_ID "mozsettings-changed"
-#define AUDIO_VOLUME_BT_SCO "audio.volume.bt_sco"
+#define MOBILE_CONNECTION_ICCINFO_CHANGED "mobile-connection-iccinfo-changed"
+#define NS_RILCONTENTHELPER_CONTRACTID "@mozilla.org/ril/content-helper;1"
+
+#define TOA_UNKNOWN 0x81
+#define TOA_INTERNATIONAL 0x91
 
 using namespace mozilla;
 using namespace mozilla::ipc;
 USING_BLUETOOTH_NAMESPACE
 
 /* CallState for sCINDItems[CINDType::CALL].value
  * - NO_CALL: there are no calls in progress
  * - IN_PROGRESS: at least one call is in progress
@@ -111,25 +117,31 @@ public:
       return false;
     }
 
     if (NS_FAILED(obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false))) {
       NS_WARNING("Failed to add shutdown observer!");
       return false;
     }
 
+    if (NS_FAILED(obs->AddObserver(this, MOBILE_CONNECTION_ICCINFO_CHANGED, false))) {
+      NS_WARNING("Failed to add mobile connection iccinfo change observer!");
+      return false;
+    }
+
     return true;
   }
 
   bool Shutdown()
   {
     nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
     if (!obs ||
-        (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) ||
-         NS_FAILED(obs->RemoveObserver(this, MOZSETTINGS_CHANGED_ID)))) {
+        NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) ||
+        NS_FAILED(obs->RemoveObserver(this, MOZSETTINGS_CHANGED_ID)) ||
+        NS_FAILED(obs->RemoveObserver(this, MOBILE_CONNECTION_ICCINFO_CHANGED))) {
       NS_WARNING("Can't unregister observers, or already unregistered!");
       return false;
     }
     return true;
   }
 
   ~BluetoothHfpManagerObserver()
   {
@@ -188,16 +200,18 @@ BluetoothHfpManagerObserver::Observe(nsI
                                      const PRUnichar* aData)
 {
   MOZ_ASSERT(gBluetoothHfpManager);
 
   if (!strcmp(aTopic, MOZSETTINGS_CHANGED_ID)) {
     return gBluetoothHfpManager->HandleVolumeChanged(nsDependentString(aData));
   } else if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
     return gBluetoothHfpManager->HandleShutdown();
+  } else if (!strcmp(aTopic, MOBILE_CONNECTION_ICCINFO_CHANGED)) {
+    return gBluetoothHfpManager->HandleIccInfoChanged();
   }
 
   MOZ_ASSERT(false, "BluetoothHfpManager got unexpected topic!");
   return NS_ERROR_UNEXPECTED;
 }
 
 class SendRingIndicatorTask : public Task
 {
@@ -461,16 +475,37 @@ BluetoothHfpManager::HandleVolumeChanged
   if (GetConnectionStatus() == SocketConnectionStatus::SOCKET_CONNECTED) {
     SendCommand("+VGS: ", mCurrentVgs);
   }
 
   return NS_OK;
 }
 
 nsresult
+BluetoothHfpManager::HandleIccInfoChanged()
+{
+  nsCOMPtr<nsIMobileConnectionProvider> connection =
+    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
+  NS_ENSURE_TRUE(connection, NS_ERROR_FAILURE);
+
+  nsIDOMMozMobileICCInfo* iccInfo;
+  connection->GetIccInfo(&iccInfo);
+  NS_ENSURE_TRUE(iccInfo, NS_ERROR_FAILURE);
+
+  nsString msisdn;
+  iccInfo->GetMsisdn(msisdn);
+
+  if (!msisdn.Equals(mMsisdn)) {
+    mMsisdn = msisdn;
+  }
+
+  return NS_OK;
+}
+
+nsresult
 BluetoothHfpManager::HandleShutdown()
 {
   MOZ_ASSERT(NS_IsMainThread());
   gInShutdown = true;
   CloseSocket();
   gBluetoothHfpManager = nullptr;
   return NS_OK;
 }
@@ -582,16 +617,26 @@ BluetoothHfpManager::ReceiveSocketData(U
         break;
       default:
 #ifdef DEBUG
         NS_WARNING("Not handling state changed");
 #endif
         break;
     }
     SendLine("OK");
+  } else if (!strncmp(msg, "AT+CNUM", 7)) {
+    if (!mMsisdn.IsEmpty()) {
+      nsAutoCString message("+CNUM: ,\"");
+      message += NS_ConvertUTF16toUTF8(mMsisdn).get();
+      message += "\",";
+      message.AppendInt(TOA_UNKNOWN);
+      message += ",,4";
+      SendLine(message.get());
+    }
+    SendLine("OK");
   } else {
 #ifdef DEBUG
     nsCString warningMsg;
     warningMsg.AssignLiteral("Not handling HFP message, reply ok: ");
     warningMsg.Append(msg);
     NS_WARNING(warningMsg.get());
 #endif
     SendLine("OK");
--- a/dom/bluetooth/BluetoothHfpManager.h
+++ b/dom/bluetooth/BluetoothHfpManager.h
@@ -38,28 +38,31 @@ public:
   bool Listen();
   void SetVolume(int aVolume);
 
 private:
   friend class BluetoothHfpManagerObserver;
   BluetoothHfpManager();
   nsresult HandleVolumeChanged(const nsAString& aData);
   nsresult HandleShutdown();
+  nsresult HandleIccInfoChanged();
+
   bool Init();
   void Cleanup();
   void NotifyDialer(const nsAString& aCommand);
   void NotifySettings();
   virtual void OnConnectSuccess() MOZ_OVERRIDE;
   virtual void OnConnectError() MOZ_OVERRIDE;
   virtual void OnDisconnect() MOZ_OVERRIDE;
 
   int mCurrentVgs;
   int mCurrentCallIndex;
   bool mReceiveVgsFlag;
   nsString mDevicePath;
+  nsString mMsisdn;
   enum mozilla::ipc::SocketConnectionStatus mSocketStatus;
   nsTArray<int> mCurrentCallStateArray;
   nsAutoPtr<BluetoothRilListener> mListener;
   nsRefPtr<BluetoothReplyRunnable> mRunnable;
 };
 
 END_BLUETOOTH_NAMESPACE