Merge b2g-inbound to m-c. a=merge

This commit is contained in:
Ryan VanderMeulen 2014-09-11 18:15:16 -04:00
Родитель 25ac1e48b6 33ea1b7d22
Коммит 37abdbb0e3
29 изменённых файлов: 5182 добавлений и 4630 удалений

Просмотреть файл

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please # changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more. # don't change CLOBBER for WebIDL changes any more.
Merge day clobber Bug 1061489: Updated moz.build requires CLOBBER

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68"> <project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project> </project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7c22462206967693ab96b6af1627ba6925f5723f"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="7c22462206967693ab96b6af1627ba6925f5723f"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68"> <project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68"> <project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project> </project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7c22462206967693ab96b6af1627ba6925f5723f"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="7c22462206967693ab96b6af1627ba6925f5723f"/>

Просмотреть файл

@ -4,6 +4,6 @@
"remote": "", "remote": "",
"branch": "" "branch": ""
}, },
"revision": "d39431f7b119e5cac505e63375ba929ac72eb681", "revision": "62c1693326443d61bfa405d41d95d05281053cfa",
"repo_path": "/integration/gaia-central" "repo_path": "/integration/gaia-central"
} }

Просмотреть файл

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project> </project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7c22462206967693ab96b6af1627ba6925f5723f"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="7c22462206967693ab96b6af1627ba6925f5723f"/>

Просмотреть файл

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -0,0 +1,109 @@
/* -*- 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 "BluetoothInterface.h"
#ifdef MOZ_B2G_BT_BLUEDROID
#include "BluetoothHALInterface.h"
#endif
BEGIN_BLUETOOTH_NAMESPACE
//
// Socket Interface
//
BluetoothSocketInterface::~BluetoothSocketInterface()
{ }
//
// Handsfree Interface
//
// Notification handling
//
BluetoothHandsfreeNotificationHandler::
~BluetoothHandsfreeNotificationHandler()
{ }
// Interface
//
BluetoothHandsfreeInterface::BluetoothHandsfreeInterface()
{ }
BluetoothHandsfreeInterface::~BluetoothHandsfreeInterface()
{ }
//
// Bluetooth Advanced Audio Interface
//
// Notification handling
//
BluetoothA2dpNotificationHandler::~BluetoothA2dpNotificationHandler()
{ }
// Interface
//
BluetoothA2dpInterface::BluetoothA2dpInterface()
{ }
BluetoothA2dpInterface::~BluetoothA2dpInterface()
{ }
//
// Bluetooth AVRCP Interface
//
// Notification handling
//
BluetoothAvrcpNotificationHandler::~BluetoothAvrcpNotificationHandler()
{ }
// Interface
//
BluetoothAvrcpInterface::BluetoothAvrcpInterface()
{ }
BluetoothAvrcpInterface::~BluetoothAvrcpInterface()
{ }
// Notification handling
//
BluetoothNotificationHandler::~BluetoothNotificationHandler()
{ }
// Interface
//
BluetoothInterface*
BluetoothInterface::GetInstance()
{
/* Here's where we decide which implementation to use. Currently
* there is only Bluedroid, but others are possible. Having multiple
* interfaces built-in and selecting the correct one at runtime could
* also be an option.
*/
#ifdef MOZ_B2G_BT_BLUEDROID
return BluetoothHALInterface::GetInstance();
#else
return nullptr;
#endif
}
BluetoothInterface::BluetoothInterface()
{ }
BluetoothInterface::~BluetoothInterface()
{ }
END_BLUETOOTH_NAMESPACE

Просмотреть файл

@ -4,23 +4,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file, * 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/. */ * You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_bluedroid_bluetoothinterface_h__ #ifndef mozilla_dom_bluetooth_bluetoothinterface_h__
#define mozilla_dom_bluetooth_bluedroid_bluetoothinterface_h__ #define mozilla_dom_bluetooth_bluetoothinterface_h__
#include <hardware/bluetooth.h>
#include <hardware/bt_sock.h>
#include <hardware/bt_hf.h>
#include <hardware/bt_av.h>
#if ANDROID_VERSION >= 18
#include <hardware/bt_rc.h>
#endif
#include "BluetoothCommon.h" #include "BluetoothCommon.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h" #include "mozilla/dom/bluetooth/BluetoothTypes.h"
BEGIN_BLUETOOTH_NAMESPACE BEGIN_BLUETOOTH_NAMESPACE
class BluetoothInterface;
// //
// Socket Interface // Socket Interface
// //
@ -47,30 +38,24 @@ public:
class BluetoothSocketInterface class BluetoothSocketInterface
{ {
public: public:
friend class BluetoothInterface;
// Init and Cleanup is handled by BluetoothInterface // Init and Cleanup is handled by BluetoothInterface
void Listen(BluetoothSocketType aType, virtual void Listen(BluetoothSocketType aType,
const nsAString& aServiceName, const nsAString& aServiceName,
const uint8_t aServiceUuid[16], const uint8_t aServiceUuid[16],
int aChannel, bool aEncrypt, bool aAuth, int aChannel, bool aEncrypt, bool aAuth,
BluetoothSocketResultHandler* aRes); BluetoothSocketResultHandler* aRes) = 0;
void Connect(const nsAString& aBdAddr, virtual void Connect(const nsAString& aBdAddr,
BluetoothSocketType aType, BluetoothSocketType aType,
const uint8_t aUuid[16], const uint8_t aUuid[16],
int aChannel, bool aEncrypt, bool aAuth, int aChannel, bool aEncrypt, bool aAuth,
BluetoothSocketResultHandler* aRes); BluetoothSocketResultHandler* aRes) = 0;
void Accept(int aFd, BluetoothSocketResultHandler* aRes); virtual void Accept(int aFd, BluetoothSocketResultHandler* aRes) = 0;
protected: protected:
BluetoothSocketInterface(const btsock_interface_t* aInterface); virtual ~BluetoothSocketInterface();
~BluetoothSocketInterface();
private:
const btsock_interface_t* mInterface;
}; };
// //
@ -191,74 +176,70 @@ public:
class BluetoothHandsfreeInterface class BluetoothHandsfreeInterface
{ {
public: public:
friend class BluetoothInterface; virtual void Init(
BluetoothHandsfreeNotificationHandler* aNotificationHandler,
void Init(BluetoothHandsfreeNotificationHandler* aNotificationHandler, BluetoothHandsfreeResultHandler* aRes) = 0;
BluetoothHandsfreeResultHandler* aRes); virtual void Cleanup(BluetoothHandsfreeResultHandler* aRes) = 0;
void Cleanup(BluetoothHandsfreeResultHandler* aRes);
/* Connect / Disconnect */ /* Connect / Disconnect */
void Connect(const nsAString& aBdAddr, virtual void Connect(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes); BluetoothHandsfreeResultHandler* aRes) = 0;
void Disconnect(const nsAString& aBdAddr, virtual void Disconnect(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes); BluetoothHandsfreeResultHandler* aRes) = 0;
void ConnectAudio(const nsAString& aBdAddr, virtual void ConnectAudio(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes); BluetoothHandsfreeResultHandler* aRes) = 0;
void DisconnectAudio(const nsAString& aBdAddr, virtual void DisconnectAudio(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes); BluetoothHandsfreeResultHandler* aRes) = 0;
/* Voice Recognition */ /* Voice Recognition */
void StartVoiceRecognition(BluetoothHandsfreeResultHandler* aRes); virtual void StartVoiceRecognition(BluetoothHandsfreeResultHandler* aRes) = 0;
void StopVoiceRecognition(BluetoothHandsfreeResultHandler* aRes); virtual void StopVoiceRecognition(BluetoothHandsfreeResultHandler* aRes) = 0;
/* Volume */ /* Volume */
void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume, virtual void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume,
BluetoothHandsfreeResultHandler* aRes); BluetoothHandsfreeResultHandler* aRes) = 0;
/* Device status */ /* Device status */
void DeviceStatusNotification(BluetoothHandsfreeNetworkState aNtkState, virtual void DeviceStatusNotification(
BluetoothHandsfreeNetworkState aNtkState,
BluetoothHandsfreeServiceType aSvcType, BluetoothHandsfreeServiceType aSvcType,
int aSignal, int aBattChg, int aSignal, int aBattChg, BluetoothHandsfreeResultHandler* aRes) = 0;
BluetoothHandsfreeResultHandler* aRes);
/* Responses */ /* Responses */
void CopsResponse(const char* aCops, virtual void CopsResponse(const char* aCops,
BluetoothHandsfreeResultHandler* aRes); BluetoothHandsfreeResultHandler* aRes) = 0;
void CindResponse(int aSvc, int aNumActive, int aNumHeld, virtual void CindResponse(int aSvc, int aNumActive, int aNumHeld,
BluetoothHandsfreeCallState aCallSetupState, int aSignal, BluetoothHandsfreeCallState aCallSetupState,
int aRoam, int aBattChg, int aSignal, int aRoam, int aBattChg,
BluetoothHandsfreeResultHandler* aRes); BluetoothHandsfreeResultHandler* aRes) = 0;
void FormattedAtResponse(const char* aRsp, virtual void FormattedAtResponse(const char* aRsp,
BluetoothHandsfreeResultHandler* aRes); BluetoothHandsfreeResultHandler* aRes) = 0;
void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode, virtual void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
BluetoothHandsfreeResultHandler* aRes); BluetoothHandsfreeResultHandler* aRes) = 0;
void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir, virtual void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir,
BluetoothHandsfreeCallState aState, BluetoothHandsfreeCallState aState,
BluetoothHandsfreeCallMode aMode, BluetoothHandsfreeCallMode aMode,
BluetoothHandsfreeCallMptyType aMpty, BluetoothHandsfreeCallMptyType aMpty,
const nsAString& aNumber, const nsAString& aNumber,
BluetoothHandsfreeCallAddressType aType, BluetoothHandsfreeCallAddressType aType,
BluetoothHandsfreeResultHandler* aRes); BluetoothHandsfreeResultHandler* aRes) = 0;
/* Phone State */ /* Phone State */
void PhoneStateChange(int aNumActive, int aNumHeld, virtual void PhoneStateChange(int aNumActive, int aNumHeld,
BluetoothHandsfreeCallState aCallSetupState, BluetoothHandsfreeCallState aCallSetupState,
const nsAString& aNumber, const nsAString& aNumber,
BluetoothHandsfreeCallAddressType aType, BluetoothHandsfreeCallAddressType aType,
BluetoothHandsfreeResultHandler* aRes); BluetoothHandsfreeResultHandler* aRes) = 0;
protected: protected:
BluetoothHandsfreeInterface(const bthf_interface_t* aInterface); BluetoothHandsfreeInterface();
~BluetoothHandsfreeInterface(); virtual ~BluetoothHandsfreeInterface();
private:
const bthf_interface_t* mInterface;
}; };
// //
@ -306,23 +287,18 @@ public:
class BluetoothA2dpInterface class BluetoothA2dpInterface
{ {
public: public:
friend class BluetoothInterface; virtual void Init(BluetoothA2dpNotificationHandler* aNotificationHandler,
BluetoothA2dpResultHandler* aRes) = 0;
virtual void Cleanup(BluetoothA2dpResultHandler* aRes) = 0;
void Init(BluetoothA2dpNotificationHandler* aNotificationHandler, virtual void Connect(const nsAString& aBdAddr,
BluetoothA2dpResultHandler* aRes); BluetoothA2dpResultHandler* aRes) = 0;
void Cleanup(BluetoothA2dpResultHandler* aRes); virtual void Disconnect(const nsAString& aBdAddr,
BluetoothA2dpResultHandler* aRes) = 0;
void Connect(const nsAString& aBdAddr,
BluetoothA2dpResultHandler* aRes);
void Disconnect(const nsAString& aBdAddr,
BluetoothA2dpResultHandler* aRes);
protected: protected:
BluetoothA2dpInterface(const btav_interface_t* aInterface); BluetoothA2dpInterface();
~BluetoothA2dpInterface(); virtual ~BluetoothA2dpInterface();
private:
const btav_interface_t* mInterface;
}; };
// //
@ -428,61 +404,50 @@ public:
class BluetoothAvrcpInterface class BluetoothAvrcpInterface
{ {
public: public:
friend class BluetoothInterface; virtual void Init(BluetoothAvrcpNotificationHandler* aNotificationHandler,
BluetoothAvrcpResultHandler* aRes) = 0;
virtual void Cleanup(BluetoothAvrcpResultHandler* aRes) = 0;
void Init(BluetoothAvrcpNotificationHandler* aNotificationHandler, virtual void GetPlayStatusRsp(ControlPlayStatus aPlayStatus,
BluetoothAvrcpResultHandler* aRes);
void Cleanup(BluetoothAvrcpResultHandler* aRes);
void GetPlayStatusRsp(ControlPlayStatus aPlayStatus,
uint32_t aSongLen, uint32_t aSongPos, uint32_t aSongLen, uint32_t aSongPos,
BluetoothAvrcpResultHandler* aRes); BluetoothAvrcpResultHandler* aRes) = 0;
void ListPlayerAppAttrRsp(int aNumAttr, virtual void ListPlayerAppAttrRsp(
const BluetoothAvrcpPlayerAttribute* aPAttrs, int aNumAttr, const BluetoothAvrcpPlayerAttribute* aPAttrs,
BluetoothAvrcpResultHandler* aRes); BluetoothAvrcpResultHandler* aRes) = 0;
void ListPlayerAppValueRsp(int aNumVal, uint8_t* aPVals, virtual void ListPlayerAppValueRsp(int aNumVal, uint8_t* aPVals,
BluetoothAvrcpResultHandler* aRes); BluetoothAvrcpResultHandler* aRes) = 0;
/* TODO: redesign this interface once we actually use it */ /* TODO: redesign this interface once we actually use it */
void GetPlayerAppValueRsp(uint8_t aNumAttrs, virtual void GetPlayerAppValueRsp(uint8_t aNumAttrs, const uint8_t* aIds,
const uint8_t* aIds, const uint8_t* aValues, const uint8_t* aValues,
BluetoothAvrcpResultHandler* aRes); BluetoothAvrcpResultHandler* aRes) = 0;
/* TODO: redesign this interface once we actually use it */ /* TODO: redesign this interface once we actually use it */
void GetPlayerAppAttrTextRsp(int aNumAttr, virtual void GetPlayerAppAttrTextRsp(int aNumAttr, const uint8_t* aIds,
const uint8_t* aIds, const char** aTexts, const char** aTexts,
BluetoothAvrcpResultHandler* aRes); BluetoothAvrcpResultHandler* aRes) = 0;
/* TODO: redesign this interface once we actually use it */ /* TODO: redesign this interface once we actually use it */
void GetPlayerAppValueTextRsp(int aNumVal, virtual void GetPlayerAppValueTextRsp(int aNumVal, const uint8_t* aIds,
const uint8_t* aIds, const char** aTexts, const char** aTexts,
BluetoothAvrcpResultHandler* aRes); BluetoothAvrcpResultHandler* aRes) = 0;
void GetElementAttrRsp(uint8_t aNumAttr, virtual void GetElementAttrRsp(uint8_t aNumAttr,
const BluetoothAvrcpElementAttribute* aAttr, const BluetoothAvrcpElementAttribute* aAttr,
BluetoothAvrcpResultHandler* aRes); BluetoothAvrcpResultHandler* aRes) = 0;
void SetPlayerAppValueRsp(BluetoothAvrcpStatus aRspStatus, virtual void SetPlayerAppValueRsp(BluetoothAvrcpStatus aRspStatus,
BluetoothAvrcpResultHandler* aRes); BluetoothAvrcpResultHandler* aRes) = 0;
void RegisterNotificationRsp(BluetoothAvrcpEvent aEvent, virtual void RegisterNotificationRsp(
BluetoothAvrcpNotification aType, BluetoothAvrcpEvent aEvent, BluetoothAvrcpNotification aType,
const BluetoothAvrcpNotificationParam& aParam, const BluetoothAvrcpNotificationParam& aParam,
BluetoothAvrcpResultHandler* aRes); BluetoothAvrcpResultHandler* aRes) = 0;
void SetVolume(uint8_t aVolume, BluetoothAvrcpResultHandler* aRes); virtual void SetVolume(uint8_t aVolume, BluetoothAvrcpResultHandler* aRes) = 0;
protected: protected:
BluetoothAvrcpInterface( BluetoothAvrcpInterface();
#if ANDROID_VERSION >= 18 virtual ~BluetoothAvrcpInterface();
const btrc_interface_t* aInterface
#endif
);
~BluetoothAvrcpInterface();
private:
#if ANDROID_VERSION >= 18
const btrc_interface_t* mInterface;
#endif
}; };
// //
@ -582,92 +547,86 @@ class BluetoothInterface
public: public:
static BluetoothInterface* GetInstance(); static BluetoothInterface* GetInstance();
void Init(BluetoothNotificationHandler* aNotificationHandler, virtual void Init(BluetoothNotificationHandler* aNotificationHandler,
BluetoothResultHandler* aRes); BluetoothResultHandler* aRes) = 0;
void Cleanup(BluetoothResultHandler* aRes); virtual void Cleanup(BluetoothResultHandler* aRes) = 0;
void Enable(BluetoothResultHandler* aRes);
void Disable(BluetoothResultHandler* aRes);
virtual void Enable(BluetoothResultHandler* aRes) = 0;
virtual void Disable(BluetoothResultHandler* aRes) = 0;
/* Adapter Properties */ /* Adapter Properties */
void GetAdapterProperties(BluetoothResultHandler* aRes); virtual void GetAdapterProperties(BluetoothResultHandler* aRes) = 0;
void GetAdapterProperty(const nsAString& aName, virtual void GetAdapterProperty(const nsAString& aName,
BluetoothResultHandler* aRes); BluetoothResultHandler* aRes) = 0;
void SetAdapterProperty(const BluetoothNamedValue& aProperty, virtual void SetAdapterProperty(const BluetoothNamedValue& aProperty,
BluetoothResultHandler* aRes); BluetoothResultHandler* aRes) = 0;
/* Remote Device Properties */ /* Remote Device Properties */
void GetRemoteDeviceProperties(const nsAString& aRemoteAddr, virtual void GetRemoteDeviceProperties(const nsAString& aRemoteAddr,
BluetoothResultHandler* aRes); BluetoothResultHandler* aRes) = 0;
void GetRemoteDeviceProperty(const nsAString& aRemoteAddr, virtual void GetRemoteDeviceProperty(const nsAString& aRemoteAddr,
const nsAString& aName, const nsAString& aName,
BluetoothResultHandler* aRes); BluetoothResultHandler* aRes) = 0;
void SetRemoteDeviceProperty(const nsAString& aRemoteAddr, virtual void SetRemoteDeviceProperty(const nsAString& aRemoteAddr,
const BluetoothNamedValue& aProperty, const BluetoothNamedValue& aProperty,
BluetoothResultHandler* aRes); BluetoothResultHandler* aRes) = 0;
/* Remote Services */ /* Remote Services */
void GetRemoteServiceRecord(const nsAString& aRemoteAddr, virtual void GetRemoteServiceRecord(const nsAString& aRemoteAddr,
const uint8_t aUuid[16], const uint8_t aUuid[16],
BluetoothResultHandler* aRes); BluetoothResultHandler* aRes) = 0;
void GetRemoteServices(const nsAString& aRemoteAddr, virtual void GetRemoteServices(const nsAString& aRemoteAddr,
BluetoothResultHandler* aRes); BluetoothResultHandler* aRes) = 0;
/* Discovery */ /* Discovery */
void StartDiscovery(BluetoothResultHandler* aRes); virtual void StartDiscovery(BluetoothResultHandler* aRes) = 0;
void CancelDiscovery(BluetoothResultHandler* aRes); virtual void CancelDiscovery(BluetoothResultHandler* aRes) = 0;
/* Bonds */ /* Bonds */
void CreateBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes); virtual void CreateBond(const nsAString& aBdAddr,
void RemoveBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes); BluetoothResultHandler* aRes) = 0;
void CancelBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes); virtual void RemoveBond(const nsAString& aBdAddr,
BluetoothResultHandler* aRes) = 0;
virtual void CancelBond(const nsAString& aBdAddr,
BluetoothResultHandler* aRes) = 0;
/* Authentication */ /* Authentication */
void PinReply(const nsAString& aBdAddr, bool aAccept, virtual void PinReply(const nsAString& aBdAddr, bool aAccept,
const nsAString& aPinCode, const nsAString& aPinCode,
BluetoothResultHandler* aRes); BluetoothResultHandler* aRes) = 0;
void SspReply(const nsAString& aBdAddr, const nsAString& aVariant, virtual void SspReply(const nsAString& aBdAddr, const nsAString& aVariant,
bool aAccept, uint32_t aPasskey, bool aAccept, uint32_t aPasskey,
BluetoothResultHandler* aRes); BluetoothResultHandler* aRes) = 0;
/* DUT Mode */ /* DUT Mode */
void DutModeConfigure(bool aEnable, BluetoothResultHandler* aRes); virtual void DutModeConfigure(bool aEnable,
void DutModeSend(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen, BluetoothResultHandler* aRes) = 0;
BluetoothResultHandler* aRes); virtual void DutModeSend(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
BluetoothResultHandler* aRes) = 0;
/* LE Mode */ /* LE Mode */
void LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen, virtual void LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
BluetoothResultHandler* aRes); BluetoothResultHandler* aRes) = 0;
/* Profile Interfaces */ /* Profile Interfaces */
BluetoothSocketInterface* GetBluetoothSocketInterface(); virtual BluetoothSocketInterface* GetBluetoothSocketInterface() = 0;
BluetoothHandsfreeInterface* GetBluetoothHandsfreeInterface(); virtual BluetoothHandsfreeInterface* GetBluetoothHandsfreeInterface() = 0;
BluetoothA2dpInterface* GetBluetoothA2dpInterface(); virtual BluetoothA2dpInterface* GetBluetoothA2dpInterface() = 0;
BluetoothAvrcpInterface* GetBluetoothAvrcpInterface(); virtual BluetoothAvrcpInterface* GetBluetoothAvrcpInterface() = 0;
protected: protected:
BluetoothInterface(const bt_interface_t* aInterface); BluetoothInterface();
~BluetoothInterface(); virtual ~BluetoothInterface();
private:
template <class T>
T* CreateProfileInterface();
template <class T>
T* GetProfileInterface();
const bt_interface_t* mInterface;
}; };
END_BLUETOOTH_NAMESPACE END_BLUETOOTH_NAMESPACE

