Bug 872907 - Patch 4: Implement NotifyStatusChagned() and NotifyAudioManager(), r=echou, r=mrbkap
authorGina Yeh <gyeh@mozilla.com>
Sat, 08 Jun 2013 23:26:01 +0800
changeset 134483 4df0816bb82cd52a8ab67a1863439869b27ce874
parent 134482 b659ff61bce829cfc62469f8420b3cebb1e8f05a
child 134484 9ac1a0ab4203af9fb3f7710e589f1cd7e36e2d52
push id29232
push useremorley@mozilla.com
push dateMon, 10 Jun 2013 09:07:08 +0000
treeherdermozilla-inbound@deb589f7e2dc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersechou, mrbkap
bugs872907
milestone24.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 872907 - Patch 4: Implement NotifyStatusChagned() and NotifyAudioManager(), r=echou, r=mrbkap
dom/bluetooth/BluetoothA2dpManager.cpp
dom/bluetooth/BluetoothA2dpManager.h
dom/bluetooth/BluetoothHfpManager.cpp
dom/bluetooth/BluetoothHfpManager.h
dom/bluetooth/BluetoothOppManager.cpp
dom/bluetooth/BluetoothOppManager.h
dom/bluetooth/BluetoothProfileManagerBase.h
--- a/dom/bluetooth/BluetoothA2dpManager.cpp
+++ b/dom/bluetooth/BluetoothA2dpManager.cpp
@@ -19,17 +19,17 @@
 #include "nsIObserverService.h"
 
 #define BLUETOOTH_A2DP_STATUS_CHANGED "bluetooth-a2dp-status-changed"
 
 using namespace mozilla;
 USING_BLUETOOTH_NAMESPACE
 
 namespace {
-  StaticAutoPtr<BluetoothA2dpManager> gBluetoothA2dpManager;
+  StaticRefPtr<BluetoothA2dpManager> gBluetoothA2dpManager;
   StaticRefPtr<BluetoothA2dpManagerObserver> sA2dpObserver;
   bool gInShutdown = false;
 } // anonymous namespace
 
 class mozilla::dom::bluetooth::BluetoothA2dpManagerObserver : public nsIObserver
 {
 public:
   NS_DECL_ISUPPORTS
@@ -226,16 +226,18 @@ BluetoothA2dpManager::HandleSinkProperty
   MOZ_ASSERT(arr.Length() == 1);
 
   const nsString& name = arr[0].name();
   const BluetoothValue& value = arr[0].value();
   if (name.EqualsLiteral("Connected")) {
     // Indicates if a stream is setup to a A2DP sink on the remote device.
     MOZ_ASSERT(value.type() == BluetoothValue::Tbool);
     mConnected = value.get_bool();
+    NotifyStatusChanged();
+    NotifyAudioManager();
   } else if (name.EqualsLiteral("Playing")) {
     // Indicates if a stream is active to a A2DP sink on the remote device.
     MOZ_ASSERT(value.type() == BluetoothValue::Tbool);
     mPlaying = value.get_bool();
   } else if (name.EqualsLiteral("State")) {
     MOZ_ASSERT(value.type() == BluetoothValue::TnsString);
     HandleSinkStateChanged(StatusStringToSinkState(value.get_nsString()));
   } else {
@@ -273,8 +275,70 @@ BluetoothA2dpManager::HandleSinkStateCha
                 mSinkState == SinkState::SINK_CONNECTED);
 
   if (aState == SinkState::SINK_DISCONNECTED) {
     mDeviceAddress.Truncate();
   }
 
   mSinkState = aState;
 }
