зеркало из https://github.com/mozilla/gecko-dev.git
Bug 872907 - Patch 3: Handle Sink property change, r=echou, r=mrbkap
This commit is contained in:
Родитель
0d6dda1c7a
Коммит
7acf3408a1
|
@ -87,9 +87,9 @@ BluetoothA2dpManagerObserver::Observe(nsISupports* aSubject,
|
|||
NS_IMPL_ISUPPORTS1(BluetoothA2dpManagerObserver, nsIObserver)
|
||||
|
||||
BluetoothA2dpManager::BluetoothA2dpManager()
|
||||
: mSinkState(SinkState::SINK_DISCONNECTED)
|
||||
, mConnected(false)
|
||||
: mConnected(false)
|
||||
, mPlaying(false)
|
||||
, mSinkState(SinkState::SINK_DISCONNECTED)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -119,6 +119,26 @@ BluetoothA2dpManager::Cleanup()
|
|||
sA2dpObserver = nullptr;
|
||||
}
|
||||
|
||||
static SinkState
|
||||
StatusStringToSinkState(const nsAString& aStatus)
|
||||
{
|
||||
SinkState state;
|
||||
if (aStatus.EqualsLiteral("disconnected")) {
|
||||
state = SinkState::SINK_DISCONNECTED;
|
||||
} else if (aStatus.EqualsLiteral("connecting")) {
|
||||
state = SinkState::SINK_CONNECTING;
|
||||
} else if (aStatus.EqualsLiteral("connected")) {
|
||||
state = SinkState::SINK_CONNECTED;
|
||||
} else if (aStatus.EqualsLiteral("playing")) {
|
||||
state = SinkState::SINK_PLAYING;
|
||||
} else if (aStatus.EqualsLiteral("disconnecting")) {
|
||||
state = SinkState::SINK_DISCONNECTING;
|
||||
} else {
|
||||
MOZ_ASSERT(false, "Unknown sink state");
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
//static
|
||||
BluetoothA2dpManager*
|
||||
BluetoothA2dpManager::Get()
|
||||
|
@ -194,3 +214,67 @@ BluetoothA2dpManager::Disconnect()
|
|||
NS_ENSURE_TRUE_VOID(bs);
|
||||
bs->SendSinkMessage(mDeviceAddress, NS_LITERAL_STRING("Disconnect"));
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothA2dpManager::HandleSinkPropertyChanged(const BluetoothSignal& aSignal)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aSignal.value().type() == BluetoothValue::TArrayOfBluetoothNamedValue);
|
||||
|
||||
const InfallibleTArray<BluetoothNamedValue>& arr =
|
||||
aSignal.value().get_ArrayOfBluetoothNamedValue();
|
||||
MOZ_ASSERT(arr.Length() == 1);
|
||||
|
||||
const nsString& name = arr[0].name();
|
||||
const BluetoothValue& value = arr[0].value();
|
||||
if (name.EqualsLiteral("Connected")) {
|
||||
// Indicates if a stream is setup to a A2DP sink on the remote device.
|
||||
MOZ_ASSERT(value.type() == BluetoothValue::Tbool);
|
||||
mConnected = value.get_bool();
|
||||
} else if (name.EqualsLiteral("Playing")) {
|
||||
// Indicates if a stream is active to a A2DP sink on the remote device.
|
||||
MOZ_ASSERT(value.type() == BluetoothValue::Tbool);
|
||||
mPlaying = value.get_bool();
|
||||
} else if (name.EqualsLiteral("State")) {
|
||||
MOZ_ASSERT(value.type() == BluetoothValue::TnsString);
|
||||
HandleSinkStateChanged(StatusStringToSinkState(value.get_nsString()));
|
||||
} else {
|
||||
NS_WARNING("Unknown sink property");
|
||||
}
|
||||
}
|
||||
|
||||
/* HandleSinkPropertyChanged update sink state in A2dp
|
||||
*
|
||||
* Possible values: "disconnected", "connecting", "connected", "playing"
|
||||
*
|
||||
* 1. "disconnected" -> "connecting"
|
||||
* Either an incoming or outgoing connection attempt ongoing
|
||||
* 2. "connecting" -> "disconnected"
|
||||
* Connection attempt failed
|
||||
* 3. "connecting" -> "connected"
|
||||
* Successfully connected
|
||||
* 4. "connected" -> "playing"
|
||||
* Audio stream active
|
||||
* 5. "playing" -> "connected"
|
||||
* Audio stream suspended
|
||||
* 6. "connected" -> "disconnected"
|
||||
* "playing" -> "disconnected"
|
||||
* Disconnected from the remote device
|
||||
* 7. "disconnecting" -> "disconnected"
|
||||
* Disconnected from local
|
||||
*/
|
||||
void
|
||||
BluetoothA2dpManager::HandleSinkStateChanged(SinkState aState)
|
||||
{
|
||||
MOZ_ASSERT_IF(aState == SinkState::SINK_CONNECTED,
|
||||
mSinkState == SinkState::SINK_CONNECTING ||
|
||||
mSinkState == SinkState::SINK_PLAYING);
|
||||
MOZ_ASSERT_IF(aState == SinkState::SINK_PLAYING,
|
||||
mSinkState == SinkState::SINK_CONNECTED);
|
||||
|
||||
if (aState == SinkState::SINK_DISCONNECTED) {
|
||||
mDeviceAddress.Truncate();
|
||||
}
|
||||
|
||||
mSinkState = aState;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,8 @@ private:
|
|||
bool Init();
|
||||
void Cleanup();
|
||||
|
||||
void HandleSinkStateChanged(SinkState aState);
|
||||
|
||||
bool mConnected;
|
||||
bool mPlaying;
|
||||
nsString mDeviceAddress;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "base/basictypes.h"
|
||||
#include "BluetoothDBusService.h"
|
||||
#include "BluetoothA2dpManager.h"
|
||||
#include "BluetoothHfpManager.h"
|
||||
#include "BluetoothOppManager.h"
|
||||
#include "BluetoothReplyRunnable.h"
|
||||
|
@ -116,6 +117,12 @@ static Properties sManagerProperties[] = {
|
|||
{"Adapters", DBUS_TYPE_ARRAY},
|
||||
};
|
||||
|
||||
static Properties sSinkProperties[] = {
|
||||
{"State", DBUS_TYPE_STRING},
|
||||
{"Connected", DBUS_TYPE_BOOLEAN},
|
||||
{"Playing", DBUS_TYPE_BOOLEAN}
|
||||
};
|
||||
|
||||
static const char* sBluetoothDBusIfaces[] =
|
||||
{
|
||||
DBUS_MANAGER_IFACE,
|
||||
|
@ -349,6 +356,35 @@ private:
|
|||
BluetoothSignal mSignal;
|
||||
};
|
||||
|
||||
class SinkPropertyChangedHandler : public nsRunnable
|
||||
{
|
||||
public:
|
||||
SinkPropertyChangedHandler(const BluetoothSignal& aSignal)
|
||||
: mSignal(aSignal)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mSignal.name().EqualsLiteral("PropertyChanged"));
|
||||
MOZ_ASSERT(mSignal.value().type() == BluetoothValue::TArrayOfBluetoothNamedValue);
|
||||
|
||||
// Replace object path with device address
|
||||
nsString address = GetAddressFromObjectPath(mSignal.path());
|
||||
mSignal.path() = address;
|
||||
|
||||
BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
|
||||
NS_ENSURE_TRUE(a2dp, NS_ERROR_FAILURE);
|
||||
a2dp->HandleSinkPropertyChanged(mSignal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothSignal mSignal;
|
||||
};
|
||||
|
||||
static bool
|
||||
IsDBusMessageError(DBusMessage* aMsg, DBusError* aErr, nsAString& aErrorStr)
|
||||
{
|
||||
|
@ -1531,6 +1567,13 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
|
|||
errorStr,
|
||||
sManagerProperties,
|
||||
ArrayLength(sManagerProperties));
|
||||
} else if (dbus_message_is_signal(aMsg, DBUS_SINK_IFACE,
|
||||
"PropertyChanged")) {
|
||||
ParsePropertyChange(aMsg,
|
||||
v,
|
||||
errorStr,
|
||||
sSinkProperties,
|
||||
ArrayLength(sSinkProperties));
|
||||
} else {
|
||||
nsAutoCString signalStr;
|
||||
signalStr += dbus_message_get_member(aMsg);
|
||||
|
@ -1545,9 +1588,14 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
|
|||
}
|
||||
|
||||
BluetoothSignal signal(signalName, signalPath, v);
|
||||
nsRefPtr<DistributeBluetoothSignalTask>
|
||||
t = new DistributeBluetoothSignalTask(signal);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(t))) {
|
||||
nsRefPtr<nsRunnable> task;
|
||||
if (signalInterface.EqualsLiteral(DBUS_SINK_IFACE)) {
|
||||
task = new SinkPropertyChangedHandler(signal);
|
||||
} else {
|
||||
task = new DistributeBluetoothSignalTask(signal);
|
||||
}
|
||||
|
||||
if (NS_FAILED(NS_DispatchToMainThread(task))) {
|
||||
NS_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче