Bug 1061124: Implement Bluetooth A2DP notifications (under bluetooth2/), r=btian

This patch adds Bluetooth A2DP and AVRCP notifications to Gecko's
A2DP manager. The code has been taken from taken from the callback
implementations, and adapted to run on the main thread. No further
cleanups have been applied.
This commit is contained in:
Thomas Zimmermann 2014-09-05 10:00:40 +02:00
parent 9543d51d44
commit 288ce086d5
2 changed files with 276 additions and 2 deletions

View File

@ -8,7 +8,6 @@
#include "BluetoothA2dpManager.h"
#include "BluetoothCommon.h"
#include "BluetoothInterface.h"
#include "BluetoothService.h"
#include "BluetoothSocket.h"
#include "BluetoothUtils.h"
@ -161,6 +160,19 @@ public:
}
}
UpdateElementAttrsTask(uint8_t aNumAttr,
const BluetoothAvrcpMediaAttribute* aAttrs)
: mNumAttr(aNumAttr)
{
MOZ_ASSERT(!NS_IsMainThread());
mAttrs = new BluetoothAvrcpElementAttribute[mNumAttr];
for (uint8_t i = 0; i < mNumAttr; ++i) {
mAttrs[i].mId = aAttrs[i];
}
}
nsresult Run()
{
MOZ_ASSERT(NS_IsMainThread());
@ -249,6 +261,28 @@ AvStatusToSinkString(btav_connection_state_t aStatus, nsAString& aState)
}
}
static void
AvStatusToSinkString(BluetoothA2dpConnectionState aState, nsAString& aString)
{
switch (aState) {
case A2DP_CONNECTION_STATE_DISCONNECTED:
aString.AssignLiteral("disconnected");
break;
case A2DP_CONNECTION_STATE_CONNECTING:
aString.AssignLiteral("connecting");
break;
case A2DP_CONNECTION_STATE_CONNECTED:
aString.AssignLiteral("connected");
break;
case A2DP_CONNECTION_STATE_DISCONNECTING:
aString.AssignLiteral("disconnecting");
break;
default:
BT_WARNING("Unknown sink state %d", static_cast<int>(aState));
return;
}
}
static void
A2dpConnectionStateCallback(btav_connection_state_t aState,
bt_bdaddr_t* aBdAddress)
@ -1327,5 +1361,203 @@ BluetoothA2dpManager::GetArtist(nsAString& aArtist)
aArtist.Assign(mArtist);
}
/*
* A2DP Notifications
*/
void
BluetoothA2dpManager::ConnectionStateNotification(BluetoothA2dpConnectionState aState,
const nsAString& aBdAddr)
{
MOZ_ASSERT(NS_IsMainThread());
nsString a2dpState;
AvStatusToSinkString(aState, a2dpState);
InfallibleTArray<BluetoothNamedValue> props;
BT_APPEND_NAMED_VALUE(props, "State", a2dpState);
BluetoothSignal signal(NS_LITERAL_STRING("AudioSink"),
nsString(aBdAddr), props);
NS_DispatchToMainThread(new SinkPropertyChangedHandler(signal));
}
void
BluetoothA2dpManager::AudioStateNotification(BluetoothA2dpAudioState aState,
const nsAString& aBdAddr)
{
MOZ_ASSERT(NS_IsMainThread());
nsString a2dpState;
if (aState == A2DP_AUDIO_STATE_STARTED) {
a2dpState = NS_LITERAL_STRING("playing");
} else if (aState == A2DP_AUDIO_STATE_STOPPED) {
// for avdtp state stop stream
a2dpState = NS_LITERAL_STRING("connected");
} else if (aState == A2DP_AUDIO_STATE_REMOTE_SUSPEND) {
// for avdtp state suspend stream from remote side
a2dpState = NS_LITERAL_STRING("connected");
}
InfallibleTArray<BluetoothNamedValue> props;
BT_APPEND_NAMED_VALUE(props, "State", a2dpState);
BluetoothSignal signal(NS_LITERAL_STRING("AudioSink"),
nsString(aBdAddr), props);
NS_DispatchToMainThread(new SinkPropertyChangedHandler(signal));
}
/*
* AVRCP Notifications
*/
void
BluetoothA2dpManager::GetPlayStatusNotification()
{
MOZ_ASSERT(NS_IsMainThread());
NS_DispatchToMainThread(new RequestPlayStatusTask());
}
/* Player application settings is optional for AVRCP 1.3. B2G
* currently does not support player-application-setting related
* functionality.
*/
void
BluetoothA2dpManager::ListPlayerAppAttrNotification()
{
MOZ_ASSERT(NS_IsMainThread());
// TODO: Support AVRCP application-setting-related functions
}
void
BluetoothA2dpManager::ListPlayerAppValuesNotification(
BluetoothAvrcpPlayerAttribute aAttrId)
{
MOZ_ASSERT(NS_IsMainThread());
// TODO: Support AVRCP application-setting-related functions
}
void
BluetoothA2dpManager::GetPlayerAppValueNotification(
uint8_t aNumAttrs, const BluetoothAvrcpPlayerAttribute* aAttrs)
{
MOZ_ASSERT(NS_IsMainThread());
// TODO: Support AVRCP application-setting-related functions
}
void
BluetoothA2dpManager::GetPlayerAppAttrsTextNotification(
uint8_t aNumAttrs, const BluetoothAvrcpPlayerAttribute* aAttrs)
{
MOZ_ASSERT(NS_IsMainThread());
// TODO: Support AVRCP application-setting-related functions
}
void
BluetoothA2dpManager::GetPlayerAppValuesTextNotification(
uint8_t aAttrId, uint8_t aNumVals, const uint8_t* aValues)
{
MOZ_ASSERT(NS_IsMainThread());
// TODO: Support AVRCP application-setting-related functions
}
void
BluetoothA2dpManager::SetPlayerAppValueNotification(
const BluetoothAvrcpPlayerSettings& aSettings)
{
MOZ_ASSERT(NS_IsMainThread());
// TODO: Support AVRCP application-setting-related functions
}
/* This method returns element attributes, which are requested from
* CT. Unlike BlueZ it calls only UpdateMetaData. Bluedroid does not cache
* meta-data information, but instead uses |GetElementAttrNotifications|
* and |GetElementAttrRsp| request them.
*/
void
BluetoothA2dpManager::GetElementAttrNotification(
uint8_t aNumAttrs, const BluetoothAvrcpMediaAttribute* aAttrs)
{
MOZ_ASSERT(NS_IsMainThread());
NS_DispatchToMainThread(new UpdateElementAttrsTask(aNumAttrs, aAttrs));
}
void
BluetoothA2dpManager::RegisterNotificationNotification(
BluetoothAvrcpEvent aEvent, uint32_t aParam)
{
MOZ_ASSERT(NS_IsMainThread());
NS_DispatchToMainThread(new UpdateRegisterNotificationTask(aEvent, aParam));
}
/* This method is used to get CT features from the Feature Bit Mask. If
* Advanced Control Player bit is set, the CT supports volume sync (absolute
* volume feature). If Browsing bit is set, AVRCP 1.4 Browse feature will be
* supported.
*/
void
BluetoothA2dpManager::RemoteFeatureNotification(
const nsAString& aBdAddr, unsigned long aFeatures)
{
MOZ_ASSERT(NS_IsMainThread());
// TODO: Support AVRCP 1.4 absolute volume/browse
}
/* This method is used to get notifications about volume changes on the
* remote car kit (if it supports AVRCP 1.4), not notification from phone.
*/
void
BluetoothA2dpManager::VolumeChangeNotification(uint8_t aVolume,
uint8_t aCType)
{
MOZ_ASSERT(NS_IsMainThread());
// TODO: Support AVRCP 1.4 absolute volume/browse
}
void
BluetoothA2dpManager::PassthroughCmdNotification(int aId, int aKeyState)
{
MOZ_ASSERT(NS_IsMainThread());
// Fast-forward and rewind key events won't be generated from bluedroid
// stack after ANDROID_VERSION > 18, but via passthrough callback.
nsAutoString name;
NS_ENSURE_TRUE_VOID(aKeyState == AVRC_KEY_PRESS_STATE ||
aKeyState == AVRC_KEY_RELEASE_STATE);
switch (aId) {
case AVRC_ID_FAST_FOR:
if (aKeyState == AVRC_KEY_PRESS_STATE) {
name.AssignLiteral("media-fast-forward-button-press");
} else {
name.AssignLiteral("media-fast-forward-button-release");
}
break;
case AVRC_ID_REWIND:
if (aKeyState == AVRC_KEY_PRESS_STATE) {
name.AssignLiteral("media-rewind-button-press");
} else {
name.AssignLiteral("media-rewind-button-release");
}
break;
default:
BT_WARNING("Unable to handle the unknown PassThrough command %d", aId);
return;
}
NS_DispatchToMainThread(new UpdatePassthroughCmdTask(name));
}
NS_IMPL_ISUPPORTS(BluetoothA2dpManager, nsIObserver)