+
+void
+BluetoothA2dpManager::NotifyStatusChanged()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  NS_NAMED_LITERAL_STRING(type, BLUETOOTH_A2DP_STATUS_CHANGED);
+  InfallibleTArray<BluetoothNamedValue> parameters;
+
+  BluetoothValue v = mConnected;
+  parameters.AppendElement(
+    BluetoothNamedValue(NS_LITERAL_STRING("connected"), v));
+
+  v = mDeviceAddress;
+  parameters.AppendElement(
+    BluetoothNamedValue(NS_LITERAL_STRING("address"), v));
+
+  if (!BroadcastSystemMessage(type, parameters)) {
+    NS_WARNING("Failed to broadcast system message to settings");
+    return;
+  }
+}
+
+void
+BluetoothA2dpManager::NotifyAudioManager()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsCOMPtr<nsIObserverService> obs =
+    do_GetService("@mozilla.org/observer-service;1");
+  NS_ENSURE_TRUE_VOID(obs);
+
+  nsAutoString data;
+  data.AppendInt(mConnected);
+
+  if (NS_FAILED(obs->NotifyObservers(this,
+                                     BLUETOOTH_A2DP_STATUS_CHANGED,
+                                     data.BeginReading()))) {
+    NS_WARNING("Failed to notify bluetooth-a2dp-status-changed observsers!");
+  }
+}
+
+void
+BluetoothA2dpManager::OnGetServiceChannel(const nsAString& aDeviceAddress,
+                                          const nsAString& aServiceUuid,
+                                          int aChannel)
+{
+}
+
+void
+BluetoothA2dpManager::OnUpdateSdpRecords(const nsAString& aDeviceAddress)
+{
+}
+
+void
+BluetoothA2dpManager::GetAddress(nsAString& aDeviceAddress)
+{
+  aDeviceAddress = mDeviceAddress;
+}
+
+NS_IMPL_ISUPPORTS0(BluetoothA2dpManager)
+
--- a/dom/bluetooth/BluetoothA2dpManager.h
+++ b/dom/bluetooth/BluetoothA2dpManager.h
@@ -3,49 +3,60 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_bluetooth_bluetootha2dpmanager_h__
 #define mozilla_dom_bluetooth_bluetootha2dpmanager_h__
 
 #include "BluetoothCommon.h"
+#include "BluetoothProfileManagerBase.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 enum SinkState {
   SINK_DISCONNECTED = 1,
   SINK_CONNECTING,
   SINK_CONNECTED,
   SINK_PLAYING,
   SINK_DISCONNECTING
 };
 
 class BluetoothA2dpManagerObserver;
 class BluetoothValue;
 class BluetoothSocket;
 
-class BluetoothA2dpManager
+class BluetoothA2dpManager : public BluetoothProfileManagerBase
 {
 public:
+  NS_DECL_ISUPPORTS
+
   static BluetoothA2dpManager* Get();
   ~BluetoothA2dpManager();
 
   bool Connect(const nsAString& aDeviceAddress);
   void Disconnect();
   void HandleSinkPropertyChanged(const BluetoothSignal& aSignal);
   nsresult HandleShutdown();
 
+  virtual void OnGetServiceChannel(const nsAString& aDeviceAddress,
+                                   const nsAString& aServiceUuid,
+                                   int aChannel) MOZ_OVERRIDE;
+  virtual void GetAddress(nsAString& aDeviceAddress) MOZ_OVERRIDE;
+
 private:
   BluetoothA2dpManager();
   bool Init();
   void Cleanup();
 
   void HandleSinkStateChanged(SinkState aState);
 
+  void NotifyStatusChanged();
+  void NotifyAudioManager();
+
   bool mConnected;
   bool mPlaying;
   nsString mDeviceAddress;
   SinkState mSinkState;
 };
 
 END_BLUETOOTH_NAMESPACE
 
