зеркало из https://github.com/mozilla/gecko-dev.git
Bug 842948 - Patch 1: Implement API for AVRCP 1.3, r=echou, sr=mrbkap
This commit is contained in:
Родитель
2bbddbc7b0
Коммит
5ab7491ae0
|
@ -17,6 +17,7 @@
|
||||||
#include "nsDOMClassInfo.h"
|
#include "nsDOMClassInfo.h"
|
||||||
#include "nsIDOMBluetoothDeviceEvent.h"
|
#include "nsIDOMBluetoothDeviceEvent.h"
|
||||||
#include "nsTArrayHelpers.h"
|
#include "nsTArrayHelpers.h"
|
||||||
|
#include "DictionaryHelpers.h"
|
||||||
#include "DOMRequest.h"
|
#include "DOMRequest.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
|
|
||||||
|
@ -833,4 +834,71 @@ BluetoothAdapter::IsScoConnected(nsIDOMDOMRequest** aRequest)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
BluetoothAdapter::SendMediaMetaData(const JS::Value& aOptions,
|
||||||
|
nsIDOMDOMRequest** aRequest)
|
||||||
|
{
|
||||||
|
idl::MediaMetaData metadata;
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
nsIScriptContext* sc = GetContextForEventHandlers(&rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
AutoPushJSContext cx(sc->GetNativeContext());
|
||||||
|
rv = metadata.Init(cx, &aOptions);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMDOMRequest> req;
|
||||||
|
rv = PrepareDOMRequest(GetOwner(), getter_AddRefs(req));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsRefPtr<BluetoothReplyRunnable> results =
|
||||||
|
new BluetoothVoidReplyRunnable(req);
|
||||||
|
|
||||||
|
BluetoothService* bs = BluetoothService::Get();
|
||||||
|
NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
|
||||||
|
bs->SendMetaData(metadata.title,
|
||||||
|
metadata.artist,
|
||||||
|
metadata.album,
|
||||||
|
metadata.mediaNumber,
|
||||||
|
metadata.totalMediaCount,
|
||||||
|
metadata.duration,
|
||||||
|
results);
|
||||||
|
|
||||||
|
req.forget(aRequest);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
BluetoothAdapter::SendMediaPlayStatus(const JS::Value& aOptions,
|
||||||
|
nsIDOMDOMRequest** aRequest)
|
||||||
|
{
|
||||||
|
idl::MediaPlayStatus status;
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
nsIScriptContext* sc = GetContextForEventHandlers(&rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
AutoPushJSContext cx(sc->GetNativeContext());
|
||||||
|
rv = status.Init(cx, &aOptions);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMDOMRequest> req;
|
||||||
|
rv = PrepareDOMRequest(GetOwner(), getter_AddRefs(req));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsRefPtr<BluetoothReplyRunnable> results =
|
||||||
|
new BluetoothVoidReplyRunnable(req);
|
||||||
|
|
||||||
|
BluetoothService* bs = BluetoothService::Get();
|
||||||
|
NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
|
||||||
|
bs->SendPlayStatus(status.duration,
|
||||||
|
status.position,
|
||||||
|
status.playStatus,
|
||||||
|
results);
|
||||||
|
|
||||||
|
req.forget(aRequest);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, devicefound)
|
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, devicefound)
|
||||||
|
|
|
@ -85,6 +85,16 @@ enum BluetoothObjectType {
|
||||||
TYPE_INVALID
|
TYPE_INVALID
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ControlPlayStatus {
|
||||||
|
PLAYSTATUS_STOPPED = 0x00,
|
||||||
|
PLAYSTATUS_PLAYING = 0x01,
|
||||||
|
PLAYSTATUS_PAUSED = 0x02,
|
||||||
|
PLAYSTATUS_FWD_SEEK = 0x03,
|
||||||
|
PLAYSTATUS_REV_SEEK = 0x04,
|
||||||
|
PLAYSTATUS_UNKNOWN,
|
||||||
|
PLAYSTATUS_ERROR = 0xFF,
|
||||||
|
};
|
||||||
|
|
||||||
END_BLUETOOTH_NAMESPACE
|
END_BLUETOOTH_NAMESPACE
|
||||||
|
|
||||||
#endif // mozilla_dom_bluetooth_bluetoothcommon_h__
|
#endif // mozilla_dom_bluetooth_bluetoothcommon_h__
|
||||||
|
|
|
@ -270,6 +270,21 @@ public:
|
||||||
virtual void
|
virtual void
|
||||||
IsScoConnected(BluetoothReplyRunnable* aRunnable) = 0;
|
IsScoConnected(BluetoothReplyRunnable* aRunnable) = 0;
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
SendMetaData(const nsAString& aTitle,
|
||||||
|
const nsAString& aArtist,
|
||||||
|
const nsAString& aAlbum,
|
||||||
|
uint32_t aMediaNumber,
|
||||||
|
uint32_t aTotalMediaCount,
|
||||||
|
uint32_t aDuration,
|
||||||
|
BluetoothReplyRunnable* aRunnable) = 0;
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
SendPlayStatus(uint32_t aDuration,
|
||||||
|
uint32_t aPosition,
|
||||||
|
const nsAString& aPlayStatus,
|
||||||
|
BluetoothReplyRunnable* aRunnable) = 0;
|
||||||
|
|
||||||
virtual nsresult
|
virtual nsresult
|
||||||
SendSinkMessage(const nsAString& aDeviceAddresses,
|
SendSinkMessage(const nsAString& aDeviceAddresses,
|
||||||
const nsAString& aMessage) = 0;
|
const nsAString& aMessage) = 0;
|
||||||
|
|
|
@ -230,6 +230,10 @@ BluetoothParent::RecvPBluetoothRequestConstructor(
|
||||||
return actor->DoRequest(aRequest.get_DisconnectScoRequest());
|
return actor->DoRequest(aRequest.get_DisconnectScoRequest());
|
||||||
case Request::TIsScoConnectedRequest:
|
case Request::TIsScoConnectedRequest:
|
||||||
return actor->DoRequest(aRequest.get_IsScoConnectedRequest());
|
return actor->DoRequest(aRequest.get_IsScoConnectedRequest());
|
||||||
|
case Request::TSendMetaDataRequest:
|
||||||
|
return actor->DoRequest(aRequest.get_SendMetaDataRequest());
|
||||||
|
case Request::TSendPlayStatusRequest:
|
||||||
|
return actor->DoRequest(aRequest.get_SendPlayStatusRequest());
|
||||||
default:
|
default:
|
||||||
MOZ_CRASH("Unknown type!");
|
MOZ_CRASH("Unknown type!");
|
||||||
}
|
}
|
||||||
|
@ -603,3 +607,32 @@ BluetoothRequestParent::DoRequest(const IsScoConnectedRequest& aRequest)
|
||||||
mService->IsScoConnected(mReplyRunnable.get());
|
mService->IsScoConnected(mReplyRunnable.get());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BluetoothRequestParent::DoRequest(const SendMetaDataRequest& aRequest)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mService);
|
||||||
|
MOZ_ASSERT(mRequestType == Request::TSendMetaDataRequest);
|
||||||
|
|
||||||
|
mService->SendMetaData(aRequest.title(),
|
||||||
|
aRequest.artist(),
|
||||||
|
aRequest.album(),
|
||||||
|
aRequest.mediaNumber(),
|
||||||
|
aRequest.totalMediaCount(),
|
||||||
|
aRequest.duration(),
|
||||||
|
mReplyRunnable.get());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BluetoothRequestParent::DoRequest(const SendPlayStatusRequest& aRequest)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mService);
|
||||||
|
MOZ_ASSERT(mRequestType == Request::TSendPlayStatusRequest);
|
||||||
|
|
||||||
|
mService->SendPlayStatus(aRequest.duration(),
|
||||||
|
aRequest.position(),
|
||||||
|
aRequest.playStatus(),
|
||||||
|
mReplyRunnable.get());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -194,6 +194,12 @@ protected:
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DoRequest(const IsScoConnectedRequest& aRequest);
|
DoRequest(const IsScoConnectedRequest& aRequest);
|
||||||
|
|
||||||
|
bool
|
||||||
|
DoRequest(const SendMetaDataRequest& aRequest);
|
||||||
|
|
||||||
|
bool
|
||||||
|
DoRequest(const SendPlayStatusRequest& aRequest);
|
||||||
};
|
};
|
||||||
|
|
||||||
END_BLUETOOTH_NAMESPACE
|
END_BLUETOOTH_NAMESPACE
|
||||||
|
|
|
@ -339,6 +339,32 @@ BluetoothServiceChildProcess::IsScoConnected(BluetoothReplyRunnable* aRunnable)
|
||||||
SendRequest(aRunnable, IsScoConnectedRequest());
|
SendRequest(aRunnable, IsScoConnectedRequest());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothServiceChildProcess::SendMetaData(const nsAString& aTitle,
|
||||||
|
const nsAString& aArtist,
|
||||||
|
const nsAString& aAlbum,
|
||||||
|
uint32_t aMediaNumber,
|
||||||
|
uint32_t aTotalMediaCount,
|
||||||
|
uint32_t aDuration,
|
||||||
|
BluetoothReplyRunnable* aRunnable)
|
||||||
|
{
|
||||||
|
SendRequest(aRunnable,
|
||||||
|
SendMetaDataRequest(nsString(aTitle), nsString(aArtist),
|
||||||
|
nsString(aAlbum), aMediaNumber,
|
||||||
|
aTotalMediaCount, aDuration));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothServiceChildProcess::SendPlayStatus(uint32_t aDuration,
|
||||||
|
uint32_t aPosition,
|
||||||
|
const nsAString& aPlayStatus,
|
||||||
|
BluetoothReplyRunnable* aRunnable)
|
||||||
|
{
|
||||||
|
SendRequest(aRunnable,
|
||||||
|
SendPlayStatusRequest(aDuration, aPosition,
|
||||||
|
nsString(aPlayStatus)));
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
BluetoothServiceChildProcess::HandleStartup()
|
BluetoothServiceChildProcess::HandleStartup()
|
||||||
{
|
{
|
||||||
|
@ -388,3 +414,4 @@ BluetoothServiceChildProcess::SendSinkMessage(const nsAString& aDeviceAddresses,
|
||||||
{
|
{
|
||||||
MOZ_CRASH("This should never be called!");
|
MOZ_CRASH("This should never be called!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,6 +152,21 @@ public:
|
||||||
virtual void
|
virtual void
|
||||||
IsScoConnected(BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
|
IsScoConnected(BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
SendMetaData(const nsAString& aTitle,
|
||||||
|
const nsAString& aArtist,
|
||||||
|
const nsAString& aAlbum,
|
||||||
|
uint32_t aMediaNumber,
|
||||||
|
uint32_t aTotalMediaCount,
|
||||||
|
uint32_t aDuration,
|
||||||
|
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
SendPlayStatus(uint32_t aDuration,
|
||||||
|
uint32_t aPosition,
|
||||||
|
const nsAString& aPlayStatus,
|
||||||
|
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual nsresult
|
virtual nsresult
|
||||||
SendSinkMessage(const nsAString& aDeviceAddresses,
|
SendSinkMessage(const nsAString& aDeviceAddresses,
|
||||||
const nsAString& aMessage) MOZ_OVERRIDE;
|
const nsAString& aMessage) MOZ_OVERRIDE;
|
||||||
|
|
|
@ -141,6 +141,23 @@ struct IsScoConnectedRequest
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SendMetaDataRequest
|
||||||
|
{
|
||||||
|
nsString title;
|
||||||
|
nsString artist;
|
||||||
|
nsString album;
|
||||||
|
uint32_t mediaNumber;
|
||||||
|
uint32_t totalMediaCount;
|
||||||
|
uint32_t duration;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SendPlayStatusRequest
|
||||||
|
{
|
||||||
|
uint32_t duration;
|
||||||
|
uint32_t position;
|
||||||
|
nsString playStatus;
|
||||||
|
};
|
||||||
|
|
||||||
union Request
|
union Request
|
||||||
{
|
{
|
||||||
DefaultAdapterPathRequest;
|
DefaultAdapterPathRequest;
|
||||||
|
@ -167,6 +184,8 @@ union Request
|
||||||
ConnectScoRequest;
|
ConnectScoRequest;
|
||||||
DisconnectScoRequest;
|
DisconnectScoRequest;
|
||||||
IsScoConnectedRequest;
|
IsScoConnectedRequest;
|
||||||
|
SendMetaDataRequest;
|
||||||
|
SendPlayStatusRequest;
|
||||||
};
|
};
|
||||||
|
|
||||||
protocol PBluetooth
|
protocol PBluetooth
|
||||||
|
|
|
@ -63,14 +63,16 @@ USING_BLUETOOTH_NAMESPACE
|
||||||
#define B2G_AGENT_CAPABILITIES "DisplayYesNo"
|
#define B2G_AGENT_CAPABILITIES "DisplayYesNo"
|
||||||
#define DBUS_MANAGER_IFACE BLUEZ_DBUS_BASE_IFC ".Manager"
|
#define DBUS_MANAGER_IFACE BLUEZ_DBUS_BASE_IFC ".Manager"
|
||||||
#define DBUS_ADAPTER_IFACE BLUEZ_DBUS_BASE_IFC ".Adapter"
|
#define DBUS_ADAPTER_IFACE BLUEZ_DBUS_BASE_IFC ".Adapter"
|
||||||
#define DBUS_DEVICE_IFACE BLUEZ_DBUS_BASE_IFC ".Device"
|
#define DBUS_DEVICE_IFACE BLUEZ_DBUS_BASE_IFC ".Device"
|
||||||
#define DBUS_AGENT_IFACE BLUEZ_DBUS_BASE_IFC ".Agent"
|
#define DBUS_AGENT_IFACE BLUEZ_DBUS_BASE_IFC ".Agent"
|
||||||
#define DBUS_SINK_IFACE BLUEZ_DBUS_BASE_IFC ".AudioSink"
|
#define DBUS_SINK_IFACE BLUEZ_DBUS_BASE_IFC ".AudioSink"
|
||||||
|
#define DBUS_CTL_IFACE BLUEZ_DBUS_BASE_IFC ".Control"
|
||||||
#define BLUEZ_DBUS_BASE_PATH "/org/bluez"
|
#define BLUEZ_DBUS_BASE_PATH "/org/bluez"
|
||||||
#define BLUEZ_DBUS_BASE_IFC "org.bluez"
|
#define BLUEZ_DBUS_BASE_IFC "org.bluez"
|
||||||
#define BLUEZ_ERROR_IFC "org.bluez.Error"
|
#define BLUEZ_ERROR_IFC "org.bluez.Error"
|
||||||
|
|
||||||
#define PROP_DEVICE_CONNECTED_TYPE "org.bluez.device.conn.type"
|
#define ERR_A2DP_IS_DISCONNECTED "A2dpIsDisconnected"
|
||||||
|
#define ERR_AVRCP_IS_DISCONNECTED "AvrcpIsDisconnected"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char* name;
|
const char* name;
|
||||||
|
@ -123,6 +125,10 @@ static Properties sSinkProperties[] = {
|
||||||
{"Playing", DBUS_TYPE_BOOLEAN}
|
{"Playing", DBUS_TYPE_BOOLEAN}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Properties sControlProperties[] = {
|
||||||
|
{"Connected", DBUS_TYPE_BOOLEAN}
|
||||||
|
};
|
||||||
|
|
||||||
static const char* sBluetoothDBusIfaces[] =
|
static const char* sBluetoothDBusIfaces[] =
|
||||||
{
|
{
|
||||||
DBUS_MANAGER_IFACE,
|
DBUS_MANAGER_IFACE,
|
||||||
|
@ -140,7 +146,8 @@ static const char* sBluetoothDBusSignals[] =
|
||||||
"type='signal',interface='org.bluez.Network'",
|
"type='signal',interface='org.bluez.Network'",
|
||||||
"type='signal',interface='org.bluez.NetworkServer'",
|
"type='signal',interface='org.bluez.NetworkServer'",
|
||||||
"type='signal',interface='org.bluez.HealthDevice'",
|
"type='signal',interface='org.bluez.HealthDevice'",
|
||||||
"type='signal',interface='org.bluez.AudioSink'"
|
"type='signal',interface='org.bluez.AudioSink'",
|
||||||
|
"type='signal',interface='org.bluez.Control'"
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2802,3 +2809,134 @@ BluetoothDBusService::IsScoConnected(BluetoothReplyRunnable* aRunnable)
|
||||||
hfp->IsScoConnected(), EmptyString());
|
hfp->IsScoConnected(), EmptyString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothDBusService::SendMetaData(const nsAString& aTitle,
|
||||||
|
const nsAString& aArtist,
|
||||||
|
const nsAString& aAlbum,
|
||||||
|
uint32_t aMediaNumber,
|
||||||
|
uint32_t aTotalMediaCount,
|
||||||
|
uint32_t aDuration,
|
||||||
|
BluetoothReplyRunnable* aRunnable)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
if (!IsReady()) {
|
||||||
|
NS_NAMED_LITERAL_STRING(errorStr, "Bluetooth service is not ready yet!");
|
||||||
|
DispatchBluetoothReply(aRunnable, BluetoothValue(), errorStr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
|
||||||
|
NS_ENSURE_TRUE_VOID(a2dp);
|
||||||
|
|
||||||
|
nsAutoString address;
|
||||||
|
a2dp->GetAddress(address);
|
||||||
|
nsString objectPath =
|
||||||
|
GetObjectPathFromAddress(sAdapterPath, address);
|
||||||
|
|
||||||
|
nsCString tempTitle = NS_ConvertUTF16toUTF8(aTitle);
|
||||||
|
nsCString tempArtist = NS_ConvertUTF16toUTF8(aArtist);
|
||||||
|
nsCString tempAlbum = NS_ConvertUTF16toUTF8(aAlbum);
|
||||||
|
nsCString tempMediaNumber, tempTotalMediaCount, tempDuration;
|
||||||
|
tempMediaNumber.AppendInt(aMediaNumber);
|
||||||
|
tempTotalMediaCount.AppendInt(aTotalMediaCount);
|
||||||
|
tempDuration.AppendInt(aDuration);
|
||||||
|
|
||||||
|
const char* title = tempTitle.get();
|
||||||
|
const char* album = tempAlbum.get();
|
||||||
|
const char* artist = tempArtist.get();
|
||||||
|
const char* mediaNumber = tempMediaNumber.get();
|
||||||
|
const char* totalMediaCount = tempTotalMediaCount.get();
|
||||||
|
const char* duration = tempDuration.get();
|
||||||
|
|
||||||
|
nsRefPtr<BluetoothReplyRunnable> runnable(aRunnable);
|
||||||
|
|
||||||
|
bool ret = dbus_func_args_async(mConnection,
|
||||||
|
-1,
|
||||||
|
GetVoidCallback,
|
||||||
|
(void*)runnable.get(),
|
||||||
|
NS_ConvertUTF16toUTF8(objectPath).get(),
|
||||||
|
DBUS_CTL_IFACE,
|
||||||
|
"UpdateMetaData",
|
||||||
|
DBUS_TYPE_STRING, &title,
|
||||||
|
DBUS_TYPE_STRING, &artist,
|
||||||
|
DBUS_TYPE_STRING, &album,
|
||||||
|
DBUS_TYPE_STRING, &mediaNumber,
|
||||||
|
DBUS_TYPE_STRING, &totalMediaCount,
|
||||||
|
DBUS_TYPE_STRING, &duration,
|
||||||
|
DBUS_TYPE_INVALID);
|
||||||
|
NS_ENSURE_TRUE_VOID(ret);
|
||||||
|
|
||||||
|
runnable.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
static ControlPlayStatus
|
||||||
|
PlayStatusStringToControlPlayStatus(const nsAString& aPlayStatus)
|
||||||
|
{
|
||||||
|
ControlPlayStatus playStatus = ControlPlayStatus::PLAYSTATUS_UNKNOWN;
|
||||||
|
if (aPlayStatus.EqualsLiteral("STOPPED")) {
|
||||||
|
playStatus = ControlPlayStatus::PLAYSTATUS_STOPPED;
|
||||||
|
} else if (aPlayStatus.EqualsLiteral("PLAYING")) {
|
||||||
|
playStatus = ControlPlayStatus::PLAYSTATUS_PLAYING;
|
||||||
|
} else if (aPlayStatus.EqualsLiteral("PAUSED")) {
|
||||||
|
playStatus = ControlPlayStatus::PLAYSTATUS_PAUSED;
|
||||||
|
} else if (aPlayStatus.EqualsLiteral("FWD_SEEK")) {
|
||||||
|
playStatus = ControlPlayStatus::PLAYSTATUS_FWD_SEEK;
|
||||||
|
} else if (aPlayStatus.EqualsLiteral("REV_SEEK")) {
|
||||||
|
playStatus = ControlPlayStatus::PLAYSTATUS_REV_SEEK;
|
||||||
|
} else if (aPlayStatus.EqualsLiteral("ERROR")) {
|
||||||
|
playStatus = ControlPlayStatus::PLAYSTATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return playStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothDBusService::SendPlayStatus(uint32_t aDuration,
|
||||||
|
uint32_t aPosition,
|
||||||
|
const nsAString& aPlayStatus,
|
||||||
|
BluetoothReplyRunnable* aRunnable)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
if (!IsReady()) {
|
||||||
|
NS_NAMED_LITERAL_STRING(errorStr, "Bluetooth service is not ready yet!");
|
||||||
|
DispatchBluetoothReply(aRunnable, BluetoothValue(), errorStr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ControlPlayStatus playStatus =
|
||||||
|
PlayStatusStringToControlPlayStatus(aPlayStatus);
|
||||||
|
if (playStatus == ControlPlayStatus::PLAYSTATUS_UNKNOWN) {
|
||||||
|
DispatchBluetoothReply(aRunnable, BluetoothValue(),
|
||||||
|
NS_LITERAL_STRING("Invalid play status"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
|
||||||
|
NS_ENSURE_TRUE_VOID(a2dp);
|
||||||
|
|
||||||
|
nsAutoString address;
|
||||||
|
a2dp->GetAddress(address);
|
||||||
|
nsString objectPath =
|
||||||
|
GetObjectPathFromAddress(sAdapterPath, address);
|
||||||
|
|
||||||
|
nsRefPtr<BluetoothReplyRunnable> runnable(aRunnable);
|
||||||
|
|
||||||
|
uint32_t tempPlayStatus = playStatus;
|
||||||
|
bool ret = dbus_func_args_async(mConnection,
|
||||||
|
-1,
|
||||||
|
GetVoidCallback,
|
||||||
|
(void*)runnable.get(),
|
||||||
|
NS_ConvertUTF16toUTF8(objectPath).get(),
|
||||||
|
DBUS_CTL_IFACE,
|
||||||
|
"UpdatePlayStatus",
|
||||||
|
DBUS_TYPE_UINT32, &aDuration,
|
||||||
|
DBUS_TYPE_UINT32, &aPosition,
|
||||||
|
DBUS_TYPE_UINT32, &tempPlayStatus,
|
||||||
|
DBUS_TYPE_INVALID);
|
||||||
|
NS_ENSURE_TRUE_VOID(ret);
|
||||||
|
|
||||||
|
runnable.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,21 @@ public:
|
||||||
virtual void
|
virtual void
|
||||||
IsScoConnected(BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
|
IsScoConnected(BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
SendMetaData(const nsAString& aTitle,
|
||||||
|
const nsAString& aArtist,
|
||||||
|
const nsAString& aAlbum,
|
||||||
|
uint32_t aMediaNumber,
|
||||||
|
uint32_t aTotalMediaCount,
|
||||||
|
uint32_t aDuration,
|
||||||
|
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
SendPlayStatus(uint32_t aDuration,
|
||||||
|
uint32_t aPosition,
|
||||||
|
const nsAString& aPlayStatus,
|
||||||
|
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual nsresult
|
virtual nsresult
|
||||||
SendSinkMessage(const nsAString& aDeviceAddresses,
|
SendSinkMessage(const nsAString& aDeviceAddresses,
|
||||||
const nsAString& aMessage) MOZ_OVERRIDE;
|
const nsAString& aMessage) MOZ_OVERRIDE;
|
||||||
|
@ -147,13 +162,16 @@ private:
|
||||||
const char* aInterface,
|
const char* aInterface,
|
||||||
void (*aCB)(DBusMessage *, void *),
|
void (*aCB)(DBusMessage *, void *),
|
||||||
BluetoothReplyRunnable* aRunnable);
|
BluetoothReplyRunnable* aRunnable);
|
||||||
|
|
||||||
nsresult SendDiscoveryMessage(const char* aMessageName,
|
nsresult SendDiscoveryMessage(const char* aMessageName,
|
||||||
BluetoothReplyRunnable* aRunnable);
|
BluetoothReplyRunnable* aRunnable);
|
||||||
|
|
||||||
nsresult SendSetPropertyMessage(const char* aInterface,
|
nsresult SendSetPropertyMessage(const char* aInterface,
|
||||||
const BluetoothNamedValue& aValue,
|
const BluetoothNamedValue& aValue,
|
||||||
BluetoothReplyRunnable* aRunnable);
|
BluetoothReplyRunnable* aRunnable);
|
||||||
|
|
||||||
void DisconnectAllAcls(const nsAString& aAdapterPath);
|
void DisconnectAllAcls(const nsAString& aAdapterPath);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
END_BLUETOOTH_NAMESPACE
|
END_BLUETOOTH_NAMESPACE
|
||||||
|
|
|
@ -6,11 +6,44 @@
|
||||||
|
|
||||||
#include "nsIDOMEventTarget.idl"
|
#include "nsIDOMEventTarget.idl"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MediaMetadata and MediaPlayStatus are used to keep data from Applications.
|
||||||
|
* Please see specification of AVRCP 1.3 for more details.
|
||||||
|
*
|
||||||
|
* @title: track title
|
||||||
|
* @artist: artist name
|
||||||
|
* @album: album name
|
||||||
|
* @mediaNumber: track number
|
||||||
|
* @totalMediaCount: number of tracks in the album
|
||||||
|
* @duration: playing time (ms)
|
||||||
|
*/
|
||||||
|
dictionary MediaMetaData
|
||||||
|
{
|
||||||
|
DOMString title;
|
||||||
|
DOMString artist;
|
||||||
|
DOMString album;
|
||||||
|
unsigned long mediaNumber;
|
||||||
|
unsigned long totalMediaCount;
|
||||||
|
unsigned long duration;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @duration: current track length (ms)
|
||||||
|
* @position: playing time (ms)
|
||||||
|
* @playStatus: STOPPED/PLAYING/PAUSED/FWD_SEEK/REV_SEEK/ERROR
|
||||||
|
*/
|
||||||
|
dictionary MediaPlayStatus
|
||||||
|
{
|
||||||
|
unsigned long duration;
|
||||||
|
unsigned long position;
|
||||||
|
DOMString playStatus;
|
||||||
|
};
|
||||||
|
|
||||||
interface nsIDOMDOMRequest;
|
interface nsIDOMDOMRequest;
|
||||||
interface nsIDOMBlob;
|
interface nsIDOMBlob;
|
||||||
interface nsIDOMBluetoothDevice;
|
interface nsIDOMBluetoothDevice;
|
||||||
|
|
||||||
[scriptable, builtinclass, uuid(7058d214-3575-4913-99ad-0980296f617a)]
|
[scriptable, builtinclass, uuid(1a0c6c90-23e3-4f4c-8076-98e4341c2024)]
|
||||||
interface nsIDOMBluetoothAdapter : nsIDOMEventTarget
|
interface nsIDOMBluetoothAdapter : nsIDOMEventTarget
|
||||||
{
|
{
|
||||||
readonly attribute DOMString address;
|
readonly attribute DOMString address;
|
||||||
|
@ -58,6 +91,10 @@ interface nsIDOMBluetoothAdapter : nsIDOMEventTarget
|
||||||
nsIDOMDOMRequest stopSendingFile(in DOMString aDeviceAddress);
|
nsIDOMDOMRequest stopSendingFile(in DOMString aDeviceAddress);
|
||||||
nsIDOMDOMRequest confirmReceivingFile(in DOMString aDeviceAddress, in bool aConfirmation);
|
nsIDOMDOMRequest confirmReceivingFile(in DOMString aDeviceAddress, in bool aConfirmation);
|
||||||
|
|
||||||
|
// AVRCP 1.3 methods
|
||||||
|
nsIDOMDOMRequest sendMediaMetaData(in jsval aOptions);
|
||||||
|
nsIDOMDOMRequest sendMediaPlayStatus(in jsval aOptions);
|
||||||
|
|
||||||
// Connect/Disconnect SCO (audio) connection
|
// Connect/Disconnect SCO (audio) connection
|
||||||
nsIDOMDOMRequest connectSco();
|
nsIDOMDOMRequest connectSco();
|
||||||
nsIDOMDOMRequest disconnectSco();
|
nsIDOMDOMRequest disconnectSco();
|
||||||
|
|
|
@ -13,7 +13,9 @@ dictionaries = [
|
||||||
[ 'CameraSelector', 'nsIDOMCameraManager.idl' ],
|
[ 'CameraSelector', 'nsIDOMCameraManager.idl' ],
|
||||||
[ 'CameraRecordingOptions', 'nsIDOMCameraManager.idl' ],
|
[ 'CameraRecordingOptions', 'nsIDOMCameraManager.idl' ],
|
||||||
[ 'SmsThreadListItem', 'nsIMobileMessageCallback.idl' ],
|
[ 'SmsThreadListItem', 'nsIMobileMessageCallback.idl' ],
|
||||||
[ 'MmsAttachment', 'nsIDOMMozMmsMessage.idl' ]
|
[ 'MmsAttachment', 'nsIDOMMozMmsMessage.idl' ],
|
||||||
|
[ 'MediaMetaData', 'nsIDOMBluetoothAdapter.idl'],
|
||||||
|
[ 'MediaPlayStatus', 'nsIDOMBluetoothAdapter.idl']
|
||||||
]
|
]
|
||||||
|
|
||||||
# include file names
|
# include file names
|
||||||
|
|
Загрузка…
Ссылка в новой задаче