mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 935578 - Patch 2: BluetoothA2dpManager bluedroid version, r=echou
This commit is contained in:
parent
757566e5b0
commit
76c13d78b7
@ -8,17 +8,21 @@
|
||||
|
||||
#include "BluetoothA2dpManager.h"
|
||||
|
||||
#include <hardware/bluetooth.h>
|
||||
#include <hardware/bt_av.h>
|
||||
|
||||
#include "BluetoothCommon.h"
|
||||
#include "BluetoothService.h"
|
||||
#include "BluetoothServiceBluedroid.h"
|
||||
#include "BluetoothSocket.h"
|
||||
#include "BluetoothUtils.h"
|
||||
|
||||
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "MainThreadUtils.h"
|
||||
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
USING_BLUETOOTH_NAMESPACE
|
||||
@ -26,8 +30,33 @@ USING_BLUETOOTH_NAMESPACE
|
||||
namespace {
|
||||
StaticRefPtr<BluetoothA2dpManager> sBluetoothA2dpManager;
|
||||
bool sInShutdown = false;
|
||||
static const btav_interface_t* sBtA2dpInterface;
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
class SinkPropertyChangedHandler : public nsRunnable
|
||||
{
|
||||
public:
|
||||
SinkPropertyChangedHandler(const BluetoothSignal& aSignal)
|
||||
: mSignal(aSignal)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
|
||||
NS_ENSURE_TRUE(a2dp, NS_ERROR_FAILURE);
|
||||
a2dp->HandleSinkPropertyChanged(mSignal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothSignal mSignal;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
BluetoothA2dpManager::Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
@ -50,18 +79,100 @@ BluetoothA2dpManager::BluetoothA2dpManager()
|
||||
ResetAvrcp();
|
||||
}
|
||||
|
||||
static void
|
||||
AvStatusToSinkString(btav_connection_state_t aStatus, nsAString& aState)
|
||||
{
|
||||
nsAutoString state;
|
||||
if (aStatus == BTAV_CONNECTION_STATE_DISCONNECTED) {
|
||||
aState = NS_LITERAL_STRING("disconnected");
|
||||
} else if (aStatus == BTAV_CONNECTION_STATE_CONNECTING) {
|
||||
aState = NS_LITERAL_STRING("connecting");
|
||||
} else if (aStatus == BTAV_CONNECTION_STATE_CONNECTED) {
|
||||
aState = NS_LITERAL_STRING("connected");
|
||||
} else if (aStatus == BTAV_CONNECTION_STATE_DISCONNECTING) {
|
||||
aState = NS_LITERAL_STRING("disconnecting");
|
||||
} else {
|
||||
BT_WARNING("Unknown sink state");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
A2dpConnectionStateCallback(btav_connection_state_t aState,
|
||||
bt_bdaddr_t* aBdAddress)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsString remoteDeviceBdAddress;
|
||||
BdAddressTypeToString(aBdAddress, remoteDeviceBdAddress);
|
||||
|
||||
nsString a2dpState;
|
||||
AvStatusToSinkString(aState, a2dpState);
|
||||
|
||||
InfallibleTArray<BluetoothNamedValue> props;
|
||||
props.AppendElement(
|
||||
BluetoothNamedValue(NS_LITERAL_STRING("State"), a2dpState));
|
||||
|
||||
BluetoothSignal signal(NS_LITERAL_STRING("AudioSink"),
|
||||
remoteDeviceBdAddress, props);
|
||||
NS_DispatchToMainThread(new SinkPropertyChangedHandler(signal));
|
||||
}
|
||||
|
||||
static void
|
||||
A2dpAudioStateCallback(btav_audio_state_t aState,
|
||||
bt_bdaddr_t* aBdAddress)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsString remoteDeviceBdAddress;
|
||||
BdAddressTypeToString(aBdAddress, remoteDeviceBdAddress);
|
||||
|
||||
nsString a2dpState;
|
||||
|
||||
if (aState == BTAV_AUDIO_STATE_STARTED) {
|
||||
a2dpState = NS_LITERAL_STRING("playing");
|
||||
} else if (aState == BTAV_AUDIO_STATE_STOPPED) {
|
||||
// for avdtp state stop stream
|
||||
a2dpState = NS_LITERAL_STRING("connected");
|
||||
} else if (aState == BTAV_AUDIO_STATE_REMOTE_SUSPEND) {
|
||||
// for avdtp state suspend stream from remote side
|
||||
a2dpState = NS_LITERAL_STRING("connected");
|
||||
}
|
||||
|
||||
InfallibleTArray<BluetoothNamedValue> props;
|
||||
props.AppendElement(
|
||||
BluetoothNamedValue(NS_LITERAL_STRING("State"), a2dpState));
|
||||
|
||||
BluetoothSignal signal(NS_LITERAL_STRING("AudioSink"),
|
||||
remoteDeviceBdAddress, props);
|
||||
NS_DispatchToMainThread(new SinkPropertyChangedHandler(signal));
|
||||
}
|
||||
|
||||
static btav_callbacks_t sBtA2dpCallbacks = {
|
||||
sizeof(sBtA2dpCallbacks),
|
||||
A2dpConnectionStateCallback,
|
||||
A2dpAudioStateCallback
|
||||
};
|
||||
|
||||
/*
|
||||
* This function will be only called when Bluetooth is turning on.
|
||||
* It is important to register a2dp callbacks before enable() gets called.
|
||||
* It is required to register a2dp callbacks before a2dp media task
|
||||
* starts up.
|
||||
*/
|
||||
bool
|
||||
BluetoothA2dpManager::Init()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
const bt_interface_t* btInf = GetBluetoothInterface();
|
||||
NS_ENSURE_TRUE(btInf, false);
|
||||
sBtA2dpInterface = (btav_interface_t *)btInf->
|
||||
get_profile_interface(BT_PROFILE_ADVANCED_AUDIO_ID);
|
||||
NS_ENSURE_TRUE(sBtA2dpInterface, false);
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
NS_ENSURE_TRUE(obs, false);
|
||||
if (NS_FAILED(obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false))) {
|
||||
BT_WARNING("Failed to add shutdown observer!");
|
||||
int ret = sBtA2dpInterface->init(&sBtA2dpCallbacks);
|
||||
if (ret != BT_STATUS_SUCCESS) {
|
||||
BT_LOGR("failed to init a2dp module");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -93,6 +204,10 @@ BluetoothA2dpManager::ResetAvrcp()
|
||||
mPlayStatus = ControlPlayStatus::PLAYSTATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Static functions
|
||||
*/
|
||||
|
||||
static BluetoothA2dpManager::SinkState
|
||||
StatusStringToSinkState(const nsAString& aStatus)
|
||||
{
|
||||
@ -165,11 +280,11 @@ BluetoothA2dpManager::Connect(const nsAString& aDeviceAddress,
|
||||
mDeviceAddress = aDeviceAddress;
|
||||
mController = aController;
|
||||
|
||||
if (NS_FAILED(bs->SendSinkMessage(aDeviceAddress,
|
||||
NS_LITERAL_STRING("Connect")))) {
|
||||
aController->OnConnect(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
|
||||
return;
|
||||
}
|
||||
bt_bdaddr_t remoteAddress;
|
||||
StringToBdAddressType(aDeviceAddress, &remoteAddress);
|
||||
NS_ENSURE_TRUE_VOID(sBtA2dpInterface);
|
||||
NS_ENSURE_TRUE_VOID(BT_STATUS_SUCCESS ==
|
||||
sBtA2dpInterface->connect(&remoteAddress));
|
||||
}
|
||||
|
||||
void
|
||||
@ -195,10 +310,11 @@ BluetoothA2dpManager::Disconnect(BluetoothProfileController* aController)
|
||||
|
||||
mController = aController;
|
||||
|
||||
if (NS_FAILED(bs->SendSinkMessage(mDeviceAddress,
|
||||
NS_LITERAL_STRING("Disconnect")))) {
|
||||
aController->OnDisconnect(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
|
||||
return;
|
||||
bt_bdaddr_t remoteAddress;
|
||||
StringToBdAddressType(mDeviceAddress, &remoteAddress);
|
||||
if (sBtA2dpInterface) {
|
||||
NS_ENSURE_TRUE_VOID(BT_STATUS_SUCCESS ==
|
||||
sBtA2dpInterface->disconnect(&remoteAddress));
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,7 +370,8 @@ void
|
||||
BluetoothA2dpManager::HandleSinkPropertyChanged(const BluetoothSignal& aSignal)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aSignal.value().type() == BluetoothValue::TArrayOfBluetoothNamedValue);
|
||||
MOZ_ASSERT(aSignal.value().type() ==
|
||||
BluetoothValue::TArrayOfBluetoothNamedValue);
|
||||
|
||||
const nsString& address = aSignal.path();
|
||||
const InfallibleTArray<BluetoothNamedValue>& arr =
|
||||
@ -293,13 +410,12 @@ BluetoothA2dpManager::HandleSinkPropertyChanged(const BluetoothSignal& aSignal)
|
||||
break;
|
||||
case SinkState::SINK_CONNECTED:
|
||||
// case 5: Audio stream suspended
|
||||
if (prevState == SinkState::SINK_PLAYING) {
|
||||
if (prevState == SinkState::SINK_PLAYING ||
|
||||
prevState == SinkState::SINK_CONNECTED) {
|
||||
break;
|
||||
}
|
||||
|
||||
// case 3: Successfully connected
|
||||
MOZ_ASSERT(prevState == SinkState::SINK_CONNECTING);
|
||||
|
||||
// case 3: Successfully connected
|
||||
mA2dpConnected = true;
|
||||
mDeviceAddress = address;
|
||||
NotifyConnectionStatusChanged();
|
||||
|
@ -60,9 +60,9 @@ public:
|
||||
void GetTitle(nsAString& aTitle);
|
||||
|
||||
private:
|
||||
class SinkPropertyChangedHandler;
|
||||
BluetoothA2dpManager();
|
||||
bool Init();
|
||||
|
||||
void HandleShutdown();
|
||||
void NotifyConnectionStatusChanged();
|
||||
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
#include <hardware/hardware.h>
|
||||
|
||||
#include "bluedroid/BluetoothA2dpManager.h"
|
||||
#include "bluedroid/BluetoothHfpManager.h"
|
||||
#include "BluetoothProfileController.h"
|
||||
#include "BluetoothReplyRunnable.h"
|
||||
#include "BluetoothUtils.h"
|
||||
@ -172,7 +174,7 @@ IsReady()
|
||||
const bt_interface_t*
|
||||
GetBluetoothInterface()
|
||||
{
|
||||
return (IsReady()) ? sBtInterface : nullptr;
|
||||
return sBtInterface;
|
||||
}
|
||||
|
||||
void
|
||||
@ -187,7 +189,7 @@ StringToBdAddressType(const nsAString& aBdAddress,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
BdAddressTypeToString(bt_bdaddr_t* aBdAddressType, nsAString& aRetBdAddress)
|
||||
{
|
||||
uint8_t* addr = aBdAddressType->address;
|
||||
@ -635,7 +637,12 @@ EnsureBluetoothHalLoad()
|
||||
module->methods->open(module, BT_HARDWARE_MODULE_ID, &device);
|
||||
sBtDevice = (bluetooth_device_t *)device;
|
||||
sBtInterface = sBtDevice->get_bluetooth_interface();
|
||||
BT_LOGD("Bluetooth HAL loaded");
|
||||
|
||||
int ret = sBtInterface->init(&sBluetoothCallbacks);
|
||||
if (ret != BT_STATUS_SUCCESS) {
|
||||
BT_LOGR("Error while setting the callbacks %s", __FUNCTION__);
|
||||
sBtInterface = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -645,25 +652,8 @@ StartStopGonkBluetooth(bool aShouldEnable)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
static bool sIsBtInterfaceInitialized = false;
|
||||
|
||||
if (!EnsureBluetoothHalLoad()) {
|
||||
BT_LOGR("Failed to load bluedroid library.\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (sIsBtEnabled == aShouldEnable)
|
||||
return NS_OK;
|
||||
|
||||
if (sBtInterface && !sIsBtInterfaceInitialized) {
|
||||
int ret = sBtInterface->init(&sBluetoothCallbacks);
|
||||
if (ret != BT_STATUS_SUCCESS) {
|
||||
BT_LOGR("Error while setting the callbacks %s", __FUNCTION__);
|
||||
sBtInterface = nullptr;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
sIsBtInterfaceInitialized = true;
|
||||
}
|
||||
NS_ENSURE_TRUE(sBtInterface, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(sIsBtEnabled != aShouldEnable, NS_OK);
|
||||
|
||||
int ret = aShouldEnable ? sBtInterface->enable() : sBtInterface->disable();
|
||||
NS_ENSURE_TRUE(ret == BT_STATUS_SUCCESS, NS_ERROR_FAILURE);
|
||||
@ -709,6 +699,16 @@ ReplyStatusError(BluetoothReplyRunnable* aBluetoothReplyRunnable,
|
||||
BluetoothServiceBluedroid::BluetoothServiceBluedroid()
|
||||
{
|
||||
sToggleBtMonitor = new Monitor("BluetoothService.sToggleBtMonitor");
|
||||
|
||||
if (!EnsureBluetoothHalLoad()) {
|
||||
BT_LOGR("Error! Failed to load bluedroid library.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Register all the bluedroid callbacks before enable() get called
|
||||
// It is required to register a2dp callbacks before a2dp media task starts up.
|
||||
BluetoothHfpManager::Get();
|
||||
BluetoothA2dpManager::Get();
|
||||
}
|
||||
|
||||
BluetoothServiceBluedroid::~BluetoothServiceBluedroid()
|
||||
@ -747,11 +747,6 @@ BluetoothServiceBluedroid::IsEnabledInternal()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
if (!EnsureBluetoothHalLoad()) {
|
||||
NS_ERROR("Failed to load bluedroid library.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return sIsBtEnabled;
|
||||
}
|
||||
|
||||
|
@ -20,14 +20,18 @@ GetBluetoothInterface();
|
||||
void
|
||||
StringToBdAddressType(const nsAString& aBdAddress,
|
||||
bt_bdaddr_t *aRetBdAddressType);
|
||||
|
||||
class DBusMessage;
|
||||
void
|
||||
BdAddressTypeToString(bt_bdaddr_t* aBdAddressType,
|
||||
nsAString& aRetBdAddress);
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothServiceBluedroid : public BluetoothService
|
||||
{
|
||||
public:
|
||||
BluetoothServiceBluedroid();
|
||||
~BluetoothServiceBluedroid();
|
||||
|
||||
virtual nsresult StartInternal();
|
||||
virtual nsresult StopInternal();
|
||||
virtual bool IsEnabledInternal();
|
||||
@ -192,9 +196,6 @@ public:
|
||||
virtual nsresult
|
||||
SendInputMessage(const nsAString& aDeviceAddresses,
|
||||
const nsAString& aMessage) MOZ_OVERRIDE;
|
||||
|
||||
BluetoothServiceBluedroid();
|
||||
~BluetoothServiceBluedroid();
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
Loading…
Reference in New Issue
Block a user