--- a/dom/bluetooth/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/BluetoothHfpManager.cpp
@@ -3,16 +3,17 @@
 /* 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 "base/basictypes.h"
 
 #include "BluetoothHfpManager.h"
 
+#include "BluetoothA2dpManager.h"
 #include "BluetoothReplyRunnable.h"
 #include "BluetoothService.h"
 #include "BluetoothSocket.h"
 #include "BluetoothUtils.h"
 #include "BluetoothUuid.h"
 
 #include "MobileConnection.h"
 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
@@ -57,17 +58,17 @@
 
 #define CR_LF "\xd\xa";
 
 using namespace mozilla;
 using namespace mozilla::ipc;
 USING_BLUETOOTH_NAMESPACE
 
 namespace {
-  StaticAutoPtr<BluetoothHfpManager> gBluetoothHfpManager;
+  StaticRefPtr<BluetoothHfpManager> gBluetoothHfpManager;
   StaticRefPtr<BluetoothHfpManagerObserver> sHfpObserver;
   bool gInShutdown = false;
   static const char kHfpCrlf[] = "\xd\xa";
 
   // Sending ringtone related
   static bool sStopSendingRingFlag = true;
   static int sRingInterval = 3000; //unit: ms
 
@@ -521,27 +522,30 @@ BluetoothHfpManager::NotifyDialer(const 
 
   if (!BroadcastSystemMessage(type, parameters)) {
     NS_WARNING("Failed to broadcast system message to dialer");
     return;
   }
 }
 
 void
-BluetoothHfpManager::NotifyAudioManager(const nsAString& aAddress)
+BluetoothHfpManager::NotifyAudioManager(bool aStatus)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCOMPtr<nsIObserverService> obs =
     do_GetService("@mozilla.org/observer-service;1");
   NS_ENSURE_TRUE_VOID(obs);
 
-  if (NS_FAILED(obs->NotifyObservers(nullptr,
+  nsAutoString data;
+  data.AppendInt(aStatus);
+
+  if (NS_FAILED(obs->NotifyObservers(this,
                                      BLUETOOTH_SCO_STATUS_CHANGED,
-                                     aAddress.BeginReading()))) {
+                                     data.BeginReading()))) {
     NS_WARNING("Failed to notify bluetooth-sco-status-changed observsers!");
   }
 }
 
 nsresult
 BluetoothHfpManager::HandleVolumeChanged(const nsAString& aData)
 {
   MOZ_ASSERT(NS_IsMainThread());
@@ -1109,16 +1113,20 @@ BluetoothHfpManager::Listen()
 
 void
 BluetoothHfpManager::Disconnect()
 {
   if (mSocket) {
     mSocket->Disconnect();
     mSocket = nullptr;
   }
+
+  BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
+  NS_ENSURE_TRUE_VOID(a2dp);
+  a2dp->Disconnect();
 }
 
 bool
 BluetoothHfpManager::SendLine(const char* aMessage)
 {
   MOZ_ASSERT(mSocket);
 
   nsAutoCString msg;
@@ -1490,16 +1498,20 @@ BluetoothHfpManager::OnConnectSuccess(Bl
   mFirstCKPD = true;
 
   // Cache device path for NotifySettings() since we can't get socket address
   // when a headset disconnect with us
   mSocket->GetAddress(mDeviceAddress);
   NotifyStatusChanged(NS_LITERAL_STRING("bluetooth-hfp-status-changed"));
 
   ListenSco();
+
+  BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
+  NS_ENSURE_TRUE_VOID(a2dp);
+  a2dp->Connect(mDeviceAddress);
 }
 
 void
 BluetoothHfpManager::OnConnectError(BluetoothSocket* aSocket)
 {
   // Failed to create a SCO socket
   if (aSocket == mScoSocket) {
     OnScoConnectError();
@@ -1618,17 +1630,17 @@ BluetoothHfpManager::OnScoConnectSuccess
 {
   // For active connection request, we need to reply the DOMRequest
   if (mScoRunnable) {
     DispatchBluetoothReply(mScoRunnable,
                            BluetoothValue(true), EmptyString());
     mScoRunnable = nullptr;
   }
 
-  NotifyAudioManager(mDeviceAddress);
+  NotifyAudioManager(true);
   NotifyStatusChanged(NS_LITERAL_STRING("bluetooth-sco-status-changed"));
 
   mScoSocketStatus = mScoSocket->GetConnectionStatus();
 }
 
 void
 BluetoothHfpManager::OnScoConnectError()
 {
@@ -1642,17 +1654,17 @@ BluetoothHfpManager::OnScoConnectError()
   ListenSco();
 }
 
 void
 BluetoothHfpManager::OnScoDisconnect()
 {
   if (mScoSocketStatus == SocketConnectionStatus::SOCKET_CONNECTED) {
     ListenSco();
-    NotifyAudioManager(EmptyString());
+    NotifyAudioManager(false);
     NotifyStatusChanged(NS_LITERAL_STRING("bluetooth-sco-status-changed"));
   }
 }
 
 bool
 BluetoothHfpManager::IsConnected()
 {
   if (mSocket) {
@@ -1747,8 +1759,11 @@ bool
 BluetoothHfpManager::IsScoConnected()
 {
   if (mScoSocket) {
     return mScoSocket->GetConnectionStatus() ==
            SocketConnectionStatus::SOCKET_CONNECTED;
   }
   return false;
 }
+
+NS_IMPL_ISUPPORTS0(BluetoothHfpManager)
+
--- a/dom/bluetooth/BluetoothHfpManager.h
+++ b/dom/bluetooth/BluetoothHfpManager.h
@@ -50,29 +50,32 @@ enum BluetoothCmeError {
   NETWORK_TIMEOUT = 31,
   NETWORK_NOT_ALLOWED = 32
 };
 
 class BluetoothHfpManager : public BluetoothSocketObserver
                           , public BluetoothProfileManagerBase
 {
 public:
+  NS_DECL_ISUPPORTS
+
   static BluetoothHfpManager* Get();
   ~BluetoothHfpManager();
 
   virtual void ReceiveSocketData(
     BluetoothSocket* aSocket,
     nsAutoPtr<mozilla::ipc::UnixSocketRawData>& aMessage) MOZ_OVERRIDE;
   virtual void OnConnectSuccess(BluetoothSocket* aSocket) MOZ_OVERRIDE;
   virtual void OnConnectError(BluetoothSocket* aSocket) MOZ_OVERRIDE;
   virtual void OnDisconnect(BluetoothSocket* aSocket) MOZ_OVERRIDE;
   virtual void OnGetServiceChannel(const nsAString& aDeviceAddress,
                                    const nsAString& aServiceUuid,
                                    int aChannel) MOZ_OVERRIDE;
   virtual void OnUpdateSdpRecords(const nsAString& aDeviceAddress) MOZ_OVERRIDE;
+  virtual void GetAddress(nsAString& aDeviceAddress) MOZ_OVERRIDE;
 
   void Connect(const nsAString& aDeviceAddress,
                const bool aIsHandsfree,
                BluetoothReplyRunnable* aRunnable);
   void Disconnect();
   bool Listen();
   bool ConnectSco(BluetoothReplyRunnable* aRunnable = nullptr);
   bool DisconnectSco();
@@ -82,17 +85,16 @@ public:
    * @param aSend A boolean indicates whether we need to notify headset or not
    */
   void HandleCallStateChanged(uint32_t aCallIndex, uint16_t aCallState,
                               const nsAString& aNumber, const bool aIsOutgoing,
                               bool aSend);
 
   bool IsConnected();
   bool IsScoConnected();
