Bug 1061126: Make Bluetooth AVRCP interface generally available, r=shuang

The methods of |BluetoothAVRCPInterface| are now always available. On
Android versions before 18, which don't support AVRCP, they always
fail with STATUS_UNSUPPORTED.
This commit is contained in:
Thomas Zimmermann 2014-09-02 12:46:07 +02:00
parent 10ae671228
commit 1234f00e91
2 changed files with 105 additions and 22 deletions

View File

@ -4,11 +4,11 @@
* 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"
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include "base/message_loop.h"
#include "BluetoothInterface.h"
#include "nsAutoPtr.h"
#include "nsThreadUtils.h"
#include "nsXULAppAPI.h"
@ -2986,6 +2986,7 @@ struct interface_traits<BluetoothAvrcpInterface>
return BT_PROFILE_AV_RC_ID;
}
};
#endif
typedef
BluetoothInterfaceRunnable0<BluetoothAvrcpResultHandler, void>
@ -3018,7 +3019,6 @@ DispatchBluetoothAvrcpResult(
}
return rv;
}
#endif
// Notification handling
//
@ -3026,7 +3026,6 @@ DispatchBluetoothAvrcpResult(
BluetoothAvrcpNotificationHandler::~BluetoothAvrcpNotificationHandler()
{ }
#if ANDROID_VERSION >= 18
static BluetoothAvrcpNotificationHandler* sAvrcpNotificationHandler;
struct BluetoothAvrcpCallback
@ -3092,7 +3091,6 @@ struct BluetoothAvrcpCallback
BluetoothAvrcpEvent, uint32_t>
RegisterNotificationNotification;
#if ANDROID_VERSION >= 19
typedef BluetoothNotificationRunnable2<AvrcpNotificationHandlerWrapper,
void,
nsString, unsigned long,
@ -3108,10 +3106,10 @@ struct BluetoothAvrcpCallback
void,
int, int>
PassthroughCmdNotification;
#endif // ANDROID_VERSION >= 19
// Bluedroid AVRCP callbacks
#if ANDROID_VERSION >= 18
static void
GetPlayStatus()
{
@ -3181,6 +3179,7 @@ struct BluetoothAvrcpCallback
&BluetoothAvrcpNotificationHandler::RegisterNotificationNotification,
aEvent, aParam);
}
#endif // ANDROID_VERSION >= 18
#if ANDROID_VERSION >= 19
static void
@ -3213,10 +3212,17 @@ struct BluetoothAvrcpCallback
//
BluetoothAvrcpInterface::BluetoothAvrcpInterface(
const btrc_interface_t* aInterface)
#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
}
BluetoothAvrcpInterface::~BluetoothAvrcpInterface()
@ -3227,6 +3233,7 @@ BluetoothAvrcpInterface::Init(
BluetoothAvrcpNotificationHandler* aNotificationHandler,
BluetoothAvrcpResultHandler* aRes)
{
#if ANDROID_VERSION >= 18
static btrc_callbacks_t sCallbacks = {
sizeof(sCallbacks),
#if ANDROID_VERSION >= 19
@ -3247,10 +3254,15 @@ BluetoothAvrcpInterface::Init(
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) {
DispatchBluetoothAvrcpResult(aRes, &BluetoothAvrcpResultHandler::Init,
@ -3261,7 +3273,9 @@ BluetoothAvrcpInterface::Init(
void
BluetoothAvrcpInterface::Cleanup(BluetoothAvrcpResultHandler* aRes)
{
#if ANDROID_VERSION >= 18
mInterface->cleanup();
#endif
if (aRes) {
DispatchBluetoothAvrcpResult(aRes, &BluetoothAvrcpResultHandler::Cleanup,
@ -3275,6 +3289,8 @@ BluetoothAvrcpInterface::GetPlayStatusRsp(ControlPlayStatus aPlayStatus,
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
btrc_play_status_t playStatus = BTRC_PLAYSTATE_STOPPED;
if (!(NS_FAILED(Convert(aPlayStatus, playStatus)))) {
@ -3282,6 +3298,9 @@ BluetoothAvrcpInterface::GetPlayStatusRsp(ControlPlayStatus aPlayStatus,
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpResult(
@ -3296,6 +3315,8 @@ BluetoothAvrcpInterface::ListPlayerAppAttrRsp(
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
ConvertArray<BluetoothAvrcpPlayerAttribute> pAttrsArray(aPAttrs, aNumAttr);
nsAutoArrayPtr<btrc_player_attr_t> pAttrs;
@ -3304,6 +3325,9 @@ BluetoothAvrcpInterface::ListPlayerAppAttrRsp(
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpResult(
@ -3316,7 +3340,11 @@ void
BluetoothAvrcpInterface::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) {
DispatchBluetoothAvrcpResult(
@ -3331,6 +3359,8 @@ BluetoothAvrcpInterface::GetPlayerAppValueRsp(
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
btrc_player_settings_t pVals;
/* FIXME: you need to implement the missing conversion functions */
@ -3341,6 +3371,9 @@ BluetoothAvrcpInterface::GetPlayerAppValueRsp(
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpResult(
@ -3355,6 +3388,8 @@ BluetoothAvrcpInterface::GetPlayerAppAttrTextRsp(
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 */
@ -3365,6 +3400,9 @@ BluetoothAvrcpInterface::GetPlayerAppAttrTextRsp(
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpResult(
@ -3379,6 +3417,8 @@ BluetoothAvrcpInterface::GetPlayerAppValueTextRsp(
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 */
@ -3389,6 +3429,9 @@ BluetoothAvrcpInterface::GetPlayerAppValueTextRsp(
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpResult(
@ -3403,6 +3446,8 @@ BluetoothAvrcpInterface::GetElementAttrRsp(
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
ConvertArray<BluetoothAvrcpElementAttribute> pAttrsArray(aAttrs, aNumAttr);
nsAutoArrayPtr<btrc_element_attr_val_t> pAttrs;
@ -3411,6 +3456,9 @@ BluetoothAvrcpInterface::GetElementAttrRsp(
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpResult(
@ -3424,6 +3472,8 @@ BluetoothAvrcpInterface::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))) {
@ -3431,6 +3481,9 @@ BluetoothAvrcpInterface::SetPlayerAppValueRsp(
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpResult(
@ -3445,8 +3498,10 @@ BluetoothAvrcpInterface::RegisterNotificationRsp(
const BluetoothAvrcpNotificationParam& aParam,
BluetoothAvrcpResultHandler* aRes)
{
nsresult rv;
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;
@ -3489,6 +3544,9 @@ BluetoothAvrcpInterface::RegisterNotificationRsp(
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpResult(
@ -3513,7 +3571,6 @@ BluetoothAvrcpInterface::SetVolume(uint8_t aVolume,
ConvertDefault(status, STATUS_FAIL));
}
}
#endif
//
// Bluetooth Core Interface
@ -4292,14 +4349,8 @@ BluetoothInterface::LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
template <class T>
T*
BluetoothInterface::GetProfileInterface()
BluetoothInterface::CreateProfileInterface()
{
static T* sBluetoothProfileInterface;
if (sBluetoothProfileInterface) {
return sBluetoothProfileInterface;
}
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()));
@ -4315,7 +4366,36 @@ BluetoothInterface::GetProfileInterface()
return nullptr;
}
sBluetoothProfileInterface = new T(interface);
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 <>
BluetoothAvrcpInterface*
BluetoothInterface::CreateProfileInterface<BluetoothAvrcpInterface>()
{
BT_WARNING("Bluetooth profile 'avrcp' is not supported");
return new BluetoothAvrcpInterface();
}
#endif
template <class T>
T*
BluetoothInterface::GetProfileInterface()
{
static T* sBluetoothProfileInterface;
if (sBluetoothProfileInterface) {
return sBluetoothProfileInterface;
}
sBluetoothProfileInterface = CreateProfileInterface<T>();
return sBluetoothProfileInterface;
}
@ -4341,11 +4421,7 @@ BluetoothInterface::GetBluetoothA2dpInterface()
BluetoothAvrcpInterface*
BluetoothInterface::GetBluetoothAvrcpInterface()
{
#if ANDROID_VERSION >= 18
return GetProfileInterface<BluetoothAvrcpInterface>();
#else
return nullptr;
#endif
}
END_BLUETOOTH_NAMESPACE

View File

@ -427,7 +427,6 @@ public:
class BluetoothAvrcpInterface
{
#if ANDROID_VERSION >= 18
public:
friend class BluetoothInterface;
@ -473,10 +472,15 @@ public:
void SetVolume(uint8_t aVolume, BluetoothAvrcpResultHandler* aRes);
protected:
BluetoothAvrcpInterface(const btrc_interface_t* aInterface);
BluetoothAvrcpInterface(
#if ANDROID_VERSION >= 18
const btrc_interface_t* aInterface
#endif
);
~BluetoothAvrcpInterface();
private:
#if ANDROID_VERSION >= 18
const btrc_interface_t* mInterface;
#endif
};
@ -657,6 +661,9 @@ protected:
~BluetoothInterface();
private:
template <class T>
T* CreateProfileInterface();
template <class T>
T* GetProfileInterface();