Bug 943752 - Refine BluetoothProfileController logic for AVRCP and HID, r=echou
authorGina Yeh <gyeh@mozilla.com>
Thu, 05 Dec 2013 10:05:39 +0800
changeset 174557 e8970388942a619b0263042c0bef9a9e78e80f75
parent 174556 4c2bc5ae8f956cda96b96b9b26522074f0e1023a
child 174558 fa1b32f3a4e02484e628bc3acae20c4217dbb396
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersechou
bugs943752
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 943752 - Refine BluetoothProfileController logic for AVRCP and HID, r=echou
dom/bluetooth/BluetoothProfileController.cpp
dom/bluetooth/BluetoothProfileController.h
--- a/dom/bluetooth/BluetoothProfileController.cpp
+++ b/dom/bluetooth/BluetoothProfileController.cpp
@@ -134,29 +134,37 @@ BluetoothProfileController::SetupProfile
 
   /**
    * For a connect request, put multiple profiles into array and connect to
    * all of them sequencely.
    */
   bool hasAudio = HAS_AUDIO(mTarget.cod);
   bool hasRendering = HAS_RENDERING(mTarget.cod);
   bool isPeripheral = IS_PERIPHERAL(mTarget.cod);
+  bool isRemoteControl = IS_REMOTE_CONTROL(mTarget.cod);
+  bool isKeyboard = IS_KEYBOARD(mTarget.cod);
+  bool isPointingDevice = IS_POINTING_DEVICE(mTarget.cod);
 
   NS_ENSURE_TRUE_VOID(hasAudio || hasRendering || isPeripheral);
 
-  /**
-   * Connect to HFP/HSP first. Then, connect A2DP if Rendering bit is set.
-   */
+  // Audio bit should be set if remote device supports HFP/HSP.
   if (hasAudio) {
     AddProfile(BluetoothHfpManager::Get());
   }
-  if (hasRendering) {
+
+  // Rendering bit should be set if remote device supports A2DP.
+  // A device which supports AVRCP should claim that it's a peripheral and it's
+  // a remote control.
+  if (hasRendering || (isPeripheral && isRemoteControl)) {
     AddProfile(BluetoothA2dpManager::Get());
   }
-  if (isPeripheral) {
+
+  // A device which supports HID should claim that it's a peripheral and it's
+  // either a keyboard, a pointing device, or both.
+  if (isPeripheral && (isKeyboard || isPointingDevice)) {
     AddProfile(BluetoothHidManager::Get());
   }
 }
 
 void
 BluetoothProfileController::Start()
 {
   MOZ_ASSERT(NS_IsMainThread());
--- a/dom/bluetooth/BluetoothProfileController.h
+++ b/dom/bluetooth/BluetoothProfileController.h
@@ -29,25 +29,34 @@ BEGIN_BLUETOOTH_NAMESPACE
 #define GET_MAJOR_SERVICE_CLASS(cod) ((cod & 0xffe000) >> 13)
 
 // Bit 12 ~ Bit 8: Major device class
 #define GET_MAJOR_DEVICE_CLASS(cod)  ((cod & 0x1f00) >> 8)
 
 // Bit 7 ~ Bit 2: Minor device class
 #define GET_MINOR_DEVICE_CLASS(cod)  ((cod & 0xfc) >> 2)
 
-// Bit 21: Major service class = 0x100, Audio
+// Audio: Major service class = 0x100 (Bit 21 is set)
 #define HAS_AUDIO(cod)               (cod & 0x200000)
 
-// Bit 18: Major service class = 0x20, Rendering
+// Rendering: Major service class = 0x20 (Bit 18 is set)
 #define HAS_RENDERING(cod)           (cod & 0x40000)
 
-// Major device class = 0x5, Peripheral
+// Peripheral: Major device class = 0x5
 #define IS_PERIPHERAL(cod)           (GET_MAJOR_DEVICE_CLASS(cod) == 0x5)
 
+// Remote Control: sub-field of minor device class, Bit 5 ~ Bit 2 = 0x3
+#define IS_REMOTE_CONTROL(cod)       ((GET_MINOR_DEVICE_CLASS(cod) & 0xf) == 0x3)
+
+// Keyboard: sub-field of minor device class (Bit 6)
+#define IS_KEYBOARD(cod)             ((GET_MINOR_DEVICE_CLASS(cod) & 0x10) >> 4)
+
+// Pointing device: sub-field of minor device class (Bit 7)
+#define IS_POINTING_DEVICE(cod)      ((GET_MINOR_DEVICE_CLASS(cod) & 0x20) >> 5)
+
 class BluetoothProfileManagerBase;
 class BluetoothReplyRunnable;
 typedef void (*BluetoothProfileControllerCallback)();
 
 class BluetoothProfileController : public RefCounted<BluetoothProfileController>
 {
 public:
   /**