-  void GetAddress(nsAString& aDeviceAddress);
 
 private:
   class GetVolumeTask;
   class RespondToBLDNTask;
   class SendRingIndicatorTask;
 
   friend class GetVolumeTask;
   friend class RespondToBLDNTask;
@@ -109,17 +111,17 @@ private:
   void Cleanup();
   void Reset();
   void ResetCallArray();
   uint32_t FindFirstCall(uint16_t aState);
   uint32_t GetNumberOfCalls(uint16_t aState);
 
   void NotifyDialer(const nsAString& aCommand);
   void NotifyStatusChanged(const nsAString& aType);
-  void NotifyAudioManager(const nsAString& aAddress);
+  void NotifyAudioManager(bool aStatus);
 
   bool SendCommand(const char* aCommand, uint32_t aValue = 0);
   bool SendLine(const char* aMessage);
   void UpdateCIND(uint8_t aType, uint8_t aValue, bool aSend);
   void OnScoConnectSuccess();
   void OnScoConnectError();
   void OnScoDisconnect();
 
--- a/dom/bluetooth/BluetoothOppManager.cpp
+++ b/dom/bluetooth/BluetoothOppManager.cpp
@@ -81,17 +81,17 @@ namespace {
 static const uint32_t kUpdateProgressBase = 50 * 1024;
 
 /*
  * The format of the header of an PUT request is
  * [opcode:1][packet length:2][headerId:1][header length:2]
  */
 static const uint32_t kPutRequestHeaderSize = 6;
 
-StaticAutoPtr<BluetoothOppManager> sInstance;
+StaticRefPtr<BluetoothOppManager> sInstance;
 
 /*
  * FIXME / Bug 806749
  *
  * Currently Bluetooth*Manager inherits mozilla::ipc::UnixSocketConsumer,
  * which means that each Bluetooth*Manager can handle only one socket
  * connection at a time. We need to support concurrent multiple socket
  * connections, and then we will be able to have multiple file transferring
@@ -1503,16 +1503,18 @@ BluetoothOppManager::OnUpdateSdpRecords(
     DispatchBluetoothReply(mRunnable, BluetoothValue(),
                            NS_LITERAL_STRING(ERR_SERVICE_CHANNEL_NOT_FOUND));
     mRunnable = nullptr;
     mSocket = nullptr;
     Listen();
   }
 }
 
+NS_IMPL_ISUPPORTS0(BluetoothOppManager)
+
 bool
 BluetoothOppManager::AcquireSdcardMountLock()
 {
   nsCOMPtr<nsIVolumeService> volumeSrv =
     do_GetService(NS_VOLUMESERVICE_CONTRACTID);
   NS_ENSURE_TRUE(volumeSrv, false);
   nsresult rv;
   rv = volumeSrv->CreateMountLock(NS_LITERAL_STRING("sdcard"),
--- a/dom/bluetooth/BluetoothOppManager.h
+++ b/dom/bluetooth/BluetoothOppManager.h
@@ -24,16 +24,18 @@ BEGIN_BLUETOOTH_NAMESPACE
 class BluetoothReplyRunnable;
 class BluetoothSocket;
 class ObexHeaderSet;
 
 class BluetoothOppManager : public BluetoothSocketObserver
                           , public BluetoothProfileManagerBase
 {
 public:
+  NS_DECL_ISUPPORTS
+
   /*
    * Channel of reserved services are fixed values, please check
    * function add_reserved_service_records() in
    * external/bluetooth/bluez/src/adapter.c for more information.
    */
   static const int DEFAULT_OPP_CHANNEL = 10;
   static const int MAX_PACKET_LENGTH = 0xFFFE;
 
@@ -71,30 +73,30 @@ public:
 
   void ExtractPacketHeaders(const ObexHeaderSet& aHeader);
   bool ExtractBlobHeaders();
   nsresult HandleShutdown();
 
   // Return true if there is an ongoing file-transfer session, please see
   // Bug 827267 for more information.
   bool IsTransferring();
-  void GetAddress(nsAString& aDeviceAddress);
 
   // Implement interface BluetoothSocketObserver
   void ReceiveSocketData(
     BluetoothSocket* aSocket,
     nsAutoPtr<mozilla::ipc::UnixSocketRawData>& aMessage) MOZ_OVERRIDE;
 
   virtual void OnConnectSuccess(BluetoothSocket* aSocket) MOZ_OVERRIDE;
   virtual void OnConnectError(BluetoothSocket* aSocket) MOZ_OVERRIDE;
   virtual void OnDisconnect(BluetoothSocket* aSocket) MOZ_OVERRIDE;
   virtual void OnGetServiceChannel(const nsAString& aDeviceAddress,
                                    const nsAString& aServiceUuid,
                                    int aChannel) MOZ_OVERRIDE;
   virtual void OnUpdateSdpRecords(const nsAString& aDeviceAddress) MOZ_OVERRIDE;
+  virtual void GetAddress(nsAString& aDeviceAddress) MOZ_OVERRIDE;
 
 private:
   BluetoothOppManager();
   void StartFileTransfer();
   void StartSendingNextFile();
   void FileTransferComplete();
   void UpdateProgress();
   void ReceivingFileConfirmation();
--- a/dom/bluetooth/BluetoothProfileManagerBase.h
+++ b/dom/bluetooth/BluetoothProfileManagerBase.h
@@ -8,21 +8,21 @@
 #define mozilla_dom_bluetooth_bluetoothprofilemanagerbase_h__
 
 #define ERR_SERVICE_CHANNEL_NOT_FOUND "DeviceChannelRetrievalError"
 
 #include "BluetoothCommon.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
-class BluetoothProfileManagerBase
+class BluetoothProfileManagerBase : public nsISupports
 {
 public:
   virtual void OnGetServiceChannel(const nsAString& aDeviceAddress,
                                    const nsAString& aServiceUuid,
                                    int aChannel) = 0;
-
   virtual void OnUpdateSdpRecords(const nsAString& aDeviceAddress) = 0;
+  virtual void GetAddress(nsAString& aDeviceAddress) = 0;
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif  //#ifndef mozilla_dom_bluetooth_bluetoothprofilemanagerbase_h__