diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index a840382704c8..62811d8fa283 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
-
+
@@ -23,7 +23,7 @@
-
+
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 16be74455f3c..bfbcce6d3fb7 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,13 +19,13 @@
-
+
-
+
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 5d1f4f2b87c2..a9ab9a179972 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,10 +17,10 @@
-
+
-
+
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index 50b84e85dab8..aa692e4a947f 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
-
+
@@ -23,7 +23,7 @@
-
+
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 16be74455f3c..bfbcce6d3fb7 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,13 +19,13 @@
-
+
-
+
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index 8a3f371adc25..6a7e53c3c4ac 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
-
+
@@ -23,7 +23,7 @@
-
+
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index 1be6c92a12e1..50d72278824a 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,10 +17,10 @@
-
+
-
+
@@ -122,7 +122,7 @@
-
+
diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 9336f8428c08..c624c4a4b6b0 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
- "revision": "bce92f813f48346b36ce9dffc16b0c93d0ac8330",
+ "revision": "14400ee07e836d74039e2317feebc0a13fcb60c8",
"repo_path": "/integration/gaia-central"
}
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index ada352510cfb..1a072435d2e2 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,12 +17,12 @@
-
+
-
+
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index fa3ce0781c32..6d3ddcb11a11 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index dc69b0b317cd..293c7beff0d5 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,10 +17,10 @@
-
+
-
+
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index b4b0695a8ee0..2aa0fb97bcc2 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,12 +17,12 @@
-
+
-
+
diff --git a/dom/bluetooth/BluetoothCommon.h b/dom/bluetooth/BluetoothCommon.h
index e15273ec2299..9667957694c7 100644
--- a/dom/bluetooth/BluetoothCommon.h
+++ b/dom/bluetooth/BluetoothCommon.h
@@ -339,6 +339,19 @@ enum BluetoothObjectType {
TYPE_INVALID
};
+enum BluetoothA2dpAudioState {
+ A2DP_AUDIO_STATE_REMOTE_SUSPEND,
+ A2DP_AUDIO_STATE_STOPPED,
+ A2DP_AUDIO_STATE_STARTED,
+};
+
+enum BluetoothA2dpConnectionState {
+ A2DP_CONNECTION_STATE_DISCONNECTED,
+ A2DP_CONNECTION_STATE_CONNECTING,
+ A2DP_CONNECTION_STATE_CONNECTED,
+ A2DP_CONNECTION_STATE_DISCONNECTING
+};
+
enum ControlPlayStatus {
PLAYSTATUS_STOPPED = 0x00,
PLAYSTATUS_PLAYING = 0x01,
@@ -349,6 +362,16 @@ enum ControlPlayStatus {
PLAYSTATUS_ERROR = 0xFF,
};
+enum BluetoothAvrcpMediaAttribute {
+ AVRCP_MEDIA_ATTRIBUTE_TITLE,
+ AVRCP_MEDIA_ATTRIBUTE_ARTIST,
+ AVRCP_MEDIA_ATTRIBUTE_ALBUM,
+ AVRCP_MEDIA_ATTRIBUTE_TRACK_NUM,
+ AVRCP_MEDIA_ATTRIBUTE_NUM_TRACKS,
+ AVRCP_MEDIA_ATTRIBUTE_GENRE,
+ AVRCP_MEDIA_ATTRIBUTE_PLAYING_TIME
+};
+
enum BluetoothAvrcpPlayerAttribute {
AVRCP_PLAYER_ATTRIBUTE_EQUALIZER,
AVRCP_PLAYER_ATTRIBUTE_REPEAT,
@@ -378,6 +401,13 @@ enum BluetoothAvrcpNotification {
AVRCP_NTF_CHANGED
};
+enum BluetoothAvrcpRemoteFeature {
+ AVRCP_REMOTE_FEATURE_NONE,
+ AVRCP_REMOTE_FEATURE_METADATA,
+ AVRCP_REMOTE_FEATURE_ABSOLUTE_VOLUME,
+ AVRCP_REMOTE_FEATURE_BROWSE
+};
+
struct BluetoothAvrcpElementAttribute {
uint32_t mId;
nsString mValue;
@@ -392,6 +422,12 @@ struct BluetoothAvrcpNotificationParam {
uint8_t mValues[256];
};
+struct BluetoothAvrcpPlayerSettings {
+ uint8_t mNumAttr;
+ uint8_t mIds[256];
+ uint8_t mValues[256];
+};
+
END_BLUETOOTH_NAMESPACE
#endif // mozilla_dom_bluetooth_bluetoothcommon_h__
diff --git a/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp b/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp
index 882274386237..f82d6ae7cc59 100644
--- a/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp
@@ -7,7 +7,6 @@
#include "base/basictypes.h"
#include "BluetoothA2dpManager.h"
-#include "BluetoothInterface.h"
#include "BluetoothCommon.h"
#include "BluetoothService.h"
#include "BluetoothSocket.h"
@@ -37,171 +36,42 @@ namespace {
#endif
} // 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;
-};
-
-class RequestPlayStatusTask : public nsRunnable
-{
-public:
- RequestPlayStatusTask()
- {
- MOZ_ASSERT(!NS_IsMainThread());
- }
-
- nsresult Run()
- {
- MOZ_ASSERT(NS_IsMainThread());
-
- BluetoothSignal signal(NS_LITERAL_STRING(REQUEST_MEDIA_PLAYSTATUS_ID),
- NS_LITERAL_STRING(KEY_ADAPTER),
- InfallibleTArray());
-
- BluetoothService* bs = BluetoothService::Get();
- NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
- bs->DistributeSignal(signal);
-
- return NS_OK;
- }
-};
-
#if ANDROID_VERSION > 17
-class UpdateRegisterNotificationTask : public nsRunnable
-{
-public:
- UpdateRegisterNotificationTask(BluetoothAvrcpEvent aEvent, uint32_t aParam)
- : mEvent(aEvent)
- , mParam(aParam)
- {
- MOZ_ASSERT(!NS_IsMainThread());
- }
-
- nsresult Run()
- {
- MOZ_ASSERT(NS_IsMainThread());
-
- BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
- NS_ENSURE_TRUE(a2dp, NS_OK);
- a2dp->UpdateRegisterNotification(mEvent, mParam);
- return NS_OK;
- }
-private:
- BluetoothAvrcpEvent mEvent;
- uint32_t mParam;
-};
-
/*
* This function maps attribute id and returns corresponding values
- * Attribute id refers to btrc_media_attr_t in bt_rc.h
*/
static void
-ConvertAttributeString(int aAttrId, nsAString& aAttrStr)
+ConvertAttributeString(BluetoothAvrcpMediaAttribute aAttrId,
+ nsAString& aAttrStr)
{
BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
NS_ENSURE_TRUE_VOID(a2dp);
switch (aAttrId) {
- case BTRC_MEDIA_ATTR_TITLE:
+ case AVRCP_MEDIA_ATTRIBUTE_TITLE:
a2dp->GetTitle(aAttrStr);
break;
- case BTRC_MEDIA_ATTR_ARTIST:
+ case AVRCP_MEDIA_ATTRIBUTE_ARTIST:
a2dp->GetArtist(aAttrStr);
break;
- case BTRC_MEDIA_ATTR_ALBUM:
+ case AVRCP_MEDIA_ATTRIBUTE_ALBUM:
a2dp->GetAlbum(aAttrStr);
break;
- case BTRC_MEDIA_ATTR_TRACK_NUM:
+ case AVRCP_MEDIA_ATTRIBUTE_TRACK_NUM:
aAttrStr.AppendInt(a2dp->GetMediaNumber());
break;
- case BTRC_MEDIA_ATTR_NUM_TRACKS:
+ case AVRCP_MEDIA_ATTRIBUTE_NUM_TRACKS:
aAttrStr.AppendInt(a2dp->GetTotalMediaNumber());
break;
- case BTRC_MEDIA_ATTR_GENRE:
+ case AVRCP_MEDIA_ATTRIBUTE_GENRE:
// TODO: we currently don't support genre from music player
aAttrStr.Truncate();
break;
- case BTRC_MEDIA_ATTR_PLAYING_TIME:
+ case AVRCP_MEDIA_ATTRIBUTE_PLAYING_TIME:
aAttrStr.AppendInt(a2dp->GetDuration());
break;
}
}
-
-class UpdateElementAttrsTask : public nsRunnable
-{
-public:
- UpdateElementAttrsTask(uint8_t aNumAttr, const btrc_media_attr_t* aPlayerAttrs)
- : mNumAttr(aNumAttr)
- {
- MOZ_ASSERT(!NS_IsMainThread());
-
- mAttrs = new BluetoothAvrcpElementAttribute[mNumAttr];
-
- for (uint8_t i = 0; i < mNumAttr; ++i) {
- mAttrs[i].mId = aPlayerAttrs[i];
- }
- }
-
- nsresult Run()
- {
- MOZ_ASSERT(NS_IsMainThread());
-
- for (uint8_t i = 0; i < mNumAttr; ++i) {
- ConvertAttributeString(mAttrs[i].mId, mAttrs[i].mValue);
- }
-
- NS_ENSURE_TRUE(sBtAvrcpInterface, NS_OK);
- sBtAvrcpInterface->GetElementAttrRsp(mNumAttr, mAttrs, nullptr);
-
- return NS_OK;
- }
-
-private:
- uint8_t mNumAttr;
- nsAutoArrayPtr mAttrs;
-};
-
-class UpdatePassthroughCmdTask : public nsRunnable
-{
-public:
- UpdatePassthroughCmdTask(const nsAString& aName)
- : mName(aName)
- {
- MOZ_ASSERT(!NS_IsMainThread());
- }
-
- nsresult Run()
- {
- MOZ_ASSERT(NS_IsMainThread());
-
- NS_NAMED_LITERAL_STRING(type, "media-button");
- BroadcastSystemMessage(type, BluetoothValue(mName));
-
- return NS_OK;
- }
-private:
- nsString mName;
-};
-
#endif
NS_IMETHODIMP
@@ -233,288 +103,21 @@ BluetoothA2dpManager::Reset()
}
static void
-AvStatusToSinkString(btav_connection_state_t aStatus, nsAString& aState)
+AvStatusToSinkString(BluetoothA2dpConnectionState aState, nsAString& aString)
{
- 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 const nsLiteralString sString[] = {
+ [A2DP_CONNECTION_STATE_DISCONNECTED] = NS_LITERAL_STRING("disconnected"),
+ [A2DP_CONNECTION_STATE_CONNECTING] = NS_LITERAL_STRING("connecting"),
+ [A2DP_CONNECTION_STATE_CONNECTED] = NS_LITERAL_STRING("connected"),
+ [A2DP_CONNECTION_STATE_DISCONNECTING] = NS_LITERAL_STRING("disconnecting")
+ };
+ if (aState >= MOZ_ARRAY_LENGTH(sString)) {
+ BT_WARNING("Unknown sink state %d", static_cast(aState));
+ return;
}
+ aString = sString[aState];
}
-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 props;
- BT_APPEND_NAMED_VALUE(props, "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 props;
- BT_APPEND_NAMED_VALUE(props, "State", a2dpState);
-
- BluetoothSignal signal(NS_LITERAL_STRING("AudioSink"),
- remoteDeviceBdAddress, props);
- NS_DispatchToMainThread(new SinkPropertyChangedHandler(signal));
-}
-
-#if ANDROID_VERSION > 17
-/*
- * Avrcp 1.3 callbacks
- */
-
-/*
- * This function is to request Gaia player application to update
- * current play status.
- * Callback for play status request
- */
-static void
-AvrcpGetPlayStatusCallback()
-{
- MOZ_ASSERT(!NS_IsMainThread());
-
- NS_DispatchToMainThread(new RequestPlayStatusTask());
-}
-
-/*
- * This function is trying to get element attributes, which request from CT
- * Unlike BlueZ only calls UpdateMetaData, bluedroid does not cache meta data
- * information, but instead uses callback AvrcpGetElementAttrCallback and
- * call get_element_attr_rsp() to reply request.
- *
- * Callback to fetch the get element attributes of the current song
- * aNumAttr: It represents the number of attributes requested in aPlayerAttrs
- * aPlayerAttrs: It represents Attribute Ids
- */
-static void
-AvrcpGetElementAttrCallback(uint8_t aNumAttr, btrc_media_attr_t* aPlayerAttrs)
-{
- MOZ_ASSERT(!NS_IsMainThread());
-
- NS_DispatchToMainThread(new UpdateElementAttrsTask(aNumAttr, aPlayerAttrs));
-}
-
-/*
- * Callback for register notification (Play state change/track change/...)
- * To reply RegisterNotification INTERIM response
- * See AVRCP 1.3 Spec 25.2
- * aParam: It only valids if event_id is BTRC_EVT_PLAY_POS_CHANGED,
- * which is playback interval time
- */
-static void
-AvrcpRegisterNotificationCallback(btrc_event_id_t aEventId, uint32_t aParam)
-{
- BluetoothAvrcpEvent event;
-
- MOZ_ASSERT(!NS_IsMainThread());
-
- switch (aEventId) {
- case BTRC_EVT_PLAY_STATUS_CHANGED:
- event = AVRCP_EVENT_PLAY_STATUS_CHANGED;
- case BTRC_EVT_TRACK_CHANGE:
- event = AVRCP_EVENT_TRACK_CHANGE;
- case BTRC_EVT_TRACK_REACHED_END:
- event = AVRCP_EVENT_TRACK_REACHED_END;
- case BTRC_EVT_TRACK_REACHED_START:
- event = AVRCP_EVENT_TRACK_REACHED_START;
- case BTRC_EVT_PLAY_POS_CHANGED:
- event = AVRCP_EVENT_PLAY_POS_CHANGED;
- case BTRC_EVT_APP_SETTINGS_CHANGED:
- event = AVRCP_EVENT_APP_SETTINGS_CHANGED;
- break;
- default:
- BT_LOGR("Unknown event 0x%x", aEventId);
- return;
- }
-
- NS_DispatchToMainThread(new UpdateRegisterNotificationTask(event, aParam));
-}
-
-/*
- * Player application settings is optional for Avrcp 1.3
- * B2G 1.3 currently does not support Player application setting
- * related functions. Support Player Setting in the future version
- */
-static void
-AvrcpListPlayerAppAttributeCallback()
-{
- MOZ_ASSERT(!NS_IsMainThread());
-
-// TODO: Support avrcp application setting related functions
-}
-
-static void
-AvrcpListPlayerAppValuesCallback(btrc_player_attr_t aAttrId)
-{
- MOZ_ASSERT(!NS_IsMainThread());
-
-// TODO: Support avrcp application setting related functions
-}
-
-static void
-AvrcpGetPlayerAppValueCallback(uint8_t aNumAttr,
- btrc_player_attr_t* aPlayerAttrs)
-{
- MOZ_ASSERT(!NS_IsMainThread());
-
-// TODO: Support avrcp application setting related functions
-}
-
-static void
-AvrcpGetPlayerAppAttrsTextCallback(uint8_t aNumAttr,
- btrc_player_attr_t* PlayerAttrs)
-{
- MOZ_ASSERT(!NS_IsMainThread());
-
-// TODO: Support avrcp application setting related functions
-}
-
-static void
-AvrcpGetPlayerAppValuesTextCallback(uint8_t aAttrId, uint8_t aNumVal,
- uint8_t* PlayerVals)
-{
- MOZ_ASSERT(!NS_IsMainThread());
-
-// TODO: Support avrcp application setting related functions
-}
-
-static void
-AvrcpSetPlayerAppValueCallback(btrc_player_settings_t* aPlayerVals)
-{
- MOZ_ASSERT(!NS_IsMainThread());
-
-// TODO: Support avrcp application setting related functions
-}
-#endif
-
-#if ANDROID_VERSION > 18
-/*
- * This callback function is to get CT features from Feature Bit Mask.
- * If Advanced Control Player bit is set, CT supports
- * volume sync (absolute volume feature). If Browsing bit is set, Avrcp 1.4
- * Browse feature will be supported
- */
-static void
-AvrcpRemoteFeaturesCallback(bt_bdaddr_t* aBdAddress,
- btrc_remote_features_t aFeatures)
-{
-// TODO: Support avrcp 1.4 absolute volume/browse
-}
-
-/*
- * This callback function is to get notification that volume changed on the
- * remote car kit (if it supports Avrcp 1.4), not notification from phone.
- */
-static void
-AvrcpRemoteVolumeChangedCallback(uint8_t aVolume, uint8_t aCType)
-{
-// TODO: Support avrcp 1.4 absolute volume/browse
-}
-
-/*
- * This callback function is to handle passthrough commands.
- */
-static void
-AvrcpPassThroughCallback(int aId, int aKeyState)
-{
- // 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);
- break;
- }
- if (!name.IsEmpty()) {
- NS_DispatchToMainThread(new UpdatePassthroughCmdTask(name));
- }
-}
-#endif
-
-static btav_callbacks_t sBtA2dpCallbacks = {
- sizeof(sBtA2dpCallbacks),
- A2dpConnectionStateCallback,
- A2dpAudioStateCallback
-};
-
-#if ANDROID_VERSION > 17
-static btrc_callbacks_t sBtAvrcpCallbacks = {
- sizeof(sBtAvrcpCallbacks),
-#if ANDROID_VERSION > 18
- AvrcpRemoteFeaturesCallback,
-#endif
- AvrcpGetPlayStatusCallback,
- AvrcpListPlayerAppAttributeCallback,
- AvrcpListPlayerAppValuesCallback,
- AvrcpGetPlayerAppValueCallback,
- AvrcpGetPlayerAppAttrsTextCallback,
- AvrcpGetPlayerAppValuesTextCallback,
- AvrcpSetPlayerAppValueCallback,
- AvrcpGetElementAttrCallback,
- AvrcpRegisterNotificationCallback,
-#if ANDROID_VERSION > 18
- AvrcpRemoteVolumeChangedCallback,
- AvrcpPassThroughCallback
-#endif
-};
-#endif
-
#if ANDROID_VERSION > 17
class InitAvrcpResultHandler MOZ_FINAL : public BluetoothAvrcpResultHandler
{
@@ -570,8 +173,8 @@ public:
sBtAvrcpInterface = btInf->GetBluetoothAvrcpInterface();
NS_ENSURE_TRUE_VOID(sBtAvrcpInterface);
- sBtAvrcpInterface->Init(&sBtAvrcpCallbacks,
- new InitAvrcpResultHandler(mRes));
+ BluetoothA2dpManager* a2dpManager = BluetoothA2dpManager::Get();
+ sBtAvrcpInterface->Init(a2dpManager, new InitAvrcpResultHandler(mRes));
#else
/* ...or signal success otherwise. */
if (mRes) {
@@ -600,7 +203,8 @@ BluetoothA2dpManager::InitA2dpInterface(BluetoothProfileResultHandler* aRes)
sBtA2dpInterface = btInf->GetBluetoothA2dpInterface();
NS_ENSURE_TRUE_VOID(sBtA2dpInterface);
- sBtA2dpInterface->Init(&sBtA2dpCallbacks, new InitA2dpResultHandler(aRes));
+ BluetoothA2dpManager* a2dpManager = BluetoothA2dpManager::Get();
+ sBtA2dpInterface->Init(a2dpManager, new InitA2dpResultHandler(aRes));
}
BluetoothA2dpManager::~BluetoothA2dpManager()
@@ -1305,5 +909,230 @@ 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 props;
+ BT_APPEND_NAMED_VALUE(props, "State", a2dpState);
+
+ HandleSinkPropertyChanged(BluetoothSignal(NS_LITERAL_STRING("AudioSink"),
+ nsString(aBdAddr), props));
+}
+
+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 props;
+ BT_APPEND_NAMED_VALUE(props, "State", a2dpState);
+
+ HandleSinkPropertyChanged(BluetoothSignal(NS_LITERAL_STRING("AudioSink"),
+ nsString(aBdAddr), props));
+}
+
+/*
+ * AVRCP Notifications
+ */
+
+void
+BluetoothA2dpManager::GetPlayStatusNotification()
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ BluetoothService* bs = BluetoothService::Get();
+ if (!bs) {
+ return;
+ }
+
+ bs->DistributeSignal(
+ BluetoothSignal(NS_LITERAL_STRING(REQUEST_MEDIA_PLAYSTATUS_ID),
+ NS_LITERAL_STRING(KEY_ADAPTER),
+ InfallibleTArray()));
+}
+
+/* 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());
+
+ nsAutoArrayPtr attrs(
+ new BluetoothAvrcpElementAttribute[aNumAttrs]);
+
+ for (uint8_t i = 0; i < aNumAttrs; ++i) {
+ attrs[i].mId = aAttrs[i];
+ ConvertAttributeString(
+ static_cast(attrs[i].mId),
+ attrs[i].mValue);
+ }
+
+#if ANDROID_VERSION >= 18
+ MOZ_ASSERT(sBtAvrcpInterface);
+ sBtAvrcpInterface->GetElementAttrRsp(aNumAttrs, attrs, nullptr);
+#endif // ANDROID_VERSION >= 18
+}
+
+void
+BluetoothA2dpManager::RegisterNotificationNotification(
+ BluetoothAvrcpEvent aEvent, uint32_t aParam)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
+ if (!a2dp) {
+ return;
+ }
+
+#if ANDROID_VERSION >= 18
+ a2dp->UpdateRegisterNotification(aEvent, aParam);
+#endif // ANDROID_VERSION >= 18
+}
+
+/* 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_NAMED_LITERAL_STRING(type, "media-button");
+ BroadcastSystemMessage(type, BluetoothValue(name));
+}
+
NS_IMPL_ISUPPORTS(BluetoothA2dpManager, nsIObserver)
diff --git a/dom/bluetooth/bluedroid/BluetoothA2dpManager.h b/dom/bluetooth/bluedroid/BluetoothA2dpManager.h
index b37decab42a4..1c34607a5c68 100644
--- a/dom/bluetooth/bluedroid/BluetoothA2dpManager.h
+++ b/dom/bluetooth/bluedroid/BluetoothA2dpManager.h
@@ -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 mController;
diff --git a/dom/bluetooth/bluedroid/BluetoothInterface.cpp b/dom/bluetooth/bluedroid/BluetoothInterface.cpp
index 4802cdbb5e80..6a520b9f7e93 100644
--- a/dom/bluetooth/bluedroid/BluetoothInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothInterface.cpp
@@ -436,18 +436,6 @@ Convert(bt_device_type_t aIn, BluetoothDeviceType& aOut)
return NS_OK;
}
-#if ANDROID_VERSION >= 18
-static nsresult
-Convert(const bt_remote_version_t& aIn, BluetoothRemoteInfo& aOut)
-{
- aOut.mVerMajor = aIn.version;
- aOut.mVerMinor = aIn.sub_ver;
- aOut.mManufacturer = aIn.manufacturer;
-
- return NS_OK;
-}
-#endif
-
static nsresult
Convert(const bt_service_record_t& aIn, BluetoothServiceRecord& aOut)
{
@@ -715,7 +703,52 @@ Convert(bthf_volume_type_t aIn, BluetoothHandsfreeVolumeType& aOut)
return NS_OK;
}
+static nsresult
+Convert(btav_connection_state_t aIn, BluetoothA2dpConnectionState& aOut)
+{
+ static const BluetoothA2dpConnectionState sConnectionState[] = {
+ CONVERT(BTAV_CONNECTION_STATE_DISCONNECTED,
+ A2DP_CONNECTION_STATE_DISCONNECTED),
+ CONVERT(BTAV_CONNECTION_STATE_CONNECTING,
+ A2DP_CONNECTION_STATE_CONNECTING),
+ CONVERT(BTAV_CONNECTION_STATE_CONNECTED,
+ A2DP_CONNECTION_STATE_CONNECTED),
+ CONVERT(BTAV_CONNECTION_STATE_DISCONNECTING,
+ A2DP_CONNECTION_STATE_DISCONNECTING),
+ };
+ if (aIn >= MOZ_ARRAY_LENGTH(sConnectionState)) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sConnectionState[aIn];
+ return NS_OK;
+}
+
+static nsresult
+Convert(btav_audio_state_t aIn, BluetoothA2dpAudioState& aOut)
+{
+ static const BluetoothA2dpAudioState sAudioState[] = {
+ CONVERT(BTAV_AUDIO_STATE_REMOTE_SUSPEND, A2DP_AUDIO_STATE_REMOTE_SUSPEND),
+ CONVERT(BTAV_AUDIO_STATE_STOPPED, A2DP_AUDIO_STATE_STOPPED),
+ CONVERT(BTAV_AUDIO_STATE_STARTED, A2DP_AUDIO_STATE_STARTED),
+ };
+ if (aIn >= MOZ_ARRAY_LENGTH(sAudioState)) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sAudioState[aIn];
+ return NS_OK;
+}
+
#if ANDROID_VERSION >= 18
+static nsresult
+Convert(const bt_remote_version_t& aIn, BluetoothRemoteInfo& aOut)
+{
+ aOut.mVerMajor = aIn.version;
+ aOut.mVerMinor = aIn.sub_ver;
+ aOut.mManufacturer = aIn.manufacturer;
+
+ return NS_OK;
+}
+
static nsresult
Convert(ControlPlayStatus aIn, btrc_play_status_t& aOut)
{
@@ -749,6 +782,23 @@ Convert(enum BluetoothAvrcpPlayerAttribute aIn, btrc_player_attr_t& aOut)
return NS_OK;
}
+static nsresult
+Convert(btrc_player_attr_t aIn, enum BluetoothAvrcpPlayerAttribute& aOut)
+{
+ static const BluetoothAvrcpPlayerAttribute sPlayerAttr[] = {
+ CONVERT(0, static_cast(0)), // invalid, [0] required by gcc
+ CONVERT(BTRC_PLAYER_ATTR_EQUALIZER, AVRCP_PLAYER_ATTRIBUTE_EQUALIZER),
+ CONVERT(BTRC_PLAYER_ATTR_REPEAT, AVRCP_PLAYER_ATTRIBUTE_REPEAT),
+ CONVERT(BTRC_PLAYER_ATTR_SHUFFLE, AVRCP_PLAYER_ATTRIBUTE_SHUFFLE),
+ CONVERT(BTRC_PLAYER_ATTR_SCAN, AVRCP_PLAYER_ATTRIBUTE_SCAN)
+ };
+ if (!aIn || aIn >= MOZ_ARRAY_LENGTH(sPlayerAttr)) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sPlayerAttr[aIn];
+ return NS_OK;
+}
+
static nsresult
Convert(enum BluetoothAvrcpStatus aIn, btrc_status_t& aOut)
{
@@ -784,6 +834,47 @@ Convert(enum BluetoothAvrcpEvent aIn, btrc_event_id_t& aOut)
return NS_OK;
}
+static nsresult
+Convert(btrc_event_id_t aIn, enum BluetoothAvrcpEvent& aOut)
+{
+ static const BluetoothAvrcpEvent sEventId[] = {
+ CONVERT(0, static_cast(0)), // invalid, [0] required by gcc
+ CONVERT(BTRC_EVT_PLAY_STATUS_CHANGED, AVRCP_EVENT_PLAY_STATUS_CHANGED),
+ CONVERT(BTRC_EVT_TRACK_CHANGE, AVRCP_EVENT_TRACK_CHANGE),
+ CONVERT(BTRC_EVT_TRACK_REACHED_END, AVRCP_EVENT_TRACK_REACHED_END),
+ CONVERT(BTRC_EVT_TRACK_REACHED_START, AVRCP_EVENT_TRACK_REACHED_START),
+ CONVERT(BTRC_EVT_PLAY_POS_CHANGED, AVRCP_EVENT_PLAY_POS_CHANGED),
+ CONVERT(6, static_cast(0)), // invalid, [6] required by gcc
+ CONVERT(7, static_cast(0)), // invalid, [7] required by gcc
+ CONVERT(BTRC_EVT_APP_SETTINGS_CHANGED, AVRCP_EVENT_APP_SETTINGS_CHANGED)
+ };
+ if (!aIn || aIn >= MOZ_ARRAY_LENGTH(sEventId)) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sEventId[aIn];
+ return NS_OK;
+}
+
+static nsresult
+Convert(btrc_media_attr_t aIn, enum BluetoothAvrcpMediaAttribute& aOut)
+{
+ static const BluetoothAvrcpMediaAttribute sEventId[] = {
+ CONVERT(0, static_cast(0)), // invalid, [0] required by gcc
+ CONVERT(BTRC_MEDIA_ATTR_TITLE, AVRCP_MEDIA_ATTRIBUTE_TITLE),
+ CONVERT(BTRC_MEDIA_ATTR_ARTIST, AVRCP_MEDIA_ATTRIBUTE_ARTIST),
+ CONVERT(BTRC_MEDIA_ATTR_ALBUM, AVRCP_MEDIA_ATTRIBUTE_ALBUM),
+ CONVERT(BTRC_MEDIA_ATTR_TRACK_NUM, AVRCP_MEDIA_ATTRIBUTE_TRACK_NUM),
+ CONVERT(BTRC_MEDIA_ATTR_NUM_TRACKS, AVRCP_MEDIA_ATTRIBUTE_NUM_TRACKS),
+ CONVERT(BTRC_MEDIA_ATTR_GENRE, AVRCP_MEDIA_ATTRIBUTE_GENRE),
+ CONVERT(BTRC_MEDIA_ATTR_PLAYING_TIME, AVRCP_MEDIA_ATTRIBUTE_PLAYING_TIME)
+ };
+ if (!aIn || aIn >= MOZ_ARRAY_LENGTH(sEventId)) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sEventId[aIn];
+ return NS_OK;
+}
+
static nsresult
Convert(enum BluetoothAvrcpNotification aIn, btrc_notification_type_t& aOut)
{
@@ -811,7 +902,28 @@ Convert(const BluetoothAvrcpElementAttribute& aIn, btrc_element_attr_val_t& aOut
return NS_OK;
}
-#endif
+static 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
+
+#if ANDROID_VERSION >= 19
+static nsresult
+Convert(btrc_remote_features_t aIn, unsigned long& aOut)
+{
+ /* The input type's name is misleading. The converted value is
+ * actually a bitmask.
+ */
+ aOut = static_cast(aIn);
+ return NS_OK;
+}
+#endif // ANDROID_VERSION >= 19
/* |ConvertArray| is a helper for converting arrays. Pass an
* instance of this structure as the first argument to |Convert|
@@ -2716,6 +2828,69 @@ DispatchBluetoothA2dpResult(
return rv;
}
+// Notification handling
+//
+
+BluetoothA2dpNotificationHandler::~BluetoothA2dpNotificationHandler()
+{ }
+
+static BluetoothA2dpNotificationHandler* sA2dpNotificationHandler;
+
+struct BluetoothA2dpCallback
+{
+ class A2dpNotificationHandlerWrapper
+ {
+ public:
+ typedef BluetoothA2dpNotificationHandler ObjectType;
+
+ static ObjectType* GetInstance()
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ return sA2dpNotificationHandler;
+ }
+ };
+
+ // Notifications
+
+ typedef BluetoothNotificationRunnable2
+ ConnectionStateNotification;
+
+ typedef BluetoothNotificationRunnable2
+ 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
+//
+
BluetoothA2dpInterface::BluetoothA2dpInterface(
const btav_interface_t* aInterface)
: mInterface(aInterface)
@@ -2727,10 +2902,19 @@ BluetoothA2dpInterface::~BluetoothA2dpInterface()
{ }
void
-BluetoothA2dpInterface::Init(btav_callbacks_t* aCallbacks,
- BluetoothA2dpResultHandler* aRes)
+BluetoothA2dpInterface::Init(
+ BluetoothA2dpNotificationHandler* aNotificationHandler,
+ BluetoothA2dpResultHandler* aRes)
{
- bt_status_t status = mInterface->init(aCallbacks);
+ static btav_callbacks_t sCallbacks = {
+ sizeof(sCallbacks),
+ BluetoothA2dpCallback::ConnectionState,
+ BluetoothA2dpCallback::AudioState
+ };
+
+ sA2dpNotificationHandler = aNotificationHandler;
+
+ bt_status_t status = mInterface->init(&sCallbacks);
if (aRes) {
DispatchBluetoothA2dpResult(aRes, &BluetoothA2dpResultHandler::Init,
@@ -2834,6 +3018,199 @@ DispatchBluetoothAvrcpResult(
}
return rv;
}
+#endif
+
+// Notification handling
+//
+
+BluetoothAvrcpNotificationHandler::~BluetoothAvrcpNotificationHandler()
+{ }
+
+#if ANDROID_VERSION >= 18
+static BluetoothAvrcpNotificationHandler* sAvrcpNotificationHandler;
+
+struct BluetoothAvrcpCallback
+{
+ class AvrcpNotificationHandlerWrapper
+ {
+ public:
+ typedef BluetoothAvrcpNotificationHandler ObjectType;
+
+ static ObjectType* GetInstance()
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ return sAvrcpNotificationHandler;
+ }
+ };
+
+ // Notifications
+
+ typedef BluetoothNotificationRunnable0
+ GetPlayStatusNotification;
+
+ typedef BluetoothNotificationRunnable0
+ ListPlayerAppAttrNotification;
+
+ typedef BluetoothNotificationRunnable1
+ ListPlayerAppValuesNotification;
+
+ typedef BluetoothNotificationRunnable2,
+ uint8_t, const BluetoothAvrcpPlayerAttribute*>
+ GetPlayerAppValueNotification;
+
+ typedef BluetoothNotificationRunnable2,
+ uint8_t, const BluetoothAvrcpPlayerAttribute*>
+ GetPlayerAppAttrsTextNotification;
+
+ typedef BluetoothNotificationRunnable3,
+ uint8_t, uint8_t, const uint8_t*>
+ GetPlayerAppValuesTextNotification;
+
+ typedef BluetoothNotificationRunnable1
+ SetPlayerAppValueNotification;
+
+ typedef BluetoothNotificationRunnable2,
+ uint8_t, const BluetoothAvrcpMediaAttribute*>
+ GetElementAttrNotification;
+
+ typedef BluetoothNotificationRunnable2
+ RegisterNotificationNotification;
+
+#if ANDROID_VERSION >= 19
+ typedef BluetoothNotificationRunnable2
+ RemoteFeatureNotification;
+
+ typedef BluetoothNotificationRunnable2
+ VolumeChangeNotification;
+
+ typedef BluetoothNotificationRunnable2
+ PassthroughCmdNotification;
+#endif // ANDROID_VERSION >= 19
+
+ // Bluedroid AVRCP callbacks
+
+ 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(aAttrs, aNumAttrs));
+ }
+
+ static void
+ GetPlayerAppAttrsText(uint8_t aNumAttrs, btrc_player_attr_t* aAttrs)
+ {
+ GetPlayerAppAttrsTextNotification::Dispatch(
+ &BluetoothAvrcpNotificationHandler::GetPlayerAppAttrsTextNotification,
+ aNumAttrs, ConvertArray(aAttrs, aNumAttrs));
+ }
+
+ static void
+ GetPlayerAppValuesText(uint8_t aAttrId, uint8_t aNumVals, uint8_t* aVals)
+ {
+ GetPlayerAppValuesTextNotification::Dispatch(
+ &BluetoothAvrcpNotificationHandler::GetPlayerAppValuesTextNotification,
+ aAttrId, aNumVals, ConvertArray(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(aAttrs, aNumAttrs));
+ }
+
+ static void
+ RegisterNotification(btrc_event_id_t aEvent, uint32_t aParam)
+ {
+ RegisterNotificationNotification::Dispatch(
+ &BluetoothAvrcpNotificationHandler::RegisterNotificationNotification,
+ aEvent, aParam);
+ }
+
+#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
+//
BluetoothAvrcpInterface::BluetoothAvrcpInterface(
const btrc_interface_t* aInterface)
@@ -2846,10 +3223,34 @@ BluetoothAvrcpInterface::~BluetoothAvrcpInterface()
{ }
void
-BluetoothAvrcpInterface::Init(btrc_callbacks_t* aCallbacks,
- BluetoothAvrcpResultHandler* aRes)
+BluetoothAvrcpInterface::Init(
+ BluetoothAvrcpNotificationHandler* aNotificationHandler,
+ BluetoothAvrcpResultHandler* aRes)
{
- bt_status_t status = mInterface->init(aCallbacks);
+ 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
+ };
+
+ sAvrcpNotificationHandler = aNotificationHandler;
+
+ bt_status_t status = mInterface->init(&sCallbacks);
if (aRes) {
DispatchBluetoothAvrcpResult(aRes, &BluetoothAvrcpResultHandler::Init,
diff --git a/dom/bluetooth/bluedroid/BluetoothInterface.h b/dom/bluetooth/bluedroid/BluetoothInterface.h
index 2b04fb144713..677c57ff3ff5 100644
--- a/dom/bluetooth/bluedroid/BluetoothInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothInterface.h
@@ -265,6 +265,26 @@ private:
// Bluetooth Advanced Audio Interface
//
+class BluetoothA2dpNotificationHandler
+{
+public:
+ virtual ~BluetoothA2dpNotificationHandler();
+
+ virtual void
+ ConnectionStateNotification(BluetoothA2dpConnectionState aState,
+ const nsAString& aBdAddr)
+ { }
+
+ virtual void
+ AudioStateNotification(BluetoothA2dpAudioState aState,
+ const nsAString& aBdAddr)
+ { }
+
+protected:
+ BluetoothA2dpNotificationHandler()
+ { }
+};
+
class BluetoothA2dpResultHandler
{
public:
@@ -288,7 +308,7 @@ class BluetoothA2dpInterface
public:
friend class BluetoothInterface;
- void Init(btav_callbacks_t *aCallbacks,
+ void Init(BluetoothA2dpNotificationHandler* aNotificationHandler,
BluetoothA2dpResultHandler* aRes);
void Cleanup(BluetoothA2dpResultHandler* aRes);
@@ -309,6 +329,69 @@ private:
// Bluetooth AVRCP Interface
//
+class BluetoothAvrcpNotificationHandler
+{
+public:
+ virtual ~BluetoothAvrcpNotificationHandler();
+
+ virtual void
+ GetPlayStatusNotification()
+ { }
+
+ virtual void
+ ListPlayerAppAttrNotification()
+ { }
+
+ virtual void
+ ListPlayerAppValuesNotification(BluetoothAvrcpPlayerAttribute aAttrId)
+ { }
+
+ virtual void
+ GetPlayerAppValueNotification(uint8_t aNumAttrs,
+ const BluetoothAvrcpPlayerAttribute* aAttrs)
+ { }
+
+ virtual void
+ GetPlayerAppAttrsTextNotification(uint8_t aNumAttrs,
+ const BluetoothAvrcpPlayerAttribute* aAttrs)
+ { }
+
+ virtual void
+ GetPlayerAppValuesTextNotification(uint8_t aAttrId, uint8_t aNumVals,
+ const uint8_t* aValues)
+ { }
+
+ virtual void
+ SetPlayerAppValueNotification(const BluetoothAvrcpPlayerSettings& aSettings)
+ { }
+
+ virtual void
+ GetElementAttrNotification(uint8_t aNumAttrs,
+ const BluetoothAvrcpMediaAttribute* aAttrs)
+ { }
+
+ virtual void
+ RegisterNotificationNotification(BluetoothAvrcpEvent aEvent,
+ uint32_t aParam)
+ { }
+
+ virtual void
+ RemoteFeatureNotification(const nsAString& aBdAddr, unsigned long aFeatures)
+ { }
+
+ virtual void
+ VolumeChangeNotification(uint8_t aVolume, uint8_t aCType)
+ { }
+
+ virtual void
+ PassthroughCmdNotification(int aId, int aKeyState)
+ { }
+
+protected:
+ BluetoothAvrcpNotificationHandler()
+ { }
+};
+
class BluetoothAvrcpResultHandler
{
public:
@@ -348,7 +431,7 @@ class BluetoothAvrcpInterface
public:
friend class BluetoothInterface;
- void Init(btrc_callbacks_t* aCallbacks,
+ void Init(BluetoothAvrcpNotificationHandler* aNotificationHandler,
BluetoothAvrcpResultHandler* aRes);
void Cleanup(BluetoothAvrcpResultHandler* aRes);
diff --git a/dom/bluetooth/bluedroid/BluetoothUtils.cpp b/dom/bluetooth/bluedroid/BluetoothUtils.cpp
index 7853ebf098ee..7054cb6f13b5 100644
--- a/dom/bluetooth/bluedroid/BluetoothUtils.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothUtils.cpp
@@ -22,19 +22,6 @@
BEGIN_BLUETOOTH_NAMESPACE
-void
-BdAddressTypeToString(bt_bdaddr_t* aBdAddressType, nsAString& aRetBdAddress)
-{
- uint8_t* addr = aBdAddressType->address;
- char bdstr[18];
-
- sprintf(bdstr, "%02x:%02x:%02x:%02x:%02x:%02x",
- (int)addr[0],(int)addr[1],(int)addr[2],
- (int)addr[3],(int)addr[4],(int)addr[5]);
-
- aRetBdAddress = NS_ConvertUTF8toUTF16(bdstr);
-}
-
uint16_t
UuidToServiceClassInt(const BluetoothUuid& mUuid)
{
diff --git a/dom/bluetooth/bluedroid/BluetoothUtils.h b/dom/bluetooth/bluedroid/BluetoothUtils.h
index 4cf0c470cb19..6d141a44e31e 100644
--- a/dom/bluetooth/bluedroid/BluetoothUtils.h
+++ b/dom/bluetooth/bluedroid/BluetoothUtils.h
@@ -7,8 +7,6 @@
#ifndef mozilla_dom_bluetooth_bluetoothutils_h__
#define mozilla_dom_bluetooth_bluetoothutils_h__
-#include
-
#include "BluetoothCommon.h"
#include "js/TypeDecls.h"
@@ -18,10 +16,6 @@ class BluetoothNamedValue;
class BluetoothValue;
class BluetoothReplyRunnable;
-void
-BdAddressTypeToString(bt_bdaddr_t* aBdAddressType,
- nsAString& aRetBdAddress);
-
uint16_t
UuidToServiceClassInt(const BluetoothUuid& mUuid);
diff --git a/dom/system/gonk/ril_worker.js b/dom/system/gonk/ril_worker.js
index ba6bb7c0b8fa..bb5df03ced41 100644
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -2383,9 +2383,15 @@ RilObject.prototype = {
let request = options.attach ? RIL_REQUEST_GPRS_ATTACH :
RIL_REQUEST_GPRS_DETACH;
this.context.Buf.simpleRequest(request, options);
+ return;
} else if (RILQUIRKS_SUBSCRIPTION_CONTROL && options.attach) {
this.context.Buf.simpleRequest(REQUEST_SET_DATA_SUBSCRIPTION, options);
+ return;
}
+
+ // We don't really send a request to rild, so instantly reply success to
+ // RadioInterfaceLayer.
+ this.sendChromeMessage(options);
},
/**