Просмотреть файл

@ -0,0 +1,184 @@
/* -*- 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 "BluetoothA2dpHALInterface.h"
#include "BluetoothHALHelpers.h"
BEGIN_BLUETOOTH_NAMESPACE
typedef
BluetoothHALInterfaceRunnable0<BluetoothA2dpResultHandler, void>
BluetoothA2dpHALResultRunnable;
typedef
BluetoothHALInterfaceRunnable1<BluetoothA2dpResultHandler, void,
BluetoothStatus, BluetoothStatus>
BluetoothA2dpHALErrorRunnable;
static nsresult
DispatchBluetoothA2dpHALResult(
BluetoothA2dpResultHandler* aRes,
void (BluetoothA2dpResultHandler::*aMethod)(),
BluetoothStatus aStatus)
{
MOZ_ASSERT(aRes);
nsRunnable* runnable;
if (aStatus == STATUS_SUCCESS) {
runnable = new BluetoothA2dpHALResultRunnable(aRes, aMethod);
} else {
runnable = new BluetoothA2dpHALErrorRunnable(aRes,
&BluetoothA2dpResultHandler::OnError, aStatus);
}
nsresult rv = NS_DispatchToMainThread(runnable);
if (NS_FAILED(rv)) {
BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
}
return rv;
}
// Notification handling
//
static BluetoothA2dpNotificationHandler* sA2dpNotificationHandler;
struct BluetoothA2dpHALCallback
{
class A2dpNotificationHandlerWrapper
{
public:
typedef BluetoothA2dpNotificationHandler ObjectType;
static ObjectType* GetInstance()
{
MOZ_ASSERT(NS_IsMainThread());
return sA2dpNotificationHandler;
}
};
// Notifications
typedef BluetoothNotificationHALRunnable2<
A2dpNotificationHandlerWrapper, void,
BluetoothA2dpConnectionState, nsString,
BluetoothA2dpConnectionState, const nsAString&>
ConnectionStateNotification;
typedef BluetoothNotificationHALRunnable2<
A2dpNotificationHandlerWrapper, void,
BluetoothA2dpAudioState, nsString,
BluetoothA2dpAudioState, const nsAString&>
AudioStateNotification;
// Bluedroid A2DP callbacks
static void
ConnectionState(btav_connection_state_t aState, bt_bdaddr_t* aBdAddr)
{
ConnectionStateNotification::Dispatch(
&BluetoothA2dpNotificationHandler::ConnectionStateNotification,
aState, aBdAddr);
}
static void
AudioState(btav_audio_state_t aState, bt_bdaddr_t* aBdAddr)
{
AudioStateNotification::Dispatch(
&BluetoothA2dpNotificationHandler::AudioStateNotification,
aState, aBdAddr);
}
};
// Interface
//
BluetoothA2dpHALInterface::BluetoothA2dpHALInterface(
const btav_interface_t* aInterface)
: mInterface(aInterface)
{
MOZ_ASSERT(mInterface);
}
BluetoothA2dpHALInterface::~BluetoothA2dpHALInterface()
{ }
void
BluetoothA2dpHALInterface::Init(
BluetoothA2dpNotificationHandler* aNotificationHandler,
BluetoothA2dpResultHandler* aRes)
{
static btav_callbacks_t sCallbacks = {
sizeof(sCallbacks),
BluetoothA2dpHALCallback::ConnectionState,
BluetoothA2dpHALCallback::AudioState
};
sA2dpNotificationHandler = aNotificationHandler;
bt_status_t status = mInterface->init(&sCallbacks);
if (aRes) {
DispatchBluetoothA2dpHALResult(aRes,
&BluetoothA2dpResultHandler::Init,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothA2dpHALInterface::Cleanup(BluetoothA2dpResultHandler* aRes)
{
mInterface->cleanup();
if (aRes) {
DispatchBluetoothA2dpHALResult(aRes,
&BluetoothA2dpResultHandler::Cleanup,
STATUS_SUCCESS);
}
}
void
BluetoothA2dpHALInterface::Connect(const nsAString& aBdAddr,
BluetoothA2dpResultHandler* aRes)
{
bt_status_t status;
bt_bdaddr_t bdAddr;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
status = mInterface->connect(&bdAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothA2dpHALResult(
aRes, &BluetoothA2dpResultHandler::Connect,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothA2dpHALInterface::Disconnect(const nsAString& aBdAddr,
BluetoothA2dpResultHandler* aRes)
{
bt_status_t status;
bt_bdaddr_t bdAddr;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
status = mInterface->disconnect(&bdAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothA2dpHALResult(
aRes, &BluetoothA2dpResultHandler::Disconnect,
ConvertDefault(status, STATUS_FAIL));
}
}
END_BLUETOOTH_NAMESPACE

Просмотреть файл

@ -0,0 +1,44 @@
/* -*- 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/. */
#ifndef mozilla_dom_bluetooth_bluedroid_bluetootha2dphalinterface_h__
#define mozilla_dom_bluetooth_bluedroid_bluetootha2dphalinterface_h__
#include <hardware/bluetooth.h>
#include <hardware/bt_av.h>
#include "BluetoothCommon.h"
#include "BluetoothInterface.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothHALInterface;
class BluetoothA2dpHALInterface MOZ_FINAL
: public BluetoothA2dpInterface
{
public:
friend class BluetoothHALInterface;
void Init(BluetoothA2dpNotificationHandler* aNotificationHandler,
BluetoothA2dpResultHandler* aRes);
void Cleanup(BluetoothA2dpResultHandler* aRes);
void Connect(const nsAString& aBdAddr,
BluetoothA2dpResultHandler* aRes);
void Disconnect(const nsAString& aBdAddr,
BluetoothA2dpResultHandler* aRes);
protected:
BluetoothA2dpHALInterface(const btav_interface_t* aInterface);
~BluetoothA2dpHALInterface();
private:
const btav_interface_t* mInterface;
};
END_BLUETOOTH_NAMESPACE
#endif

Просмотреть файл

