Bug 1095488: Added AVRCP support for Bluetooth daemon backend, r=shuang
authorThomas Zimmermann <tdz@users.sourceforge.net>
Wed, 07 Jan 2015 11:32:06 +0100
changeset 248263 5968614a47687f73ee97919fa19498c2fe692dc2
parent 248262 e48fd6fe791f8a1d8a6997164cafea772d0c309a
child 248264 9e315e49e73a059789aa9bf93feaf3e79920f055
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshuang
bugs1095488
milestone37.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 1095488: Added AVRCP support for Bluetooth daemon backend, r=shuang
dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
dom/bluetooth/bluedroid/BluetoothDaemonInterface.h
--- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* 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 "BluetoothDaemonInterface.h"
 #include "BluetoothDaemonA2dpInterface.h"
+#include "BluetoothDaemonAvrcpInterface.h"
 #include "BluetoothDaemonHandsfreeInterface.h"
 #include "BluetoothDaemonHelpers.h"
 #include "BluetoothDaemonSetupInterface.h"
 #include "BluetoothDaemonSocketInterface.h"
 #include "BluetoothInterfaceHelpers.h"
 #include "mozilla/unused.h"
 
 using namespace mozilla::ipc;
@@ -1351,23 +1352,72 @@ private:
   }
 
 };
 
 //
 // Protocol handling
 //
 
+// |BluetoothDaemonProtocol| is the central class for communicating
+// with the Bluetooth daemon. It maintains both socket connections
+// to the external daemon and implements the complete HAL protocol
+// by inheriting from base-class modules.
+//
+// Each |BluetoothDaemon*Module| class implements an individual
+// module of the HAL protocol. Each class contains the abstract
+// methods
+//
+//  - |Send|,
+//  - |RegisterModule|, and
+//  - |UnregisterModule|.
+//
+// Module classes use |Send| to send out command PDUs. The socket
+// in |BluetoothDaemonProtocol| is required for sending. The abstract
+// method hides all these internal details from the modules.
+//
+// |RegisterModule| is required during module initialization, when
+// modules must register themselves at the daemon. The register command
+// is not part of the module itself, but contained in the Setup module
+// (id of 0x00). The abstract method |RegisterModule| allows modules to
+// call into the Setup module for generating the register command.
+//
+// |UnregisterModule| works like |RegisterModule|, but for cleanups.
+//
+// |BluetoothDaemonProtocol| also handles PDU receiving. It implements
+// the method |Handle| from |BluetoothDaemonPDUConsumer|. The socket
+// connections of type |BluetoothDaemonConnection| invoke this method
+// to forward received PDUs for processing by higher layers. The
+// implementation of |Handle| checks the service id of the PDU and
+// forwards it to the correct module class using the module's method
+// |HandleSvc|. Further PDU processing is module-dependent.
+//
+// To summarize the interface between |BluetoothDaemonProtocol| and
+// modules; the former implements the abstract methods
+//
+//  - |Send|,
+//  - |RegisterModule|, and
+//  - |UnregisterModule|,
+//
+// which allow modules to send out data. Each module implements the
+// method
+//
+//  - |HandleSvc|,
+//
+// which is called by |BluetoothDaemonProtcol| to hand over received
+// PDUs into a module.
+//
 class BluetoothDaemonProtocol MOZ_FINAL
   : public BluetoothDaemonPDUConsumer
   , public BluetoothDaemonSetupModule
   , public BluetoothDaemonCoreModule
   , public BluetoothDaemonSocketModule
   , public BluetoothDaemonHandsfreeModule
   , public BluetoothDaemonA2dpModule