View File

@ -8,11 +8,14 @@
#define mozilla_dom_bluetooth_bluetootha2dpmanager_h__
#include "BluetoothCommon.h"
#include "BluetoothInterface.h"
#include "BluetoothProfileController.h"
#include "BluetoothProfileManagerBase.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothA2dpManager : public BluetoothProfileManagerBase
, public BluetoothA2dpNotificationHandler
, public BluetoothAvrcpNotificationHandler
{
public:
BT_DECL_PROFILE_MGR_BASE
@ -63,7 +66,6 @@ public:
void GetArtist(nsAString& aArtist);
private:
class SinkPropertyChangedHandler;
BluetoothA2dpManager();
void ResetA2dp();
void ResetAvrcp();
@ -71,6 +73,46 @@ private:
void HandleShutdown();
void NotifyConnectionStatusChanged();
void ConnectionStateNotification(BluetoothA2dpConnectionState aState,
const nsAString& aBdAddr) MOZ_OVERRIDE;
void AudioStateNotification(BluetoothA2dpAudioState aState,
const nsAString& aBdAddr) MOZ_OVERRIDE;
void GetPlayStatusNotification() MOZ_OVERRIDE;
void ListPlayerAppAttrNotification() MOZ_OVERRIDE;
void ListPlayerAppValuesNotification(
BluetoothAvrcpPlayerAttribute aAttrId) MOZ_OVERRIDE;
void GetPlayerAppValueNotification(
uint8_t aNumAttrs,
const BluetoothAvrcpPlayerAttribute* aAttrs) MOZ_OVERRIDE;
void GetPlayerAppAttrsTextNotification(
uint8_t aNumAttrs,
const BluetoothAvrcpPlayerAttribute* aAttrs) MOZ_OVERRIDE;
void GetPlayerAppValuesTextNotification(
uint8_t aAttrId, uint8_t aNumVals, const uint8_t* aValues) MOZ_OVERRIDE;
void SetPlayerAppValueNotification(
const BluetoothAvrcpPlayerSettings& aSettings) MOZ_OVERRIDE;
void GetElementAttrNotification(
uint8_t aNumAttrs,
const BluetoothAvrcpMediaAttribute* aAttrs) MOZ_OVERRIDE;
void RegisterNotificationNotification(
BluetoothAvrcpEvent aEvent, uint32_t aParam) MOZ_OVERRIDE;
void RemoteFeatureNotification(
const nsAString& aBdAddr, unsigned long aFeatures) MOZ_OVERRIDE;
void VolumeChangeNotification(uint8_t aVolume, uint8_t aCType) MOZ_OVERRIDE;
void PassthroughCmdNotification(int aId, int aKeyState) MOZ_OVERRIDE;
nsString mDeviceAddress;
nsRefPtr<BluetoothProfileController> mController;