@ -0,0 +1,593 @@
/* -*- 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 "BluetoothAvrcpHALInterface.h"
#include "BluetoothHALHelpers.h"
BEGIN_BLUETOOTH_NAMESPACE
typedef
BluetoothHALInterfaceRunnable0<BluetoothAvrcpResultHandler, void>
BluetoothAvrcpHALResultRunnable;
typedef
BluetoothHALInterfaceRunnable1<BluetoothAvrcpResultHandler, void,
BluetoothStatus, BluetoothStatus>
BluetoothAvrcpHALErrorRunnable;
static nsresult
DispatchBluetoothAvrcpHALResult(
BluetoothAvrcpResultHandler* aRes,
void (BluetoothAvrcpResultHandler::*aMethod)(),
BluetoothStatus aStatus)
{
MOZ_ASSERT(aRes);
nsRunnable* runnable;
if (aStatus == STATUS_SUCCESS) {
runnable = new BluetoothAvrcpHALResultRunnable(aRes, aMethod);
} else {
runnable = new BluetoothAvrcpHALErrorRunnable(aRes,
&BluetoothAvrcpResultHandler::OnError, aStatus);
}
nsresult rv = NS_DispatchToMainThread(runnable);
if (NS_FAILED(rv)) {
BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
}
return rv;
}
// Notification handling
//
static BluetoothAvrcpNotificationHandler* sAvrcpNotificationHandler;
struct BluetoothAvrcpCallback
{
class AvrcpNotificationHandlerWrapper
{
public:
typedef BluetoothAvrcpNotificationHandler ObjectType;
static ObjectType* GetInstance()
{
MOZ_ASSERT(NS_IsMainThread());
return sAvrcpNotificationHandler;
}
};
// Notifications
typedef BluetoothNotificationHALRunnable0<AvrcpNotificationHandlerWrapper,
void>
GetPlayStatusNotification;
typedef BluetoothNotificationHALRunnable0<AvrcpNotificationHandlerWrapper,
void>
ListPlayerAppAttrNotification;
typedef BluetoothNotificationHALRunnable1<AvrcpNotificationHandlerWrapper,
void,
BluetoothAvrcpPlayerAttribute>
ListPlayerAppValuesNotification;
typedef BluetoothNotificationHALRunnable2<AvrcpNotificationHandlerWrapper, void,
uint8_t, nsAutoArrayPtr<BluetoothAvrcpPlayerAttribute>,
uint8_t, const BluetoothAvrcpPlayerAttribute*>
GetPlayerAppValueNotification;
typedef BluetoothNotificationHALRunnable2<AvrcpNotificationHandlerWrapper, void,
uint8_t, nsAutoArrayPtr<BluetoothAvrcpPlayerAttribute>,
uint8_t, const BluetoothAvrcpPlayerAttribute*>
GetPlayerAppAttrsTextNotification;
typedef BluetoothNotificationHALRunnable3<AvrcpNotificationHandlerWrapper,
void,
uint8_t, uint8_t,
nsAutoArrayPtr<uint8_t>,
uint8_t, uint8_t, const uint8_t*>
GetPlayerAppValuesTextNotification;
typedef BluetoothNotificationHALRunnable1<AvrcpNotificationHandlerWrapper,
void,
BluetoothAvrcpPlayerSettings,
const BluetoothAvrcpPlayerSettings&>
SetPlayerAppValueNotification;
typedef BluetoothNotificationHALRunnable2<AvrcpNotificationHandlerWrapper, void,
uint8_t, nsAutoArrayPtr<BluetoothAvrcpMediaAttribute>,
uint8_t, const BluetoothAvrcpMediaAttribute*>
GetElementAttrNotification;
typedef BluetoothNotificationHALRunnable2<AvrcpNotificationHandlerWrapper,
void,
BluetoothAvrcpEvent, uint32_t>
RegisterNotificationNotification;
typedef BluetoothNotificationHALRunnable2<AvrcpNotificationHandlerWrapper,
void,
nsString, unsigned long,
const nsAString&>
RemoteFeatureNotification;
typedef BluetoothNotificationHALRunnable2<AvrcpNotificationHandlerWrapper,
void,
uint8_t, uint8_t>
VolumeChangeNotification;
typedef BluetoothNotificationHALRunnable2<AvrcpNotificationHandlerWrapper,
void,
int, int>
PassthroughCmdNotification;
// Bluedroid AVRCP callbacks
#if ANDROID_VERSION >= 18
static void
GetPlayStatus()
{
GetPlayStatusNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::GetPlayStatusNotification);
}
static void
ListPlayerAppAttr()
{
ListPlayerAppAttrNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::ListPlayerAppAttrNotification);
}
static void
ListPlayerAppValues(btrc_player_attr_t aAttrId)
{
ListPlayerAppValuesNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::ListPlayerAppValuesNotification,
aAttrId);
}
static void
GetPlayerAppValue(uint8_t aNumAttrs, btrc_player_attr_t* aAttrs)
{
GetPlayerAppValueNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::GetPlayerAppValueNotification,
aNumAttrs, ConvertArray<btrc_player_attr_t>(aAttrs, aNumAttrs));
}
static void
GetPlayerAppAttrsText(uint8_t aNumAttrs, btrc_player_attr_t* aAttrs)
{
GetPlayerAppAttrsTextNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::GetPlayerAppAttrsTextNotification,
aNumAttrs, ConvertArray<btrc_player_attr_t>(aAttrs, aNumAttrs));
}
static void
GetPlayerAppValuesText(uint8_t aAttrId, uint8_t aNumVals, uint8_t* aVals)
{
GetPlayerAppValuesTextNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::GetPlayerAppValuesTextNotification,
aAttrId, aNumVals, ConvertArray<uint8_t>(aVals, aNumVals));
}
static void
SetPlayerAppValue(btrc_player_settings_t* aVals)
{
SetPlayerAppValueNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::SetPlayerAppValueNotification,
*aVals);
}
static void
GetElementAttr(uint8_t aNumAttrs, btrc_media_attr_t* aAttrs)
{
GetElementAttrNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::GetElementAttrNotification,
aNumAttrs, ConvertArray<btrc_media_attr_t>(aAttrs, aNumAttrs));
}
static void
RegisterNotification(btrc_event_id_t aEvent, uint32_t aParam)
{
RegisterNotificationNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::RegisterNotificationNotification,
aEvent, aParam);
}
#endif // ANDROID_VERSION >= 18
#if ANDROID_VERSION >= 19
static void
RemoteFeature(bt_bdaddr_t* aBdAddr, btrc_remote_features_t aFeatures)
{
RemoteFeatureNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::RemoteFeatureNotification,
aBdAddr, aFeatures);
}
static void
VolumeChange(uint8_t aVolume, uint8_t aCType)
{
VolumeChangeNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::VolumeChangeNotification,
aVolume, aCType);
}
static void
PassthroughCmd(int aId, int aKeyState)
{
PassthroughCmdNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::PassthroughCmdNotification,
aId, aKeyState);
}
#endif // ANDROID_VERSION >= 19
};
// Interface
//
BluetoothAvrcpHALInterface::BluetoothAvrcpHALInterface(
#if ANDROID_VERSION >= 18
const btrc_interface_t* aInterface
#endif
)
#if ANDROID_VERSION >= 18
: mInterface(aInterface)
#endif
{
#if ANDROID_VERSION >= 18
MOZ_ASSERT(mInterface);
#endif
}
BluetoothAvrcpHALInterface::~BluetoothAvrcpHALInterface()
{ }
void
BluetoothAvrcpHALInterface::Init(
BluetoothAvrcpNotificationHandler* aNotificationHandler,
BluetoothAvrcpResultHandler* aRes)
{
#if ANDROID_VERSION >= 18
static btrc_callbacks_t sCallbacks = {
sizeof(sCallbacks),
#if ANDROID_VERSION >= 19
BluetoothAvrcpCallback::RemoteFeature,
#endif
BluetoothAvrcpCallback::GetPlayStatus,
BluetoothAvrcpCallback::ListPlayerAppAttr,
BluetoothAvrcpCallback::ListPlayerAppValues,
BluetoothAvrcpCallback::GetPlayerAppValue,
BluetoothAvrcpCallback::GetPlayerAppAttrsText,
BluetoothAvrcpCallback::GetPlayerAppValuesText,
BluetoothAvrcpCallback::SetPlayerAppValue,
BluetoothAvrcpCallback::GetElementAttr,
BluetoothAvrcpCallback::RegisterNotification
#if ANDROID_VERSION >= 19
,
BluetoothAvrcpCallback::VolumeChange,
BluetoothAvrcpCallback::PassthroughCmd
#endif
};
#endif // ANDROID_VERSION >= 18
sAvrcpNotificationHandler = aNotificationHandler;
#if ANDROID_VERSION >= 18
bt_status_t status = mInterface->init(&sCallbacks);
#else
bt_status_t status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(aRes, &BluetoothAvrcpResultHandler::Init,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::Cleanup(BluetoothAvrcpResultHandler* aRes)
{
#if ANDROID_VERSION >= 18
mInterface->cleanup();
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(aRes,
&BluetoothAvrcpResultHandler::Cleanup, STATUS_SUCCESS);
}
}
void
BluetoothAvrcpHALInterface::GetPlayStatusRsp(
ControlPlayStatus aPlayStatus, uint32_t aSongLen, uint32_t aSongPos,
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
btrc_play_status_t playStatus = BTRC_PLAYSTATE_STOPPED;
if (!(NS_FAILED(Convert(aPlayStatus, playStatus)))) {
status = mInterface->get_play_status_rsp(playStatus, aSongLen, aSongPos);
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::GetPlayStatusRsp,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::ListPlayerAppAttrRsp(
int aNumAttr, const BluetoothAvrcpPlayerAttribute* aPAttrs,
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
ConvertArray<BluetoothAvrcpPlayerAttribute> pAttrsArray(aPAttrs, aNumAttr);
nsAutoArrayPtr<btrc_player_attr_t> pAttrs;
if (NS_SUCCEEDED(Convert(pAttrsArray, pAttrs))) {
status = mInterface->list_player_app_attr_rsp(aNumAttr, pAttrs);
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::ListPlayerAppAttrRsp,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::ListPlayerAppValueRsp(
int aNumVal, uint8_t* aPVals, BluetoothAvrcpResultHandler* aRes)
{
#if ANDROID_VERSION >= 18
bt_status_t status = mInterface->list_player_app_value_rsp(aNumVal, aPVals);
#else
bt_status_t status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::ListPlayerAppValueRsp,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::GetPlayerAppValueRsp(
uint8_t aNumAttrs, const uint8_t* aIds, const uint8_t* aValues,
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
btrc_player_settings_t pVals;
/* FIXME: you need to implement the missing conversion functions */
NS_NOTREACHED("Conversion function missing");
if (false /* TODO: we don't support any player app values currently */) {
status = mInterface->get_player_app_value_rsp(&pVals);
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::GetPlayerAppValueRsp,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::GetPlayerAppAttrTextRsp(
int aNumAttr, const uint8_t* aIds, const char** aTexts,
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
btrc_player_setting_text_t* aPAttrs;
/* FIXME: you need to implement the missing conversion functions */
NS_NOTREACHED("Conversion function missing");
if (false /* TODO: we don't support any attributes currently */) {
status = mInterface->get_player_app_attr_text_rsp(aNumAttr, aPAttrs);
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::GetPlayerAppAttrTextRsp,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::GetPlayerAppValueTextRsp(
int aNumVal, const uint8_t* aIds, const char** aTexts,
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
btrc_player_setting_text_t* pVals;
/* FIXME: you need to implement the missing conversion functions */
NS_NOTREACHED("Conversion function missing");
if (false /* TODO: we don't support any values currently */) {
status = mInterface->get_player_app_value_text_rsp(aNumVal, pVals);
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::GetPlayerAppValueTextRsp,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::GetElementAttrRsp(
uint8_t aNumAttr, const BluetoothAvrcpElementAttribute* aAttrs,
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
ConvertArray<BluetoothAvrcpElementAttribute> pAttrsArray(aAttrs, aNumAttr);
nsAutoArrayPtr<btrc_element_attr_val_t> pAttrs;
if (NS_SUCCEEDED(Convert(pAttrsArray, pAttrs))) {
status = mInterface->get_element_attr_rsp(aNumAttr, pAttrs);
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::GetElementAttrRsp,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::SetPlayerAppValueRsp(
BluetoothAvrcpStatus aRspStatus, BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
btrc_status_t rspStatus = BTRC_STS_BAD_CMD; // silences compiler warning
if (NS_SUCCEEDED(Convert(aRspStatus, rspStatus))) {
status = mInterface->set_player_app_value_rsp(rspStatus);
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::SetPlayerAppValueRsp,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::RegisterNotificationRsp(
BluetoothAvrcpEvent aEvent, BluetoothAvrcpNotification aType,
const BluetoothAvrcpNotificationParam& aParam,
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
nsresult rv;
btrc_event_id_t event = { };
btrc_notification_type_t type = BTRC_NOTIFICATION_TYPE_INTERIM;
btrc_register_notification_t param;
switch (aEvent) {
case AVRCP_EVENT_PLAY_STATUS_CHANGED:
rv = Convert(aParam.mPlayStatus, param.play_status);
break;
case AVRCP_EVENT_TRACK_CHANGE:
MOZ_ASSERT(sizeof(aParam.mTrack) == sizeof(param.track));
memcpy(param.track, aParam.mTrack, sizeof(param.track));
rv = NS_OK;
break;
case AVRCP_EVENT_TRACK_REACHED_END:
NS_NOTREACHED("Unknown conversion");
rv = NS_ERROR_ILLEGAL_VALUE;
break;
case AVRCP_EVENT_TRACK_REACHED_START:
NS_NOTREACHED("Unknown conversion");
rv = NS_ERROR_ILLEGAL_VALUE;
break;
case AVRCP_EVENT_PLAY_POS_CHANGED:
param.song_pos = aParam.mSongPos;
rv = NS_OK;
break;
case AVRCP_EVENT_APP_SETTINGS_CHANGED:
NS_NOTREACHED("Unknown conversion");
rv = NS_ERROR_ILLEGAL_VALUE;
break;
default:
NS_NOTREACHED("Unknown conversion");
rv = NS_ERROR_ILLEGAL_VALUE;
break;
}
if (NS_SUCCEEDED(rv) &&
NS_SUCCEEDED(Convert(aEvent, event)) &&
NS_SUCCEEDED(Convert(aType, type))) {
status = mInterface->register_notification_rsp(event, type, &param);
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::RegisterNotificationRsp,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::SetVolume(uint8_t aVolume,
BluetoothAvrcpResultHandler* aRes)
{
#if ANDROID_VERSION >= 19
bt_status_t status = mInterface->set_volume(aVolume);
#else
bt_status_t status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::SetVolume,
ConvertDefault(status, STATUS_FAIL));
}
}
END_BLUETOOTH_NAMESPACE

Просмотреть файл

@ -0,0 +1,84 @@
/* -*- 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/. */
#ifndef mozilla_dom_bluetooth_bluedroid_bluetoothavrcphalinterface_h__
#define mozilla_dom_bluetooth_bluedroid_bluetoothavrcphalinterface_h__
#include <hardware/bluetooth.h>
#if ANDROID_VERSION >= 18
#include <hardware/bt_rc.h>
#endif
#include "BluetoothCommon.h"
#include "BluetoothInterface.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothHALInterface;
class BluetoothAvrcpHALInterface MOZ_FINAL
: public BluetoothAvrcpInterface
{
public:
friend class BluetoothHALInterface;
void Init(BluetoothAvrcpNotificationHandler* aNotificationHandler,
BluetoothAvrcpResultHandler* aRes);
void Cleanup(BluetoothAvrcpResultHandler* aRes);
void GetPlayStatusRsp(ControlPlayStatus aPlayStatus,
uint32_t aSongLen, uint32_t aSongPos,
BluetoothAvrcpResultHandler* aRes);
void ListPlayerAppAttrRsp(int aNumAttr,
const BluetoothAvrcpPlayerAttribute* aPAttrs,
BluetoothAvrcpResultHandler* aRes);
void ListPlayerAppValueRsp(int aNumVal, uint8_t* aPVals,
BluetoothAvrcpResultHandler* aRes);
/* TODO: redesign this interface once we actually use it */
void GetPlayerAppValueRsp(uint8_t aNumAttrs,
const uint8_t* aIds, const uint8_t* aValues,
BluetoothAvrcpResultHandler* aRes);
/* TODO: redesign this interface once we actually use it */
void GetPlayerAppAttrTextRsp(int aNumAttr,
const uint8_t* aIds, const char** aTexts,
BluetoothAvrcpResultHandler* aRes);
/* TODO: redesign this interface once we actually use it */
void GetPlayerAppValueTextRsp(int aNumVal,
const uint8_t* aIds, const char** aTexts,
BluetoothAvrcpResultHandler* aRes);
void GetElementAttrRsp(uint8_t aNumAttr,
const BluetoothAvrcpElementAttribute* aAttr,
BluetoothAvrcpResultHandler* aRes);
void SetPlayerAppValueRsp(BluetoothAvrcpStatus aRspStatus,
BluetoothAvrcpResultHandler* aRes);
void RegisterNotificationRsp(BluetoothAvrcpEvent aEvent,
BluetoothAvrcpNotification aType,
const BluetoothAvrcpNotificationParam& aParam,
BluetoothAvrcpResultHandler* aRes);
void SetVolume(uint8_t aVolume, BluetoothAvrcpResultHandler* aRes);
protected:
BluetoothAvrcpHALInterface(
#if ANDROID_VERSION >= 18
const btrc_interface_t* aInterface
#endif
);
~BluetoothAvrcpHALInterface();
private:
#if ANDROID_VERSION >= 18
const btrc_interface_t* mInterface;
#endif
};
END_BLUETOOTH_NAMESPACE
#endif

Просмотреть файл

@ -0,0 +1,298 @@
/* -*- 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 "BluetoothHALHelpers.h"
#define MAX_UUID_SIZE 16
BEGIN_BLUETOOTH_NAMESPACE
//
// Conversion
//
nsresult
Convert(const nsAString& aIn, bt_property_type_t& aOut)
{
if (aIn.EqualsLiteral("Name")) {
aOut = BT_PROPERTY_BDNAME;
} else if (aIn.EqualsLiteral("Discoverable")) {
aOut = BT_PROPERTY_ADAPTER_SCAN_MODE;
} else if (aIn.EqualsLiteral("DiscoverableTimeout")) {
aOut = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT;
} else {
BT_LOGR("Invalid property name: %s", NS_ConvertUTF16toUTF8(aIn).get());
return NS_ERROR_ILLEGAL_VALUE;
}
return NS_OK;
}
nsresult
Convert(ConvertNamedValue& aIn, bt_property_t& aOut)
{
nsresult rv = Convert(aIn.mNamedValue.name(), aOut.type);
if (NS_FAILED(rv)) {
return rv;
}
if (aIn.mNamedValue.value().type() == BluetoothValue::Tuint32_t) {
// Set discoverable timeout
aOut.val =
reinterpret_cast<void*>(aIn.mNamedValue.value().get_uint32_t());
} else if (aIn.mNamedValue.value().type() == BluetoothValue::TnsString) {
// Set name
aIn.mStringValue =
NS_ConvertUTF16toUTF8(aIn.mNamedValue.value().get_nsString());
aOut.val =
const_cast<void*>(static_cast<const void*>(aIn.mStringValue.get()));
aOut.len = strlen(static_cast<char*>(aOut.val));
} else if (aIn.mNamedValue.value().type() == BluetoothValue::Tbool) {
// Set scan mode
rv = Convert(aIn.mNamedValue.value().get_bool(), aIn.mScanMode);
if (NS_FAILED(rv)) {
return rv;
}
aOut.val = &aIn.mScanMode;
aOut.len = sizeof(aIn.mScanMode);
} else {
BT_LOGR("Invalid property value type");
return NS_ERROR_ILLEGAL_VALUE;
}
return NS_OK;
}
nsresult
Convert(const nsAString& aIn, bt_bdaddr_t& aOut)
{
NS_ConvertUTF16toUTF8 bdAddressUTF8(aIn);
const char* str = bdAddressUTF8.get();
for (size_t i = 0; i < MOZ_ARRAY_LENGTH(aOut.address); ++i, ++str) {
aOut.address[i] =
static_cast<uint8_t>(strtoul(str, const_cast<char**>(&str), 16));
}
return NS_OK;
}
nsresult
Convert(const nsAString& aIn, bt_ssp_variant_t& aOut)
{
if (aIn.EqualsLiteral("PasskeyConfirmation")) {
aOut = BT_SSP_VARIANT_PASSKEY_CONFIRMATION;
} else if (aIn.EqualsLiteral("PasskeyEntry")) {
aOut = BT_SSP_VARIANT_PASSKEY_ENTRY;
} else if (aIn.EqualsLiteral("Consent")) {
aOut = BT_SSP_VARIANT_CONSENT;
} else if (aIn.EqualsLiteral("PasskeyNotification")) {
aOut = BT_SSP_VARIANT_PASSKEY_NOTIFICATION;
} else {
BT_LOGR("Invalid SSP variant name: %s", NS_ConvertUTF16toUTF8(aIn).get());
aOut = BT_SSP_VARIANT_PASSKEY_CONFIRMATION; // silences compiler warning
return NS_ERROR_ILLEGAL_VALUE;
}
return NS_OK;
}
nsresult
Convert(const uint8_t aIn[16], bt_uuid_t& aOut)
{
if (sizeof(aOut.uu) != 16) {
return NS_ERROR_ILLEGAL_VALUE;
}
memcpy(aOut.uu, aIn, sizeof(aOut.uu));
return NS_OK;
}
nsresult
Convert(const bt_uuid_t& aIn, BluetoothUuid& aOut)
{
if (sizeof(aIn.uu) != sizeof(aOut.mUuid)) {
return NS_ERROR_ILLEGAL_VALUE;
}
memcpy(aOut.mUuid, aIn.uu, sizeof(aOut.mUuid));
return NS_OK;
}
nsresult
Convert(const nsAString& aIn, bt_pin_code_t& aOut)
{
if (aIn.Length() > MOZ_ARRAY_LENGTH(aOut.pin)) {
return NS_ERROR_ILLEGAL_VALUE;
}
NS_ConvertUTF16toUTF8 pinCodeUTF8(aIn);
const char* str = pinCodeUTF8.get();
nsAString::size_type i;
// Fill pin into aOut
for (i = 0; i < aIn.Length(); ++i, ++str) {
aOut.pin[i] = static_cast<uint8_t>(*str);
}
// Clear remaining bytes in aOut
size_t ntrailing =
(MOZ_ARRAY_LENGTH(aOut.pin) - aIn.Length()) * sizeof(aOut.pin[0]);
memset(aOut.pin + aIn.Length(), 0, ntrailing);
return NS_OK;
}
nsresult
Convert(const bt_bdaddr_t& aIn, nsAString& aOut)
{
char str[BLUETOOTH_ADDRESS_LENGTH + 1];
int res = snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
static_cast<int>(aIn.address[0]),
static_cast<int>(aIn.address[1]),
static_cast<int>(aIn.address[2]),
static_cast<int>(aIn.address[3]),
static_cast<int>(aIn.address[4]),
static_cast<int>(aIn.address[5]));
if (res < 0) {
return NS_ERROR_ILLEGAL_VALUE;
} else if ((size_t)res >= sizeof(str)) {
return NS_ERROR_OUT_OF_MEMORY; /* string buffer too small */
}
aOut = NS_ConvertUTF8toUTF16(str);
return NS_OK;
}
nsresult
Convert(const bt_service_record_t& aIn, BluetoothServiceRecord& aOut)
{
nsresult rv = Convert(aIn.uuid, aOut.mUuid);
if (NS_FAILED(rv)) {
return rv;
}
aOut.mChannel = aIn.channel;
MOZ_ASSERT(sizeof(aIn.name) == sizeof(aOut.mName));
memcpy(aOut.mName, aIn.name, sizeof(aOut.mName));
return NS_OK;
}
#if ANDROID_VERSION >= 18
nsresult
Convert(const BluetoothAvrcpElementAttribute& aIn, btrc_element_attr_val_t& aOut)
{
const NS_ConvertUTF16toUTF8 value(aIn.mValue);
size_t len = std::min<size_t>(strlen(value.get()), sizeof(aOut.text) - 1);
memcpy(aOut.text, value.get(), len);
aOut.text[len] = '\0';
aOut.attr_id = aIn.mId;
return NS_OK;
}
nsresult
Convert(const btrc_player_settings_t& aIn, BluetoothAvrcpPlayerSettings& aOut)
{
aOut.mNumAttr = aIn.num_attr;
memcpy(aOut.mIds, aIn.attr_ids, aIn.num_attr);
memcpy(aOut.mValues, aIn.attr_values, aIn.num_attr);
return NS_OK;
}
#endif // ANDROID_VERSION >= 18
nsresult
Convert(const bt_property_t& aIn, BluetoothProperty& aOut)
{
/* type conversion */
nsresult rv = Convert(aIn.type, aOut.mType);
if (NS_FAILED(rv)) {
return rv;
}
/* value conversion */
switch (aOut.mType) {
case PROPERTY_BDNAME:
/* fall through */
case PROPERTY_REMOTE_FRIENDLY_NAME:
{
// We construct an nsCString here because bdname
// returned from Bluedroid is not 0-terminated.
aOut.mString = NS_ConvertUTF8toUTF16(
nsCString(static_cast<char*>(aIn.val), aIn.len));
}
break;
case PROPERTY_BDADDR:
rv = Convert(*static_cast<bt_bdaddr_t*>(aIn.val), aOut.mString);
break;
case PROPERTY_UUIDS:
{
size_t numUuids = aIn.len / MAX_UUID_SIZE;
ConvertArray<bt_uuid_t> array(
static_cast<bt_uuid_t*>(aIn.val), numUuids);
aOut.mUuidArray.SetLength(numUuids);
rv = Convert(array, aOut.mUuidArray);
}
break;
case PROPERTY_CLASS_OF_DEVICE:
/* fall through */
case PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
aOut.mUint32 = *static_cast<uint32_t*>(aIn.val);
break;
case PROPERTY_TYPE_OF_DEVICE:
rv = Convert(*static_cast<bt_device_type_t*>(aIn.val),
aOut.mDeviceType);
break;
case PROPERTY_SERVICE_RECORD:
rv = Convert(*static_cast<bt_service_record_t*>(aIn.val),
aOut.mServiceRecord);
break;
case PROPERTY_ADAPTER_SCAN_MODE:
rv = Convert(*static_cast<bt_scan_mode_t*>(aIn.val),
aOut.mScanMode);
break;
case PROPERTY_ADAPTER_BONDED_DEVICES:
{
size_t numAddresses = aIn.len / BLUETOOTH_ADDRESS_BYTES;
ConvertArray<bt_bdaddr_t> array(
static_cast<bt_bdaddr_t*>(aIn.val), numAddresses);
aOut.mStringArray.SetLength(numAddresses);
rv = Convert(array, aOut.mStringArray);
}
break;
case PROPERTY_REMOTE_RSSI:
aOut.mInt32 = *static_cast<int32_t*>(aIn.val);
break;
#if ANDROID_VERSION >= 18
case PROPERTY_REMOTE_VERSION_INFO:
rv = Convert(*static_cast<bt_remote_version_t*>(aIn.val),
aOut.mRemoteInfo);
break;
#endif
case PROPERTY_REMOTE_DEVICE_TIMESTAMP:
/* nothing to do */
break;
default:
/* mismatch with type conversion */
NS_NOTREACHED("Unhandled property type");
break;
}
if (NS_FAILED(rv)) {
return rv;
}
return NS_OK;
}
END_BLUETOOTH_NAMESPACE

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,913 @@
/* -*- 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 "BluetoothHALInterface.h"
#include "BluetoothHALHelpers.h"
#include "BluetoothA2dpHALInterface.h"
#include "BluetoothAvrcpHALInterface.h"
#include "BluetoothHandsfreeHALInterface.h"
#include "BluetoothSocketHALInterface.h"
BEGIN_BLUETOOTH_NAMESPACE
template<class T>
struct interface_traits
{ };
template<>
struct interface_traits<BluetoothSocketHALInterface>
{
typedef const btsock_interface_t const_interface_type;
static const char* profile_id()
{
return BT_PROFILE_SOCKETS_ID;
}
};
template<>
struct interface_traits<BluetoothHandsfreeHALInterface>
{
typedef const bthf_interface_t const_interface_type;
static const char* profile_id()
{
return BT_PROFILE_HANDSFREE_ID;
}
};
template<>
struct interface_traits<BluetoothA2dpHALInterface>
{
typedef const btav_interface_t const_interface_type;
static const char* profile_id()
{
return BT_PROFILE_ADVANCED_AUDIO_ID;
}
};
#if ANDROID_VERSION >= 18
template<>
struct interface_traits<BluetoothAvrcpHALInterface>
{
typedef const btrc_interface_t const_interface_type;
static const char* profile_id()
{
return BT_PROFILE_AV_RC_ID;
}
};
#endif
typedef
BluetoothHALInterfaceRunnable0<BluetoothResultHandler, void>
BluetoothHALResultRunnable;
typedef
BluetoothHALInterfaceRunnable1<BluetoothResultHandler, void,
BluetoothStatus, BluetoothStatus>
BluetoothHALErrorRunnable;
static nsresult
DispatchBluetoothHALResult(BluetoothResultHandler* aRes,
void (BluetoothResultHandler::*aMethod)(),
BluetoothStatus aStatus)
{
MOZ_ASSERT(aRes);
nsRunnable* runnable;
if (aStatus == STATUS_SUCCESS) {
runnable = new BluetoothHALResultRunnable(aRes, aMethod);
} else {
runnable = new BluetoothHALErrorRunnable(
aRes, &BluetoothResultHandler::OnError, aStatus);
}
nsresult rv = NS_DispatchToMainThread(runnable);
if (NS_FAILED(rv)) {
BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
}
return rv;
}
// Notification handling
//
static BluetoothNotificationHandler* sNotificationHandler;
struct BluetoothCallback
{
class NotificationHandlerWrapper
{
public:
typedef BluetoothNotificationHandler ObjectType;
static ObjectType* GetInstance()
{
MOZ_ASSERT(NS_IsMainThread());
return sNotificationHandler;
}
};
// Notifications
typedef BluetoothNotificationHALRunnable1<NotificationHandlerWrapper, void,
bool>
AdapterStateChangedNotification;
typedef BluetoothNotificationHALRunnable3<NotificationHandlerWrapper, void,
BluetoothStatus, int,
nsAutoArrayPtr<BluetoothProperty>,
BluetoothStatus, int,
const BluetoothProperty*>
AdapterPropertiesNotification;
typedef BluetoothNotificationHALRunnable4<NotificationHandlerWrapper, void,
BluetoothStatus, nsString, int,
nsAutoArrayPtr<BluetoothProperty>,
BluetoothStatus, const nsAString&,
int, const BluetoothProperty*>
RemoteDevicePropertiesNotification;
typedef BluetoothNotificationHALRunnable2<NotificationHandlerWrapper, void,
int,
nsAutoArrayPtr<BluetoothProperty>,
int, const BluetoothProperty*>
DeviceFoundNotification;
typedef BluetoothNotificationHALRunnable1<NotificationHandlerWrapper, void,
bool>
DiscoveryStateChangedNotification;
typedef BluetoothNotificationHALRunnable3<NotificationHandlerWrapper, void,
nsString, nsString, uint32_t,
const nsAString&, const nsAString&>
PinRequestNotification;
typedef BluetoothNotificationHALRunnable5<NotificationHandlerWrapper, void,
nsString, nsString, uint32_t,
nsString, uint32_t,
const nsAString&, const nsAString&,
uint32_t, const nsAString&>
SspRequestNotification;
typedef BluetoothNotificationHALRunnable3<NotificationHandlerWrapper, void,
BluetoothStatus, nsString,
BluetoothBondState,
BluetoothStatus, const nsAString&>
BondStateChangedNotification;
typedef BluetoothNotificationHALRunnable3<NotificationHandlerWrapper, void,
BluetoothStatus, nsString, bool,
BluetoothStatus, const nsAString&>
AclStateChangedNotification;
typedef BluetoothNotificationHALRunnable3<NotificationHandlerWrapper, void,
uint16_t, nsAutoArrayPtr<uint8_t>,
uint8_t, uint16_t, const uint8_t*>
DutModeRecvNotification;
typedef BluetoothNotificationHALRunnable2<NotificationHandlerWrapper, void,
BluetoothStatus, uint16_t>
LeTestModeNotification;
// Bluedroid callbacks
static const bt_property_t*
AlignedProperties(bt_property_t* aProperties, size_t aNumProperties,
nsAutoArrayPtr<bt_property_t>& aPropertiesArray)
{
// See Bug 989976: consider aProperties address is not aligned. If
// it is aligned, we return the pointer directly; otherwise we make
// an aligned copy. The argument |aPropertiesArray| keeps track of
// the memory buffer.
if (!(reinterpret_cast<uintptr_t>(aProperties) % sizeof(void*))) {
return aProperties;
}
bt_property_t* properties = new bt_property_t[aNumProperties];
memcpy(properties, aProperties, aNumProperties * sizeof(*properties));
aPropertiesArray = properties;
return properties;
}
static void
AdapterStateChanged(bt_state_t aStatus)
{
AdapterStateChangedNotification::Dispatch(
&BluetoothNotificationHandler::AdapterStateChangedNotification,
aStatus);
}
static void
AdapterProperties(bt_status_t aStatus, int aNumProperties,
bt_property_t* aProperties)
{
nsAutoArrayPtr<bt_property_t> propertiesArray;
AdapterPropertiesNotification::Dispatch(
&BluetoothNotificationHandler::AdapterPropertiesNotification,
ConvertDefault(aStatus, STATUS_FAIL), aNumProperties,
ConvertArray<bt_property_t>(
AlignedProperties(aProperties, aNumProperties, propertiesArray),
aNumProperties));
}
static void
RemoteDeviceProperties(bt_status_t aStatus, bt_bdaddr_t* aBdAddress,
int aNumProperties, bt_property_t* aProperties)
{
nsAutoArrayPtr<bt_property_t> propertiesArray;
RemoteDevicePropertiesNotification::Dispatch(
&BluetoothNotificationHandler::RemoteDevicePropertiesNotification,
ConvertDefault(aStatus, STATUS_FAIL), aBdAddress, aNumProperties,
ConvertArray<bt_property_t>(
AlignedProperties(aProperties, aNumProperties, propertiesArray),
aNumProperties));
}
static void
DeviceFound(int aNumProperties, bt_property_t* aProperties)
{
nsAutoArrayPtr<bt_property_t> propertiesArray;
DeviceFoundNotification::Dispatch(
&BluetoothNotificationHandler::DeviceFoundNotification,
aNumProperties,
ConvertArray<bt_property_t>(
AlignedProperties(aProperties, aNumProperties, propertiesArray),
aNumProperties));
}
static void
DiscoveryStateChanged(bt_discovery_state_t aState)
{
DiscoveryStateChangedNotification::Dispatch(
&BluetoothNotificationHandler::DiscoveryStateChangedNotification,
aState);
}
static void
PinRequest(bt_bdaddr_t* aRemoteBdAddress,
bt_bdname_t* aRemoteBdName, uint32_t aRemoteClass)
{
PinRequestNotification::Dispatch(
&BluetoothNotificationHandler::PinRequestNotification,
aRemoteBdAddress, aRemoteBdName, aRemoteClass);
}
static void
SspRequest(bt_bdaddr_t* aRemoteBdAddress, bt_bdname_t* aRemoteBdName,
uint32_t aRemoteClass, bt_ssp_variant_t aPairingVariant,
uint32_t aPasskey)
{
SspRequestNotification::Dispatch(
&BluetoothNotificationHandler::SspRequestNotification,
aRemoteBdAddress, aRemoteBdName, aRemoteClass,
aPairingVariant, aPasskey);
}
static void
BondStateChanged(bt_status_t aStatus, bt_bdaddr_t* aRemoteBdAddress,
bt_bond_state_t aState)
{
BondStateChangedNotification::Dispatch(
&BluetoothNotificationHandler::BondStateChangedNotification,
aStatus, aRemoteBdAddress, aState);
}
static void
AclStateChanged(bt_status_t aStatus, bt_bdaddr_t* aRemoteBdAddress,
bt_acl_state_t aState)
{
AclStateChangedNotification::Dispatch(
&BluetoothNotificationHandler::AclStateChangedNotification,
aStatus, aRemoteBdAddress, aState);
}
static void
ThreadEvt(bt_cb_thread_evt evt)
{
// This callback maintains internal state and is not exported.
}
static void
DutModeRecv(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen)
{
DutModeRecvNotification::Dispatch(
&BluetoothNotificationHandler::DutModeRecvNotification,
aOpcode, ConvertArray<uint8_t>(aBuf, aLen), aLen);
}
static void
LeTestMode(bt_status_t aStatus, uint16_t aNumPackets)
{
LeTestModeNotification::Dispatch(
&BluetoothNotificationHandler::LeTestModeNotification,
aStatus, aNumPackets);
}
};
// Interface
//
/* returns the container structure of a variable; _t is the container's
* type, _v the name of the variable, and _m is _v's field within _t
*/
#define container(_t, _v, _m) \
( (_t*)( ((const unsigned char*)(_v)) - offsetof(_t, _m) ) )
BluetoothHALInterface*
BluetoothHALInterface::GetInstance()
{
static BluetoothHALInterface* sBluetoothInterface;
if (sBluetoothInterface) {
return sBluetoothInterface;
}
/* get driver module */
const hw_module_t* module;
int err = hw_get_module(BT_HARDWARE_MODULE_ID, &module);
if (err) {
BT_WARNING("hw_get_module failed: %s", strerror(err));
return nullptr;
}
/* get device */
hw_device_t* device;
err = module->methods->open(module, BT_HARDWARE_MODULE_ID, &device);
if (err) {
BT_WARNING("open failed: %s", strerror(err));
return nullptr;
}
const bluetooth_device_t* bt_device =
container(bluetooth_device_t, device, common);
/* get interface */
const bt_interface_t* bt_interface = bt_device->get_bluetooth_interface();
if (!bt_interface) {
BT_WARNING("get_bluetooth_interface failed");
goto err_get_bluetooth_interface;
}
if (bt_interface->size != sizeof(*bt_interface)) {
BT_WARNING("interface of incorrect size");
goto err_bt_interface_size;
}
sBluetoothInterface = new BluetoothHALInterface(bt_interface);
return sBluetoothInterface;
err_bt_interface_size:
err_get_bluetooth_interface:
err = device->close(device);
if (err) {
BT_WARNING("close failed: %s", strerror(err));
}
return nullptr;
}
BluetoothHALInterface::BluetoothHALInterface(
const bt_interface_t* aInterface)
: mInterface(aInterface)
{
MOZ_ASSERT(mInterface);
}
BluetoothHALInterface::~BluetoothHALInterface()
{ }
void
BluetoothHALInterface::Init(
BluetoothNotificationHandler* aNotificationHandler,
BluetoothResultHandler* aRes)
{
static bt_callbacks_t sBluetoothCallbacks = {
sizeof(sBluetoothCallbacks),
BluetoothCallback::AdapterStateChanged,
BluetoothCallback::AdapterProperties,
BluetoothCallback::RemoteDeviceProperties,
BluetoothCallback::DeviceFound,
BluetoothCallback::DiscoveryStateChanged,
BluetoothCallback::PinRequest,
BluetoothCallback::SspRequest,
BluetoothCallback::BondStateChanged,
BluetoothCallback::AclStateChanged,
BluetoothCallback::ThreadEvt,
BluetoothCallback::DutModeRecv,
#if ANDROID_VERSION >= 18
BluetoothCallback::LeTestMode
#endif
};
sNotificationHandler = aNotificationHandler;
int status = mInterface->init(&sBluetoothCallbacks);
if (aRes) {
DispatchBluetoothHALResult(aRes, &BluetoothResultHandler::Init,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::Cleanup(BluetoothResultHandler* aRes)
{
mInterface->cleanup();
if (aRes) {
DispatchBluetoothHALResult(aRes, &BluetoothResultHandler::Cleanup,
STATUS_SUCCESS);
}
sNotificationHandler = nullptr;
}
void
BluetoothHALInterface::Enable(BluetoothResultHandler* aRes)
{
int status = mInterface->enable();
if (aRes) {
DispatchBluetoothHALResult(aRes, &BluetoothResultHandler::Enable,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::Disable(BluetoothResultHandler* aRes)
{
int status = mInterface->disable();
if (aRes) {
DispatchBluetoothHALResult(aRes, &BluetoothResultHandler::Disable,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Adapter Properties */
void
BluetoothHALInterface::GetAdapterProperties(BluetoothResultHandler* aRes)
{
int status = mInterface->get_adapter_properties();
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::GetAdapterProperties,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::GetAdapterProperty(const nsAString& aName,
BluetoothResultHandler* aRes)
{
int status;
bt_property_type_t type;
/* FIXME: you need to implement the missing conversion functions */
NS_NOTREACHED("Conversion function missing");
if (false /* TODO: we don't support any values for aName currently */) {
status = mInterface->get_adapter_property(type);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::GetAdapterProperties,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::SetAdapterProperty(
const BluetoothNamedValue& aProperty, BluetoothResultHandler* aRes)
{
int status;
ConvertNamedValue convertProperty(aProperty);
bt_property_t property;
if (NS_SUCCEEDED(Convert(convertProperty, property))) {
status = mInterface->set_adapter_property(&property);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::SetAdapterProperty,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Remote Device Properties */
void
BluetoothHALInterface::GetRemoteDeviceProperties(
const nsAString& aRemoteAddr, BluetoothResultHandler* aRes)
{
int status;
bt_bdaddr_t addr;
if (NS_SUCCEEDED(Convert(aRemoteAddr, addr))) {
status = mInterface->get_remote_device_properties(&addr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::GetRemoteDeviceProperties,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::GetRemoteDeviceProperty(
const nsAString& aRemoteAddr, const nsAString& aName,
BluetoothResultHandler* aRes)
{
int status;
bt_bdaddr_t remoteAddr;
bt_property_type_t name;
/* FIXME: you need to implement the missing conversion functions */
NS_NOTREACHED("Conversion function missing");
if (NS_SUCCEEDED(Convert(aRemoteAddr, remoteAddr)) &&
false /* TODO: we don't support any values for aName currently */) {
status = mInterface->get_remote_device_property(&remoteAddr, name);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::GetRemoteDeviceProperty,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::SetRemoteDeviceProperty(
const nsAString& aRemoteAddr, const BluetoothNamedValue& aProperty,
BluetoothResultHandler* aRes)
{
int status;
bt_bdaddr_t remoteAddr;
bt_property_t property;
/* FIXME: you need to implement the missing conversion functions */
NS_NOTREACHED("Conversion function missing");
if (NS_SUCCEEDED(Convert(aRemoteAddr, remoteAddr)) &&
false /* TODO: we don't support any values for aProperty currently */) {
status = mInterface->set_remote_device_property(&remoteAddr, &property);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::SetRemoteDeviceProperty,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Remote Services */
void
BluetoothHALInterface::GetRemoteServiceRecord(const nsAString& aRemoteAddr,
const uint8_t aUuid[16],
BluetoothResultHandler* aRes)
{
int status;
bt_bdaddr_t remoteAddr;
bt_uuid_t uuid;
if (NS_SUCCEEDED(Convert(aRemoteAddr, remoteAddr)) &&
NS_SUCCEEDED(Convert(aUuid, uuid))) {
status = mInterface->get_remote_service_record(&remoteAddr, &uuid);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::GetRemoteServiceRecord,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::GetRemoteServices(const nsAString& aRemoteAddr,
BluetoothResultHandler* aRes)
{
int status;
bt_bdaddr_t remoteAddr;
if (NS_SUCCEEDED(Convert(aRemoteAddr, remoteAddr))) {
status = mInterface->get_remote_services(&remoteAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::GetRemoteServices,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Discovery */
void
BluetoothHALInterface::StartDiscovery(BluetoothResultHandler* aRes)
{
int status = mInterface->start_discovery();
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::StartDiscovery,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::CancelDiscovery(BluetoothResultHandler* aRes)
{
int status = mInterface->cancel_discovery();
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::CancelDiscovery,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Bonds */
void
BluetoothHALInterface::CreateBond(const nsAString& aBdAddr,
BluetoothResultHandler* aRes)
{
bt_bdaddr_t bdAddr;
int status;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
status = mInterface->create_bond(&bdAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::CreateBond,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::RemoveBond(const nsAString& aBdAddr,
BluetoothResultHandler* aRes)
{
bt_bdaddr_t bdAddr;
int status;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
status = mInterface->remove_bond(&bdAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::RemoveBond,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::CancelBond(const nsAString& aBdAddr,
BluetoothResultHandler* aRes)
{
bt_bdaddr_t bdAddr;
int status;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
status = mInterface->cancel_bond(&bdAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::CancelBond,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Authentication */
void
BluetoothHALInterface::PinReply(const nsAString& aBdAddr, bool aAccept,
const nsAString& aPinCode,
BluetoothResultHandler* aRes)
{
int status;
bt_bdaddr_t bdAddr;
uint8_t accept;
bt_pin_code_t pinCode;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr)) &&
NS_SUCCEEDED(Convert(aAccept, accept)) &&
NS_SUCCEEDED(Convert(aPinCode, pinCode))) {
status = mInterface->pin_reply(&bdAddr, accept, aPinCode.Length(),
&pinCode);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::PinReply,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::SspReply(const nsAString& aBdAddr,
const nsAString& aVariant,
bool aAccept, uint32_t aPasskey,
BluetoothResultHandler* aRes)
{
int status;
bt_bdaddr_t bdAddr;
bt_ssp_variant_t variant;
uint8_t accept;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr)) &&
NS_SUCCEEDED(Convert(aVariant, variant)) &&
NS_SUCCEEDED(Convert(aAccept, accept))) {
status = mInterface->ssp_reply(&bdAddr, variant, accept, aPasskey);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::SspReply,
ConvertDefault(status, STATUS_FAIL));
}
}
/* DUT Mode */
void
BluetoothHALInterface::DutModeConfigure(bool aEnable,
BluetoothResultHandler* aRes)
{
int status;
uint8_t enable;
if (NS_SUCCEEDED(Convert(aEnable, enable))) {
status = mInterface->dut_mode_configure(enable);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::DutModeConfigure,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::DutModeSend(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
BluetoothResultHandler* aRes)
{
int status = mInterface->dut_mode_send(aOpcode, aBuf, aLen);
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::DutModeSend,
ConvertDefault(status, STATUS_FAIL));
}
}
/* LE Mode */
void
BluetoothHALInterface::LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
BluetoothResultHandler* aRes)
{
#if ANDROID_VERSION >= 18
int status = mInterface->le_test_mode(aOpcode, aBuf, aLen);
#else
int status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::LeTestMode,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Profile Interfaces */
template <class T>
T*
BluetoothHALInterface::CreateProfileInterface()
{
typename interface_traits<T>::const_interface_type* interface =
reinterpret_cast<typename interface_traits<T>::const_interface_type*>(
mInterface->get_profile_interface(interface_traits<T>::profile_id()));
if (!interface) {
BT_WARNING("Bluetooth profile '%s' is not supported",
interface_traits<T>::profile_id());
return nullptr;
}
if (interface->size != sizeof(*interface)) {
BT_WARNING("interface of incorrect size");
return nullptr;
}
return new T(interface);
}
#if ANDROID_VERSION < 18
/*
* Bluedroid versions that don't support AVRCP will call this function
* to create an AVRCP interface. All interface methods will fail with
* the error constant STATUS_UNSUPPORTED.
*/
template <>
BluetoothAvrcpHALInterface*
BluetoothHALInterface::CreateProfileInterface<BluetoothAvrcpHALInterface>()
{
BT_WARNING("Bluetooth profile 'avrcp' is not supported");
return new BluetoothAvrcpHALInterface();
}
#endif
template <class T>
T*
BluetoothHALInterface::GetProfileInterface()
{
static T* sBluetoothProfileInterface;
if (sBluetoothProfileInterface) {
return sBluetoothProfileInterface;
}
sBluetoothProfileInterface = CreateProfileInterface<T>();
return sBluetoothProfileInterface;
}
BluetoothSocketInterface*
BluetoothHALInterface::GetBluetoothSocketInterface()
{
return GetProfileInterface<BluetoothSocketHALInterface>();
}
BluetoothHandsfreeInterface*
BluetoothHALInterface::GetBluetoothHandsfreeInterface()
{
return GetProfileInterface<BluetoothHandsfreeHALInterface>();
}
BluetoothA2dpInterface*
BluetoothHALInterface::GetBluetoothA2dpInterface()
{
return GetProfileInterface<BluetoothA2dpHALInterface>();
}
BluetoothAvrcpInterface*
BluetoothHALInterface::GetBluetoothAvrcpInterface()
{
return GetProfileInterface<BluetoothAvrcpHALInterface>();
}
END_BLUETOOTH_NAMESPACE

Просмотреть файл

@ -0,0 +1,110 @@
/* -*- 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/. */
#ifndef mozilla_dom_bluetooth_bluedroid_bluetoothhalinterface_h__
#define mozilla_dom_bluetooth_bluedroid_bluetoothhalinterface_h__
#include <hardware/bluetooth.h>
#include "BluetoothInterface.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothHALInterface MOZ_FINAL : public BluetoothInterface
{
public:
static BluetoothHALInterface* GetInstance();
void Init(BluetoothNotificationHandler* aNotificationHandler,
BluetoothResultHandler* aRes);
void Cleanup(BluetoothResultHandler* aRes);
void Enable(BluetoothResultHandler* aRes);
void Disable(BluetoothResultHandler* aRes);
/* Adapter Properties */
void GetAdapterProperties(BluetoothResultHandler* aRes);
void GetAdapterProperty(const nsAString& aName,
BluetoothResultHandler* aRes);
void SetAdapterProperty(const BluetoothNamedValue& aProperty,
BluetoothResultHandler* aRes);
/* Remote Device Properties */
void GetRemoteDeviceProperties(const nsAString& aRemoteAddr,
BluetoothResultHandler* aRes);
void GetRemoteDeviceProperty(const nsAString& aRemoteAddr,
const nsAString& aName,
BluetoothResultHandler* aRes);
void SetRemoteDeviceProperty(const nsAString& aRemoteAddr,
const BluetoothNamedValue& aProperty,
BluetoothResultHandler* aRes);
/* Remote Services */
void GetRemoteServiceRecord(const nsAString& aRemoteAddr,
const uint8_t aUuid[16],
BluetoothResultHandler* aRes);
void GetRemoteServices(const nsAString& aRemoteAddr,
BluetoothResultHandler* aRes);
/* Discovery */
void StartDiscovery(BluetoothResultHandler* aRes);
void CancelDiscovery(BluetoothResultHandler* aRes);
/* Bonds */
void CreateBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes);
void RemoveBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes);
void CancelBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes);
/* Authentication */
void PinReply(const nsAString& aBdAddr, bool aAccept,
const nsAString& aPinCode,
BluetoothResultHandler* aRes);
void SspReply(const nsAString& aBdAddr, const nsAString& aVariant,
bool aAccept, uint32_t aPasskey,
BluetoothResultHandler* aRes);
/* DUT Mode */
void DutModeConfigure(bool aEnable, BluetoothResultHandler* aRes);
void DutModeSend(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
BluetoothResultHandler* aRes);
/* LE Mode */
void LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
BluetoothResultHandler* aRes);
/* Profile Interfaces */
BluetoothSocketInterface* GetBluetoothSocketInterface();
BluetoothHandsfreeInterface* GetBluetoothHandsfreeInterface();
BluetoothA2dpInterface* GetBluetoothA2dpInterface();
BluetoothAvrcpInterface* GetBluetoothAvrcpInterface();
protected:
BluetoothHALInterface(const bt_interface_t* aInterface);
~BluetoothHALInterface();
private:
template <class T>
T* CreateProfileInterface();
template <class T>
T* GetProfileInterface();
const bt_interface_t* mInterface;
};
END_BLUETOOTH_NAMESPACE
#endif

Просмотреть файл

@ -0,0 +1,616 @@
/* -*- 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 "BluetoothHandsfreeHALInterface.h"
#include "BluetoothHALHelpers.h"
BEGIN_BLUETOOTH_NAMESPACE
typedef
BluetoothHALInterfaceRunnable0<BluetoothHandsfreeResultHandler, void>
BluetoothHandsfreeHALResultRunnable;
typedef
BluetoothHALInterfaceRunnable1<BluetoothHandsfreeResultHandler, void,
BluetoothStatus, BluetoothStatus>
BluetoothHandsfreeHALErrorRunnable;
static nsresult
DispatchBluetoothHandsfreeHALResult(
BluetoothHandsfreeResultHandler* aRes,
void (BluetoothHandsfreeResultHandler::*aMethod)(),
BluetoothStatus aStatus)
{
MOZ_ASSERT(aRes);
nsRunnable* runnable;
if (aStatus == STATUS_SUCCESS) {
runnable = new BluetoothHandsfreeHALResultRunnable(aRes, aMethod);
} else {
runnable = new BluetoothHandsfreeHALErrorRunnable(aRes,
&BluetoothHandsfreeResultHandler::OnError, aStatus);
}
nsresult rv = NS_DispatchToMainThread(runnable);
if (NS_FAILED(rv)) {
BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
}
return rv;
}
// Notification handling
//
static BluetoothHandsfreeNotificationHandler* sHandsfreeNotificationHandler;
struct BluetoothHandsfreeHALCallback
{
class HandsfreeNotificationHandlerWrapper
{
public:
typedef BluetoothHandsfreeNotificationHandler ObjectType;
static ObjectType* GetInstance()
{
MOZ_ASSERT(NS_IsMainThread());
return sHandsfreeNotificationHandler;
}
};
// Notifications
typedef BluetoothNotificationHALRunnable2<
HandsfreeNotificationHandlerWrapper, void,
BluetoothHandsfreeConnectionState, nsString,
BluetoothHandsfreeConnectionState, const nsAString&>
ConnectionStateNotification;
typedef BluetoothNotificationHALRunnable2<
HandsfreeNotificationHandlerWrapper, void,
BluetoothHandsfreeAudioState, nsString,
BluetoothHandsfreeAudioState, const nsAString&>
AudioStateNotification;
typedef BluetoothNotificationHALRunnable1<
HandsfreeNotificationHandlerWrapper, void,
BluetoothHandsfreeVoiceRecognitionState>
VoiceRecognitionNotification;
typedef BluetoothNotificationHALRunnable0<
HandsfreeNotificationHandlerWrapper, void>
AnswerCallNotification;
typedef BluetoothNotificationHALRunnable0<
HandsfreeNotificationHandlerWrapper, void>
HangupCallNotification;
typedef BluetoothNotificationHALRunnable2<
HandsfreeNotificationHandlerWrapper, void,
BluetoothHandsfreeVolumeType, int>
VolumeNotification;
typedef BluetoothNotificationHALRunnable1<
HandsfreeNotificationHandlerWrapper, void, nsString, const nsAString&>
DialCallNotification;
typedef BluetoothNotificationHALRunnable1<
HandsfreeNotificationHandlerWrapper, void, char>
DtmfNotification;
typedef BluetoothNotificationHALRunnable1<
HandsfreeNotificationHandlerWrapper, void, BluetoothHandsfreeNRECState>
NRECNotification;
typedef BluetoothNotificationHALRunnable1<
HandsfreeNotificationHandlerWrapper, void, BluetoothHandsfreeCallHoldType>
CallHoldNotification;
typedef BluetoothNotificationHALRunnable0<
HandsfreeNotificationHandlerWrapper, void>
CnumNotification;
typedef BluetoothNotificationHALRunnable0<
HandsfreeNotificationHandlerWrapper, void>
CindNotification;
typedef BluetoothNotificationHALRunnable0<
HandsfreeNotificationHandlerWrapper, void>
CopsNotification;
typedef BluetoothNotificationHALRunnable0<
HandsfreeNotificationHandlerWrapper, void>
ClccNotification;
typedef BluetoothNotificationHALRunnable1<
HandsfreeNotificationHandlerWrapper, void, nsCString, const nsACString&>
UnknownAtNotification;
typedef BluetoothNotificationHALRunnable0<
HandsfreeNotificationHandlerWrapper, void>
KeyPressedNotification;
// Bluedroid Handsfree callbacks
static void
ConnectionState(bthf_connection_state_t aState, bt_bdaddr_t* aBdAddr)
{
ConnectionStateNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::ConnectionStateNotification,
aState, aBdAddr);
}
static void
AudioState(bthf_audio_state_t aState, bt_bdaddr_t* aBdAddr)
{
AudioStateNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::AudioStateNotification,
aState, aBdAddr);
}
static void
VoiceRecognition(bthf_vr_state_t aState)
{
VoiceRecognitionNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::VoiceRecognitionNotification,
aState);
}
static void
AnswerCall()
{
AnswerCallNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::AnswerCallNotification);
}
static void
HangupCall()
{
HangupCallNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::HangupCallNotification);
}
static void
Volume(bthf_volume_type_t aType, int aVolume)
{
VolumeNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::VolumeNotification,
aType, aVolume);
}
static void
DialCall(char* aNumber)
{
DialCallNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::DialCallNotification, aNumber);
}
static void
Dtmf(char aDtmf)
{
DtmfNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::DtmfNotification, aDtmf);
}
static void
NoiseReductionEchoCancellation(bthf_nrec_t aNrec)
{
NRECNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::NRECNotification, aNrec);
}
static void
CallHold(bthf_chld_type_t aChld)
{
CallHoldNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::CallHoldNotification, aChld);
}
static void
Cnum()
{
CnumNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::CnumNotification);
}
static void
Cind()
{
CindNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::CindNotification);
}
static void
Cops()
{
CopsNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::CopsNotification);
}
static void
Clcc()
{
ClccNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::ClccNotification);
}
static void
UnknownAt(char* aAtString)
{
UnknownAtNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::UnknownAtNotification,
aAtString);
}
static void
KeyPressed()
{
KeyPressedNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::KeyPressedNotification);
}
};
// Interface
//
BluetoothHandsfreeHALInterface::BluetoothHandsfreeHALInterface(
const bthf_interface_t* aInterface)
: mInterface(aInterface)
{
MOZ_ASSERT(mInterface);
}
BluetoothHandsfreeHALInterface::~BluetoothHandsfreeHALInterface()
{ }
void
BluetoothHandsfreeHALInterface::Init(
BluetoothHandsfreeNotificationHandler* aNotificationHandler,
BluetoothHandsfreeResultHandler* aRes)
{
static bthf_callbacks_t sCallbacks = {
sizeof(sCallbacks),
BluetoothHandsfreeHALCallback::ConnectionState,
BluetoothHandsfreeHALCallback::AudioState,
BluetoothHandsfreeHALCallback::VoiceRecognition,
BluetoothHandsfreeHALCallback::AnswerCall,
BluetoothHandsfreeHALCallback::HangupCall,
BluetoothHandsfreeHALCallback::Volume,
BluetoothHandsfreeHALCallback::DialCall,
BluetoothHandsfreeHALCallback::Dtmf,
BluetoothHandsfreeHALCallback::NoiseReductionEchoCancellation,
BluetoothHandsfreeHALCallback::CallHold,
BluetoothHandsfreeHALCallback::Cnum,
BluetoothHandsfreeHALCallback::Cind,
BluetoothHandsfreeHALCallback::Cops,
BluetoothHandsfreeHALCallback::Clcc,
BluetoothHandsfreeHALCallback::UnknownAt,
BluetoothHandsfreeHALCallback::KeyPressed
};
sHandsfreeNotificationHandler = aNotificationHandler;
bt_status_t status = mInterface->init(&sCallbacks);
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::Init,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHandsfreeHALInterface::Cleanup(
BluetoothHandsfreeResultHandler* aRes)
{
mInterface->cleanup();
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::Cleanup, STATUS_SUCCESS);
}
}
/* Connect / Disconnect */
void
BluetoothHandsfreeHALInterface::Connect(
const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bt_bdaddr_t bdAddr;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
status = mInterface->connect(&bdAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::Connect,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHandsfreeHALInterface::Disconnect(
const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bt_bdaddr_t bdAddr;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
status = mInterface->disconnect(&bdAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::Disconnect,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHandsfreeHALInterface::ConnectAudio(
const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bt_bdaddr_t bdAddr;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
status = mInterface->connect_audio(&bdAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::ConnectAudio,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHandsfreeHALInterface::DisconnectAudio(
const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bt_bdaddr_t bdAddr;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
status = mInterface->disconnect_audio(&bdAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::DisconnectAudio,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Voice Recognition */
void
BluetoothHandsfreeHALInterface::StartVoiceRecognition(
BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status = mInterface->start_voice_recognition();
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::StartVoiceRecognition,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHandsfreeHALInterface::StopVoiceRecognition(
BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status = mInterface->stop_voice_recognition();
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::StopVoiceRecognition,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Volume */
void
BluetoothHandsfreeHALInterface::VolumeControl(
BluetoothHandsfreeVolumeType aType, int aVolume,
BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bthf_volume_type_t type = BTHF_VOLUME_TYPE_SPK;
if (NS_SUCCEEDED(Convert(aType, type))) {
status = mInterface->volume_control(type, aVolume);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::VolumeControl,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Device status */
void
BluetoothHandsfreeHALInterface::DeviceStatusNotification(
BluetoothHandsfreeNetworkState aNtkState,
BluetoothHandsfreeServiceType aSvcType, int aSignal,
int aBattChg, BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bthf_network_state_t ntkState = BTHF_NETWORK_STATE_NOT_AVAILABLE;
bthf_service_type_t svcType = BTHF_SERVICE_TYPE_HOME;
if (NS_SUCCEEDED(Convert(aNtkState, ntkState)) &&
NS_SUCCEEDED(Convert(aSvcType, svcType))) {
status = mInterface->device_status_notification(ntkState, svcType,
aSignal, aBattChg);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::DeviceStatusNotification,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Responses */
void
BluetoothHandsfreeHALInterface::CopsResponse(
const char* aCops, BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status = mInterface->cops_response(aCops);
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::CopsResponse,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHandsfreeHALInterface::CindResponse(
int aSvc, int aNumActive, int aNumHeld,
BluetoothHandsfreeCallState aCallSetupState,
int aSignal, int aRoam, int aBattChg,
BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bthf_call_state_t callSetupState = BTHF_CALL_STATE_ACTIVE;
if (NS_SUCCEEDED(Convert(aCallSetupState, callSetupState))) {
status = mInterface->cind_response(aSvc, aNumActive, aNumHeld,
callSetupState, aSignal,
aRoam, aBattChg);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::CindResponse,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHandsfreeHALInterface::FormattedAtResponse(
const char* aRsp, BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status = mInterface->formatted_at_response(aRsp);
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::FormattedAtResponse,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHandsfreeHALInterface::AtResponse(
BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bthf_at_response_t responseCode = BTHF_AT_RESPONSE_ERROR;
if (NS_SUCCEEDED(Convert(aResponseCode, responseCode))) {
status = mInterface->at_response(responseCode, aErrorCode);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::AtResponse,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHandsfreeHALInterface::ClccResponse(
int aIndex,
BluetoothHandsfreeCallDirection aDir,
BluetoothHandsfreeCallState aState,
BluetoothHandsfreeCallMode aMode,
BluetoothHandsfreeCallMptyType aMpty,
const nsAString& aNumber,
BluetoothHandsfreeCallAddressType aType,
BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bthf_call_direction_t dir = BTHF_CALL_DIRECTION_OUTGOING;
bthf_call_state_t state = BTHF_CALL_STATE_ACTIVE;
bthf_call_mode_t mode = BTHF_CALL_TYPE_VOICE;
bthf_call_mpty_type_t mpty = BTHF_CALL_MPTY_TYPE_SINGLE;
bthf_call_addrtype_t type = BTHF_CALL_ADDRTYPE_UNKNOWN;
if (NS_SUCCEEDED(Convert(aDir, dir)) &&
NS_SUCCEEDED(Convert(aState, state)) &&
NS_SUCCEEDED(Convert(aMode, mode)) &&
NS_SUCCEEDED(Convert(aMpty, mpty)) &&
NS_SUCCEEDED(Convert(aType, type))) {
status = mInterface->clcc_response(aIndex, dir, state, mode, mpty,
NS_ConvertUTF16toUTF8(aNumber).get(),
type);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::ClccResponse,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Phone State */
void
BluetoothHandsfreeHALInterface::PhoneStateChange(int aNumActive, int aNumHeld,
BluetoothHandsfreeCallState aCallSetupState, const nsAString& aNumber,
BluetoothHandsfreeCallAddressType aType,
BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bthf_call_state_t callSetupState = BTHF_CALL_STATE_ACTIVE;
bthf_call_addrtype_t type = BTHF_CALL_ADDRTYPE_UNKNOWN;
if (NS_SUCCEEDED(Convert(aCallSetupState, callSetupState)) &&
NS_SUCCEEDED(Convert(aType, type))) {
status = mInterface->phone_state_change(
aNumActive, aNumHeld, callSetupState,
NS_ConvertUTF16toUTF8(aNumber).get(), type);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::PhoneStateChange,
ConvertDefault(status, STATUS_FAIL));
}
}
END_BLUETOOTH_NAMESPACE

Просмотреть файл

@ -0,0 +1,95 @@
/* -*- 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/. */
#ifndef mozilla_dom_bluetooth_bluedroid_bluetoothhandsfreehalinterface_h__
#define mozilla_dom_bluetooth_bluedroid_bluetoothhandsfreehalinterface_h__
#include <hardware/bluetooth.h>
#include <hardware/bt_hf.h>
#include "BluetoothCommon.h"
#include "BluetoothInterface.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothHALInterface;
class BluetoothHandsfreeHALInterface MOZ_FINAL
: public BluetoothHandsfreeInterface
{
public:
friend class BluetoothHALInterface;
void Init(BluetoothHandsfreeNotificationHandler* aNotificationHandler,
BluetoothHandsfreeResultHandler* aRes);
void Cleanup(BluetoothHandsfreeResultHandler* aRes);
/* Connect / Disconnect */
void Connect(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes);
void Disconnect(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes);
void ConnectAudio(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes);
void DisconnectAudio(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes);
/* Voice Recognition */
void StartVoiceRecognition(BluetoothHandsfreeResultHandler* aRes);
void StopVoiceRecognition(BluetoothHandsfreeResultHandler* aRes);
/* Volume */
void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume,
BluetoothHandsfreeResultHandler* aRes);
/* Device status */
void DeviceStatusNotification(BluetoothHandsfreeNetworkState aNtkState,
BluetoothHandsfreeServiceType aSvcType,
int aSignal, int aBattChg,
BluetoothHandsfreeResultHandler* aRes);
/* Responses */
void CopsResponse(const char* aCops,
BluetoothHandsfreeResultHandler* aRes);
void CindResponse(int aSvc, int aNumActive, int aNumHeld,
BluetoothHandsfreeCallState aCallSetupState, int aSignal,
int aRoam, int aBattChg,
BluetoothHandsfreeResultHandler* aRes);
void FormattedAtResponse(const char* aRsp,
BluetoothHandsfreeResultHandler* aRes);
void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
BluetoothHandsfreeResultHandler* aRes);
void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir,
BluetoothHandsfreeCallState aState,
BluetoothHandsfreeCallMode aMode,
BluetoothHandsfreeCallMptyType aMpty,
const nsAString& aNumber,
BluetoothHandsfreeCallAddressType aType,
BluetoothHandsfreeResultHandler* aRes);
/* Phone State */
void PhoneStateChange(int aNumActive, int aNumHeld,
BluetoothHandsfreeCallState aCallSetupState,
const nsAString& aNumber,
BluetoothHandsfreeCallAddressType aType,
BluetoothHandsfreeResultHandler* aRes);
protected:
BluetoothHandsfreeHALInterface(const bthf_interface_t* aInterface);
~BluetoothHandsfreeHALInterface();
private:
const bthf_interface_t* mInterface;
};
END_BLUETOOTH_NAMESPACE
#endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,480 @@
/* -*- 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 "BluetoothSocketHALInterface.h"
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include "BluetoothHALHelpers.h"
#include "nsXULAppAPI.h"
BEGIN_BLUETOOTH_NAMESPACE
typedef
BluetoothHALInterfaceRunnable1<BluetoothSocketResultHandler, void,
int, int>
BluetoothSocketHALIntResultRunnable;
typedef
BluetoothHALInterfaceRunnable3<BluetoothSocketResultHandler, void,
int, const nsString, int,
int, const nsAString_internal&, int>
BluetoothSocketHALIntStringIntResultRunnable;
typedef
BluetoothHALInterfaceRunnable1<BluetoothSocketResultHandler, void,
BluetoothStatus, BluetoothStatus>
BluetoothSocketHALErrorRunnable;
static nsresult
DispatchBluetoothSocketHALResult(
BluetoothSocketResultHandler* aRes,
void (BluetoothSocketResultHandler::*aMethod)(int), int aArg,
BluetoothStatus aStatus)
{
MOZ_ASSERT(aRes);
nsRunnable* runnable;
if (aStatus == STATUS_SUCCESS) {
runnable = new BluetoothSocketHALIntResultRunnable(aRes, aMethod, aArg);
} else {
runnable = new BluetoothSocketHALErrorRunnable(aRes,
&BluetoothSocketResultHandler::OnError, aStatus);
}
nsresult rv = NS_DispatchToMainThread(runnable);
if (NS_FAILED(rv)) {
BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
}
return rv;
}
static nsresult
DispatchBluetoothSocketHALResult(
BluetoothSocketResultHandler* aRes,
void (BluetoothSocketResultHandler::*aMethod)(int, const nsAString&, int),
int aArg1, const nsAString& aArg2, int aArg3, BluetoothStatus aStatus)
{
MOZ_ASSERT(aRes);
nsRunnable* runnable;
if (aStatus == STATUS_SUCCESS) {
runnable = new BluetoothSocketHALIntStringIntResultRunnable(
aRes, aMethod, aArg1, aArg2, aArg3);
} else {
runnable = new BluetoothSocketHALErrorRunnable(aRes,
&BluetoothSocketResultHandler::OnError, aStatus);
}
nsresult rv = NS_DispatchToMainThread(runnable);
if (NS_FAILED(rv)) {
BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
}
return rv;
}
void
BluetoothSocketHALInterface::Listen(BluetoothSocketType aType,
const nsAString& aServiceName,
const uint8_t aServiceUuid[16],
int aChannel, bool aEncrypt,
bool aAuth,
BluetoothSocketResultHandler* aRes)
{
int fd;
bt_status_t status;
btsock_type_t type = BTSOCK_RFCOMM; // silences compiler warning
if (NS_SUCCEEDED(Convert(aType, type))) {
status = mInterface->listen(type,
NS_ConvertUTF16toUTF8(aServiceName).get(),
aServiceUuid, aChannel, &fd,
(BTSOCK_FLAG_ENCRYPT * aEncrypt) |
(BTSOCK_FLAG_AUTH * aAuth));
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothSocketHALResult(
aRes, &BluetoothSocketResultHandler::Listen, fd,
ConvertDefault(status, STATUS_FAIL));
}
}
#define CMSGHDR_CONTAINS_FD(_cmsghdr) \
( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
/* |SocketMessageWatcher| receives Bluedroid's socket setup
* messages on the I/O thread. You need to inherit from this
* class to make use of it.
*
* Bluedroid sends two socket info messages (20 bytes) at
* the beginning of a connection to both peers.
*
* - 1st message: [channel:4]
* - 2nd message: [size:2][bd address:6][channel:4][connection status:4]
*
* On the server side, the second message will contain a
* socket file descriptor for the connection. The client
* uses the original file descriptor.
*/
class SocketMessageWatcher : public MessageLoopForIO::Watcher
{
public:
static const unsigned char MSG1_SIZE = 4;
static const unsigned char MSG2_SIZE = 16;
static const unsigned char OFF_CHANNEL1 = 0;
static const unsigned char OFF_SIZE = 4;
static const unsigned char OFF_BDADDRESS = 6;
static const unsigned char OFF_CHANNEL2 = 12;
static const unsigned char OFF_STATUS = 16;
SocketMessageWatcher(int aFd)
: mFd(aFd)
, mClientFd(-1)
, mLen(0)
{ }
virtual ~SocketMessageWatcher()
{ }
virtual void Proceed(BluetoothStatus aStatus) = 0;
void OnFileCanReadWithoutBlocking(int aFd) MOZ_OVERRIDE
{
BluetoothStatus status;
switch (mLen) {
case 0:
status = RecvMsg1();
break;
case MSG1_SIZE:
status = RecvMsg2();
break;
default:
/* message-size error */
status = STATUS_FAIL;
break;
}
if (IsComplete() || status != STATUS_SUCCESS) {
mWatcher.StopWatchingFileDescriptor();
Proceed(status);
}
}
void OnFileCanWriteWithoutBlocking(int aFd) MOZ_OVERRIDE
{ }
void Watch()
{
MessageLoopForIO::current()->WatchFileDescriptor(
mFd,
true,
MessageLoopForIO::WATCH_READ,
&mWatcher,
this);
}
bool IsComplete() const
{
return mLen == (MSG1_SIZE + MSG2_SIZE);
}
int GetFd() const
{
return mFd;
}
int32_t GetChannel1() const
{
return ReadInt32(OFF_CHANNEL1);
}
int32_t GetSize() const
{
return ReadInt16(OFF_SIZE);
}
nsString GetBdAddress() const
{
nsString bdAddress;
ReadBdAddress(OFF_BDADDRESS, bdAddress);
return bdAddress;
}
int32_t GetChannel2() const
{
return ReadInt32(OFF_CHANNEL2);
}
int32_t GetConnectionStatus() const
{
return ReadInt32(OFF_STATUS);
}
int GetClientFd() const
{
return mClientFd;
}
private:
BluetoothStatus RecvMsg1()
{
struct iovec iv;
memset(&iv, 0, sizeof(iv));
iv.iov_base = mBuf;
iv.iov_len = MSG1_SIZE;
struct msghdr msg;
memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iv;
msg.msg_iovlen = 1;
ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
if (res < 0) {
return STATUS_FAIL;
}
mLen += res;
return STATUS_SUCCESS;
}
BluetoothStatus RecvMsg2()
{
struct iovec iv;
memset(&iv, 0, sizeof(iv));
iv.iov_base = mBuf + MSG1_SIZE;
iv.iov_len = MSG2_SIZE;
struct msghdr msg;
struct cmsghdr cmsgbuf[2 * sizeof(cmsghdr) + 0x100];
memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iv;
msg.msg_iovlen = 1;
msg.msg_control = cmsgbuf;
msg.msg_controllen = sizeof(cmsgbuf);
ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
if (res < 0) {
return STATUS_FAIL;
}
mLen += res;
if (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) {
return STATUS_FAIL;
}
struct cmsghdr *cmsgptr = CMSG_FIRSTHDR(&msg);
// Extract client fd from message header
for (; cmsgptr; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
if (CMSGHDR_CONTAINS_FD(cmsgptr)) {
// if multiple file descriptors have been sent, we close
// all but the final one.
if (mClientFd != -1) {
TEMP_FAILURE_RETRY(close(mClientFd));
}
// retrieve sent client fd
mClientFd = *(static_cast<int*>(CMSG_DATA(cmsgptr)));
}
}
return STATUS_SUCCESS;
}
int16_t ReadInt16(unsigned long aOffset) const
{
/* little-endian buffer */
return (static_cast<int16_t>(mBuf[aOffset + 1]) << 8) |
static_cast<int16_t>(mBuf[aOffset]);
}
int32_t ReadInt32(unsigned long aOffset) const
{
/* little-endian buffer */
return (static_cast<int32_t>(mBuf[aOffset + 3]) << 24) |
(static_cast<int32_t>(mBuf[aOffset + 2]) << 16) |
(static_cast<int32_t>(mBuf[aOffset + 1]) << 8) |
static_cast<int32_t>(mBuf[aOffset]);
}
void ReadBdAddress(unsigned long aOffset, nsAString& aBdAddress) const
{
const bt_bdaddr_t* bdAddress =
reinterpret_cast<const bt_bdaddr_t*>(mBuf+aOffset);
if (NS_FAILED(Convert(*bdAddress, aBdAddress))) {
aBdAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
}
}
MessageLoopForIO::FileDescriptorWatcher mWatcher;
int mFd;
int mClientFd;
unsigned char mLen;
uint8_t mBuf[MSG1_SIZE + MSG2_SIZE];
};
/* |SocketMessageWatcherTask| starts a SocketMessageWatcher
* on the I/O task
*/
class SocketMessageWatcherTask MOZ_FINAL : public Task
{
public:
SocketMessageWatcherTask(SocketMessageWatcher* aWatcher)
: mWatcher(aWatcher)
{
MOZ_ASSERT(mWatcher);
}
void Run() MOZ_OVERRIDE
{
mWatcher->Watch();
}
private:
SocketMessageWatcher* mWatcher;
};
/* |DeleteTask| deletes a class instance on the I/O thread
*/
template <typename T>
class DeleteTask MOZ_FINAL : public Task
{
public:
DeleteTask(T* aPtr)
: mPtr(aPtr)
{ }
void Run() MOZ_OVERRIDE
{
mPtr = nullptr;
}
private:
nsAutoPtr<T> mPtr;
};
/* |ConnectWatcher| specializes SocketMessageWatcher for
* connect operations by reading the socket messages from
* Bluedroid and forwarding the connected socket to the
* resource handler.
*/
class ConnectWatcher MOZ_FINAL : public SocketMessageWatcher
{
public:
ConnectWatcher(int aFd, BluetoothSocketResultHandler* aRes)
: SocketMessageWatcher(aFd)
, mRes(aRes)
{ }
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
{
if (mRes) {
DispatchBluetoothSocketHALResult(
mRes, &BluetoothSocketResultHandler::Connect, GetFd(),
GetBdAddress(), GetConnectionStatus(), aStatus);
}
MessageLoopForIO::current()->PostTask(
FROM_HERE, new DeleteTask<ConnectWatcher>(this));
}
private:
nsRefPtr<BluetoothSocketResultHandler> mRes;
};
void
BluetoothSocketHALInterface::Connect(const nsAString& aBdAddr,
BluetoothSocketType aType,
const uint8_t aUuid[16],
int aChannel, bool aEncrypt,
bool aAuth,
BluetoothSocketResultHandler* aRes)
{
int fd;
bt_status_t status;
bt_bdaddr_t bdAddr;
btsock_type_t type = BTSOCK_RFCOMM; // silences compiler warning
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr)) &&
NS_SUCCEEDED(Convert(aType, type))) {
status = mInterface->connect(&bdAddr, type, aUuid, aChannel, &fd,
(BTSOCK_FLAG_ENCRYPT * aEncrypt) |
(BTSOCK_FLAG_AUTH * aAuth));
} else {
status = BT_STATUS_PARM_INVALID;
}
if (status == BT_STATUS_SUCCESS) {
/* receive Bluedroid's socket-setup messages */
Task* t = new SocketMessageWatcherTask(new ConnectWatcher(fd, aRes));
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
} else if (aRes) {
DispatchBluetoothSocketHALResult(
aRes, &BluetoothSocketResultHandler::Connect, -1, EmptyString(), 0,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Specializes SocketMessageWatcher for Accept operations by
* reading the socket messages from Bluedroid and forwarding
* the received client socket to the resource handler. The
* first message is received immediately. When there's a new
* connection, Bluedroid sends the 2nd message with the socket
* info and socket file descriptor.
*/
class AcceptWatcher MOZ_FINAL : public SocketMessageWatcher
{
public:
AcceptWatcher(int aFd, BluetoothSocketResultHandler* aRes)
: SocketMessageWatcher(aFd)
, mRes(aRes)
{
/* not supplying a result handler leaks received file descriptor */
MOZ_ASSERT(mRes);
}
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
{
if (mRes) {
DispatchBluetoothSocketHALResult(
mRes, &BluetoothSocketResultHandler::Accept, GetClientFd(),
GetBdAddress(), GetConnectionStatus(), aStatus);
}
MessageLoopForIO::current()->PostTask(
FROM_HERE, new DeleteTask<AcceptWatcher>(this));
}
private:
nsRefPtr<BluetoothSocketResultHandler> mRes;
};
void
BluetoothSocketHALInterface::Accept(int aFd,
BluetoothSocketResultHandler* aRes)
{
/* receive Bluedroid's socket-setup messages and client fd */
Task* t = new SocketMessageWatcherTask(new AcceptWatcher(aFd, aRes));
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
}
BluetoothSocketHALInterface::BluetoothSocketHALInterface(
const btsock_interface_t* aInterface)
: mInterface(aInterface)
{
MOZ_ASSERT(mInterface);
}
BluetoothSocketHALInterface::~BluetoothSocketHALInterface()
{ }
END_BLUETOOTH_NAMESPACE

Просмотреть файл

@ -0,0 +1,49 @@
/* -*- 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/. */
#ifndef mozilla_dom_bluetooth_bluedroid_bluetoothsockethalinterface_h__
#define mozilla_dom_bluetooth_bluedroid_bluetoothsockethalinterface_h__
#include <hardware/bluetooth.h>
#include <hardware/bt_sock.h>
#include "BluetoothCommon.h"
#include "BluetoothInterface.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothHALInterface;
class BluetoothSocketHALInterface MOZ_FINAL
: public BluetoothSocketInterface
{
public:
friend class BluetoothHALInterface;
void Listen(BluetoothSocketType aType,
const nsAString& aServiceName,
const uint8_t aServiceUuid[16],
int aChannel, bool aEncrypt, bool aAuth,
BluetoothSocketResultHandler* aRes);
void Connect(const nsAString& aBdAddr,
BluetoothSocketType aType,
const uint8_t aUuid[16],
int aChannel, bool aEncrypt, bool aAuth,
BluetoothSocketResultHandler* aRes);
void Accept(int aFd, BluetoothSocketResultHandler* aRes);
protected:
BluetoothSocketHALInterface(const btsock_interface_t* aInterface);
~BluetoothSocketHALInterface();
private:
const btsock_interface_t* mInterface;
};
END_BLUETOOTH_NAMESPACE
#endif

Просмотреть файл

@ -9,6 +9,7 @@ if CONFIG['MOZ_B2G_BT']:
'BluetoothAdapter.cpp', 'BluetoothAdapter.cpp',
'BluetoothDevice.cpp', 'BluetoothDevice.cpp',
'BluetoothHidManager.cpp', 'BluetoothHidManager.cpp',
'BluetoothInterface.cpp',
'BluetoothManager.cpp', 'BluetoothManager.cpp',
'BluetoothProfileController.cpp', 'BluetoothProfileController.cpp',
'BluetoothPropertyContainer.cpp', 'BluetoothPropertyContainer.cpp',
@ -44,11 +45,16 @@ if CONFIG['MOZ_B2G_BT']:
DEFINES['MOZ_B2G_BT_BLUEZ'] = True DEFINES['MOZ_B2G_BT_BLUEZ'] = True
elif CONFIG['MOZ_B2G_BT_BLUEDROID']: elif CONFIG['MOZ_B2G_BT_BLUEDROID']:
SOURCES += [ SOURCES += [
'bluedroid/BluetoothA2dpHALInterface.cpp',
'bluedroid/BluetoothA2dpManager.cpp', 'bluedroid/BluetoothA2dpManager.cpp',
'bluedroid/BluetoothInterface.cpp', 'bluedroid/BluetoothAvrcpHALInterface.cpp',
'bluedroid/BluetoothHALHelpers.cpp',
'bluedroid/BluetoothHALInterface.cpp',
'bluedroid/BluetoothHandsfreeHALInterface.cpp',
'bluedroid/BluetoothOppManager.cpp', 'bluedroid/BluetoothOppManager.cpp',
'bluedroid/BluetoothServiceBluedroid.cpp', 'bluedroid/BluetoothServiceBluedroid.cpp',
'bluedroid/BluetoothSocket.cpp', 'bluedroid/BluetoothSocket.cpp',
'bluedroid/BluetoothSocketHALInterface.cpp',
'bluedroid/BluetoothUtils.cpp', 'bluedroid/BluetoothUtils.cpp',
] ]
LOCAL_INCLUDES += [ LOCAL_INCLUDES += [