+  , public BluetoothDaemonAvrcpModule
 {
 public:
   BluetoothDaemonProtocol(BluetoothDaemonConnection* aConnection);
 
   nsresult RegisterModule(uint8_t aId, uint8_t aMode,
                           BluetoothSetupResultHandler* aRes) MOZ_OVERRIDE;
 
   nsresult UnregisterModule(uint8_t aId,
@@ -1393,16 +1443,18 @@ private:
   void HandleCoreSvc(const BluetoothDaemonPDUHeader& aHeader,
                      BluetoothDaemonPDU& aPDU, void* aUserData);
   void HandleSocketSvc(const BluetoothDaemonPDUHeader& aHeader,
                        BluetoothDaemonPDU& aPDU, void* aUserData);
   void HandleHandsfreeSvc(const BluetoothDaemonPDUHeader& aHeader,
                           BluetoothDaemonPDU& aPDU, void* aUserData);
   void HandleA2dpSvc(const BluetoothDaemonPDUHeader& aHeader,
                      BluetoothDaemonPDU& aPDU, void* aUserData);
+  void HandleAvrcpSvc(const BluetoothDaemonPDUHeader& aHeader,
+                      BluetoothDaemonPDU& aPDU, void* aUserData);
 
   BluetoothDaemonConnection* mConnection;
   nsTArray<void*> mUserDataQ;
 };
 
 BluetoothDaemonProtocol::BluetoothDaemonProtocol(
   BluetoothDaemonConnection* aConnection)
   : mConnection(aConnection)
@@ -1470,29 +1522,40 @@ void
 BluetoothDaemonProtocol::HandleA2dpSvc(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
   void* aUserData)
 {
   BluetoothDaemonA2dpModule::HandleSvc(aHeader, aPDU, aUserData);
 }
 
 void
+BluetoothDaemonProtocol::HandleAvrcpSvc(
+  const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
+  void* aUserData)
+{
+  BluetoothDaemonAvrcpModule::HandleSvc(aHeader, aPDU, aUserData);
+}
+
+void
 BluetoothDaemonProtocol::Handle(BluetoothDaemonPDU& aPDU)
 {
   static void (BluetoothDaemonProtocol::* const HandleSvc[])(
     const BluetoothDaemonPDUHeader&, BluetoothDaemonPDU&, void*) = {
     INIT_ARRAY_AT(0x00, &BluetoothDaemonProtocol::HandleSetupSvc),
     INIT_ARRAY_AT(0x01, &BluetoothDaemonProtocol::HandleCoreSvc),
     INIT_ARRAY_AT(0x02, &BluetoothDaemonProtocol::HandleSocketSvc),
     INIT_ARRAY_AT(0x03, nullptr), // HID host
     INIT_ARRAY_AT(0x04, nullptr), // PAN
     INIT_ARRAY_AT(BluetoothDaemonHandsfreeModule::SERVICE_ID,
       &BluetoothDaemonProtocol::HandleHandsfreeSvc),
     INIT_ARRAY_AT(BluetoothDaemonA2dpModule::SERVICE_ID,
-      &BluetoothDaemonProtocol::HandleA2dpSvc)
+      &BluetoothDaemonProtocol::HandleA2dpSvc),
+    INIT_ARRAY_AT(0x07, nullptr), // Health
+    INIT_ARRAY_AT(BluetoothDaemonAvrcpModule::SERVICE_ID,
+      &BluetoothDaemonProtocol::HandleAvrcpSvc)
   };
 
   BluetoothDaemonPDUHeader header;
 
   if (NS_FAILED(UnpackPDU(aPDU, header)) ||
       NS_WARN_IF(!(header.mService < MOZ_ARRAY_LENGTH(HandleSvc))) ||
       NS_WARN_IF(!(HandleSvc[header.mService]))) {
     return;
@@ -2074,12 +2137,18 @@ BluetoothDaemonInterface::GetBluetoothA2
   mA2dpInterface = new BluetoothDaemonA2dpInterface(mProtocol);
 
   return mA2dpInterface;
 }
 
 BluetoothAvrcpInterface*
 BluetoothDaemonInterface::GetBluetoothAvrcpInterface()
 {
-  return nullptr;
+  if (mAvrcpInterface) {
+    return mAvrcpInterface;
+  }
+
+  mAvrcpInterface = new BluetoothDaemonAvrcpInterface(mProtocol);
+
+  return mAvrcpInterface;
 }
 
 END_BLUETOOTH_NAMESPACE
--- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.h
@@ -8,16 +8,17 @@
 #define mozilla_dom_bluetooth_bluedroid_bluetoothdaemoninterface_h__
 
 #include "BluetoothInterface.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 class BluetoothDaemonChannel;
 class BluetoothDaemonA2dpInterface;
+class BluetoothDaemonAvrcpInterface;
 class BluetoothDaemonHandsfreeInterface;
 class BluetoothDaemonProtocol;
 class BluetoothDaemonSocketInterface;
 
 class BluetoothDaemonInterface MOZ_FINAL : public BluetoothInterface
 {
 public:
   class CleanupResultHandler;
@@ -124,13 +125,14 @@ private:
   nsAutoPtr<BluetoothDaemonChannel> mNtfChannel;
   nsAutoPtr<BluetoothDaemonProtocol> mProtocol;
 
   nsTArray<nsRefPtr<BluetoothResultHandler> > mResultHandlerQ;
 
   nsAutoPtr<BluetoothDaemonSocketInterface> mSocketInterface;
   nsAutoPtr<BluetoothDaemonHandsfreeInterface> mHandsfreeInterface;
   nsAutoPtr<BluetoothDaemonA2dpInterface> mA2dpInterface;
+  nsAutoPtr<BluetoothDaemonAvrcpInterface> mAvrcpInterface;
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif