mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 842948 - Patch 2: Handle control signal "PropertyChanged" and add IsConnected() in BluetoothProfileManagerBase, r=echou
This commit is contained in:
parent
d368c340e4
commit
e9527b054f
@ -45,10 +45,9 @@ BluetoothA2dpManager::Observe(nsISupports* aSubject,
|
||||
}
|
||||
|
||||
BluetoothA2dpManager::BluetoothA2dpManager()
|
||||
: mConnected(false)
|
||||
, mPlaying(false)
|
||||
, mSinkState(SinkState::SINK_DISCONNECTED)
|
||||
{
|
||||
ResetA2dp();
|
||||
ResetAvrcp();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -75,20 +74,34 @@ BluetoothA2dpManager::~BluetoothA2dpManager()
|
||||
}
|
||||
}
|
||||
|
||||
static SinkState
|
||||
void
|
||||
BluetoothA2dpManager::ResetA2dp()
|
||||
{
|
||||
mA2dpConnected = false;
|
||||
mPlaying = false;
|
||||
mSinkState = SinkState::SINK_DISCONNECTED;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothA2dpManager::ResetAvrcp()
|
||||
{
|
||||
mAvrcpConnected = false;
|
||||
}
|
||||
|
||||
static BluetoothA2dpManager::SinkState
|
||||
StatusStringToSinkState(const nsAString& aStatus)
|
||||
{
|
||||
SinkState state;
|
||||
BluetoothA2dpManager::SinkState state;
|
||||
if (aStatus.EqualsLiteral("disconnected")) {
|
||||
state = SinkState::SINK_DISCONNECTED;
|
||||
state = BluetoothA2dpManager::SinkState::SINK_DISCONNECTED;
|
||||
} else if (aStatus.EqualsLiteral("connecting")) {
|
||||
state = SinkState::SINK_CONNECTING;
|
||||
state = BluetoothA2dpManager::SinkState::SINK_CONNECTING;
|
||||
} else if (aStatus.EqualsLiteral("connected")) {
|
||||
state = SinkState::SINK_CONNECTED;
|
||||
state = BluetoothA2dpManager::SinkState::SINK_CONNECTED;
|
||||
} else if (aStatus.EqualsLiteral("playing")) {
|
||||
state = SinkState::SINK_PLAYING;
|
||||
state = BluetoothA2dpManager::SinkState::SINK_PLAYING;
|
||||
} else if (aStatus.EqualsLiteral("disconnecting")) {
|
||||
state = SinkState::SINK_DISCONNECTING;
|
||||
state = BluetoothA2dpManager::SinkState::SINK_DISCONNECTING;
|
||||
} else {
|
||||
MOZ_ASSERT(false, "Unknown sink state");
|
||||
}
|
||||
@ -140,7 +153,7 @@ BluetoothA2dpManager::Connect(const nsAString& aDeviceAddress)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mConnected) {
|
||||
if (mA2dpConnected) {
|
||||
NS_WARNING("BluetoothA2dpManager is connected");
|
||||
return false;
|
||||
}
|
||||
@ -158,7 +171,7 @@ BluetoothA2dpManager::Connect(const nsAString& aDeviceAddress)
|
||||
void
|
||||
BluetoothA2dpManager::Disconnect()
|
||||
{
|
||||
if (!mConnected) {
|
||||
if (!mA2dpConnected) {
|
||||
NS_WARNING("BluetoothA2dpManager has been disconnected");
|
||||
return;
|
||||
}
|
||||
@ -185,7 +198,7 @@ BluetoothA2dpManager::HandleSinkPropertyChanged(const BluetoothSignal& aSignal)
|
||||
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();
|
||||
mA2dpConnected = value.get_bool();
|
||||
NotifyStatusChanged();
|
||||
NotifyAudioManager();
|
||||
} else if (name.EqualsLiteral("Playing")) {
|
||||
@ -244,7 +257,7 @@ BluetoothA2dpManager::NotifyStatusChanged()
|
||||
NS_NAMED_LITERAL_STRING(type, BLUETOOTH_A2DP_STATUS_CHANGED_ID);
|
||||
InfallibleTArray<BluetoothNamedValue> parameters;
|
||||
|
||||
BluetoothValue v = mConnected;
|
||||
BluetoothValue v = mA2dpConnected;
|
||||
parameters.AppendElement(
|
||||
BluetoothNamedValue(NS_LITERAL_STRING("connected"), v));
|
||||
|
||||
@ -268,7 +281,7 @@ BluetoothA2dpManager::NotifyAudioManager()
|
||||
NS_ENSURE_TRUE_VOID(obs);
|
||||
|
||||
nsAutoString data;
|
||||
data.AppendInt(mConnected);
|
||||
data.AppendInt(mA2dpConnected);
|
||||
|
||||
if (NS_FAILED(obs->NotifyObservers(this,
|
||||
BLUETOOTH_A2DP_STATUS_CHANGED_ID,
|
||||
@ -295,5 +308,26 @@ BluetoothA2dpManager::GetAddress(nsAString& aDeviceAddress)
|
||||
aDeviceAddress = mDeviceAddress;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothA2dpManager::IsConnected()
|
||||
{
|
||||
return mA2dpConnected;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothA2dpManager::SetAvrcpConnected(bool aConnected)
|
||||
{
|
||||
mAvrcpConnected = aConnected;
|
||||
if (!aConnected) {
|
||||
ResetAvrcp();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothA2dpManager::IsAvrcpConnected()
|
||||
{
|
||||
return mAvrcpConnected;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(BluetoothA2dpManager, nsIObserver)
|
||||
|
||||
|
@ -12,17 +12,7 @@
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
enum SinkState {
|
||||
SINK_DISCONNECTED = 1,
|
||||
SINK_CONNECTING,
|
||||
SINK_CONNECTED,
|
||||
SINK_PLAYING,
|
||||
SINK_DISCONNECTING
|
||||
};
|
||||
|
||||
class BluetoothA2dpManagerObserver;
|
||||
class BluetoothValue;
|
||||
class BluetoothSocket;
|
||||
|
||||
class BluetoothA2dpManager : public BluetoothProfileManagerBase
|
||||
{
|
||||
@ -30,24 +20,39 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
enum SinkState {
|
||||
SINK_DISCONNECTED = 1,
|
||||
SINK_CONNECTING,
|
||||
SINK_CONNECTED,
|
||||
SINK_PLAYING,
|
||||
SINK_DISCONNECTING
|
||||
};
|
||||
|
||||
static BluetoothA2dpManager* Get();
|
||||
~BluetoothA2dpManager();
|
||||
void ResetA2dp();
|
||||
void ResetAvrcp();
|
||||
|
||||
bool Connect(const nsAString& aDeviceAddress);
|
||||
void Disconnect();
|
||||
|
||||
// Member functions inherited from parent class BluetoothProfileManagerBase
|
||||
virtual void OnGetServiceChannel(const nsAString& aDeviceAddress,
|
||||
const nsAString& aServiceUuid,
|
||||
int aChannel) MOZ_OVERRIDE;
|
||||
virtual void OnUpdateSdpRecords(const nsAString& aDeviceAddress) MOZ_OVERRIDE;
|
||||
virtual void GetAddress(nsAString& aDeviceAddress) MOZ_OVERRIDE;
|
||||
virtual bool IsConnected() MOZ_OVERRIDE;
|
||||
|
||||
// A2DP member functions
|
||||
bool Connect(const nsAString& aDeviceAddress);
|
||||
void Disconnect();
|
||||
void HandleSinkPropertyChanged(const BluetoothSignal& aSignal);
|
||||
|
||||
// AVRCP member functions
|
||||
void SetAvrcpConnected(bool aConnected);
|
||||
bool IsAvrcpConnected();
|
||||
|
||||
private:
|
||||
BluetoothA2dpManager();
|
||||
bool Init();
|
||||
void Cleanup();
|
||||
|
||||
void HandleSinkStateChanged(SinkState aState);
|
||||
void HandleShutdown();
|
||||
@ -55,10 +60,15 @@ private:
|
||||
void NotifyStatusChanged();
|
||||
void NotifyAudioManager();
|
||||
|
||||
bool mConnected;
|
||||
bool mPlaying;
|
||||
nsString mDeviceAddress;
|
||||
|
||||
// A2DP data member
|
||||
bool mA2dpConnected;
|
||||
bool mPlaying;
|
||||
SinkState mSinkState;
|
||||
|
||||
// AVRCP data member
|
||||
bool mAvrcpConnected;
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
@ -341,7 +341,7 @@ void
|
||||
BluetoothOppManager::StartSendingNextFile()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!IsTransferring());
|
||||
MOZ_ASSERT(!IsConnected());
|
||||
MOZ_ASSERT(mBlobs.Length() > mCurrentBlobIndex + 1);
|
||||
|
||||
mIsServer = false;
|
||||
@ -1104,7 +1104,7 @@ BluetoothOppManager::CheckPutFinal(uint32_t aNumRead)
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothOppManager::IsTransferring()
|
||||
BluetoothOppManager::IsConnected()
|
||||
{
|
||||
return (mConnected && !mSendTransferCompleteFlag);
|
||||
}
|
||||
|
@ -76,10 +76,6 @@ public:
|
||||
bool ExtractBlobHeaders();
|
||||
void CheckPutFinal(uint32_t aNumRead);
|
||||
|
||||
// Return true if there is an ongoing file-transfer session, please see
|
||||
// Bug 827267 for more information.
|
||||
bool IsTransferring();
|
||||
|
||||
// Implement interface BluetoothSocketObserver
|
||||
void ReceiveSocketData(
|
||||
BluetoothSocket* aSocket,
|
||||
@ -93,6 +89,7 @@ public:
|
||||
int aChannel) MOZ_OVERRIDE;
|
||||
virtual void OnUpdateSdpRecords(const nsAString& aDeviceAddress) MOZ_OVERRIDE;
|
||||
virtual void GetAddress(nsAString& aDeviceAddress) MOZ_OVERRIDE;
|
||||
virtual bool IsConnected() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
BluetoothOppManager();
|
||||
|
@ -30,6 +30,7 @@ public:
|
||||
int aChannel) = 0;
|
||||
virtual void OnUpdateSdpRecords(const nsAString& aDeviceAddress) = 0;
|
||||
virtual void GetAddress(nsAString& aDeviceAddress) = 0;
|
||||
virtual bool IsConnected() = 0;
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
@ -73,6 +73,7 @@ USING_BLUETOOTH_NAMESPACE
|
||||
|
||||
#define ERR_A2DP_IS_DISCONNECTED "A2dpIsDisconnected"
|
||||
#define ERR_AVRCP_IS_DISCONNECTED "AvrcpIsDisconnected"
|
||||
#define ERR_UNKNOWN_PROFILE "UnknownProfileError"
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
@ -216,6 +217,38 @@ private:
|
||||
BluetoothSignal mSignal;
|
||||
};
|
||||
|
||||
class ControlPropertyChangedHandler : public nsRunnable
|
||||
{
|
||||
public:
|
||||
ControlPropertyChangedHandler(const BluetoothSignal& aSignal)
|
||||
: mSignal(aSignal)
|
||||
{
|
||||
}
|
||||
|
||||
nsresult Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (mSignal.value().type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
|
||||
BT_WARNING("Wrong value type for ControlPropertyChangedHandler");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
InfallibleTArray<BluetoothNamedValue>& arr =
|
||||
mSignal.value().get_ArrayOfBluetoothNamedValue();
|
||||
MOZ_ASSERT(arr[0].name().EqualsLiteral("Connected"));
|
||||
MOZ_ASSERT(arr[0].value().type() == BluetoothValue::Tbool);
|
||||
bool connected = arr[0].value().get_bool();
|
||||
|
||||
BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
|
||||
NS_ENSURE_TRUE(a2dp, NS_ERROR_FAILURE);
|
||||
a2dp->SetAvrcpConnected(connected);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothSignal mSignal;
|
||||
};
|
||||
|
||||
class SinkPropertyChangedHandler : public nsRunnable
|
||||
{
|
||||
public:
|
||||
@ -229,7 +262,8 @@ public:
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mSignal.name().EqualsLiteral("PropertyChanged"));
|
||||
MOZ_ASSERT(mSignal.value().type() == BluetoothValue::TArrayOfBluetoothNamedValue);
|
||||
MOZ_ASSERT(mSignal.value().type() ==
|
||||
BluetoothValue::TArrayOfBluetoothNamedValue);
|
||||
|
||||
// Replace object path with device address
|
||||
nsString address = GetAddressFromObjectPath(mSignal.path());
|
||||
@ -409,6 +443,11 @@ public:
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
|
||||
NS_ENSURE_TRUE(a2dp, NS_ERROR_FAILURE);
|
||||
a2dp->ResetA2dp();
|
||||
a2dp->ResetAvrcp();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
@ -1450,6 +1489,12 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
|
||||
errorStr,
|
||||
sSinkProperties,
|
||||
ArrayLength(sSinkProperties));
|
||||
} else if (dbus_message_is_signal(aMsg, DBUS_CTL_IFACE, "PropertyChanged")) {
|
||||
ParsePropertyChange(aMsg,
|
||||
v,
|
||||
errorStr,
|
||||
sControlProperties,
|
||||
ArrayLength(sControlProperties));
|
||||
} else {
|
||||
errorStr = NS_ConvertUTF8toUTF16(dbus_message_get_member(aMsg));
|
||||
errorStr.AppendLiteral(" Signal not handled!");
|
||||
@ -1464,6 +1509,8 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
|
||||
nsRefPtr<nsRunnable> task;
|
||||
if (signalInterface.EqualsLiteral(DBUS_SINK_IFACE)) {
|
||||
task = new SinkPropertyChangedHandler(signal);
|
||||
} else if (signalInterface.EqualsLiteral(DBUS_CTL_IFACE)) {
|
||||
task = new ControlPropertyChangedHandler(signal);
|
||||
} else {
|
||||
task = new DistributeBluetoothSignalTask(signal);
|
||||
}
|
||||
@ -1908,37 +1955,30 @@ BluetoothDBusService::GetConnectedDevicePropertiesInternal(uint16_t aProfileId,
|
||||
}
|
||||
|
||||
nsTArray<nsString> deviceAddresses;
|
||||
BluetoothProfileManagerBase* profile;
|
||||
if (aProfileId == BluetoothServiceClass::HANDSFREE ||
|
||||
aProfileId == BluetoothServiceClass::HEADSET) {
|
||||
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
|
||||
if (hfp->IsConnected()) {
|
||||
nsString address;
|
||||
hfp->GetAddress(address);
|
||||
deviceAddresses.AppendElement(address);
|
||||
}
|
||||
profile = BluetoothHfpManager::Get();
|
||||
} else if (aProfileId == BluetoothServiceClass::OBJECT_PUSH) {
|
||||
BluetoothOppManager* opp = BluetoothOppManager::Get();
|
||||
if (opp->IsTransferring()) {
|
||||
nsString address;
|
||||
opp->GetAddress(address);
|
||||
deviceAddresses.AppendElement(address);
|
||||
}
|
||||
profile = BluetoothOppManager::Get();
|
||||
} else {
|
||||
errorStr.AssignLiteral("Unknown profile");
|
||||
DispatchBluetoothReply(aRunnable, values, errorStr);
|
||||
DispatchBluetoothReply(aRunnable, values,
|
||||
NS_LITERAL_STRING(ERR_UNKNOWN_PROFILE));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (profile->IsConnected()) {
|
||||
nsString address;
|
||||
profile->GetAddress(address);
|
||||
deviceAddresses.AppendElement(address);
|
||||
}
|
||||
|
||||
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
|
||||
nsRefPtr<nsRunnable> func(
|
||||
new BluetoothArrayOfDevicePropertiesRunnable(deviceAddresses,
|
||||
runnable,
|
||||
GetConnectedDevicesFilter));
|
||||
|
||||
if (NS_FAILED(mBluetoothCommandThread->Dispatch(func, NS_DISPATCH_NORMAL))) {
|
||||
NS_WARNING("Cannot dispatch task!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mBluetoothCommandThread->Dispatch(func, NS_DISPATCH_NORMAL);
|
||||
|
||||
runnable.forget();
|
||||
return NS_OK;
|
||||
@ -2391,7 +2431,7 @@ BluetoothDBusService::Connect(const nsAString& aDeviceAddress,
|
||||
opp->Connect(aDeviceAddress, aRunnable);
|
||||
} else {
|
||||
DispatchBluetoothReply(aRunnable, BluetoothValue(),
|
||||
NS_LITERAL_STRING("UnknownProfileError"));
|
||||
NS_LITERAL_STRING(ERR_UNKNOWN_PROFILE));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2409,7 +2449,7 @@ BluetoothDBusService::Disconnect(const uint16_t aProfileId,
|
||||
BluetoothOppManager* opp = BluetoothOppManager::Get();
|
||||
opp->Disconnect();
|
||||
} else {
|
||||
NS_WARNING("Unknown profile");
|
||||
BT_WARNING(ERR_UNKNOWN_PROFILE);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2424,16 +2464,19 @@ BluetoothDBusService::IsConnected(const uint16_t aProfileId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
BluetoothProfileManagerBase* profile;
|
||||
if (aProfileId == BluetoothServiceClass::HANDSFREE ||
|
||||
aProfileId == BluetoothServiceClass::HEADSET) {
|
||||
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
|
||||
return (hfp->IsConnected());
|
||||
profile = BluetoothHfpManager::Get();
|
||||
} else if (aProfileId == BluetoothServiceClass::OBJECT_PUSH) {
|
||||
BluetoothOppManager* opp = BluetoothOppManager::Get();
|
||||
return opp->IsTransferring();
|
||||
profile = BluetoothOppManager::Get();
|
||||
} else {
|
||||
NS_WARNING(ERR_UNKNOWN_PROFILE);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
NS_ENSURE_TRUE(profile, false);
|
||||
return profile->IsConnected();
|
||||
}
|
||||
|
||||
class ConnectBluetoothSocketRunnable : public nsRunnable
|
||||
@ -2829,6 +2872,16 @@ BluetoothDBusService::SendMetaData(const nsAString& aTitle,
|
||||
BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
|
||||
NS_ENSURE_TRUE_VOID(a2dp);
|
||||
|
||||
if (!a2dp->IsConnected()) {
|
||||
DispatchBluetoothReply(aRunnable, BluetoothValue(),
|
||||
NS_LITERAL_STRING(ERR_A2DP_IS_DISCONNECTED));
|
||||
return;
|
||||
} else if (!a2dp->IsAvrcpConnected()) {
|
||||
DispatchBluetoothReply(aRunnable, BluetoothValue(),
|
||||
NS_LITERAL_STRING(ERR_AVRCP_IS_DISCONNECTED));
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString address;
|
||||
a2dp->GetAddress(address);
|
||||
nsString objectPath =
|
||||
@ -2916,6 +2969,16 @@ BluetoothDBusService::SendPlayStatus(uint32_t aDuration,
|
||||
BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
|
||||
NS_ENSURE_TRUE_VOID(a2dp);
|
||||
|
||||
if (!a2dp->IsConnected()) {
|
||||
DispatchBluetoothReply(aRunnable, BluetoothValue(),
|
||||
NS_LITERAL_STRING(ERR_A2DP_IS_DISCONNECTED));
|
||||
return;
|
||||
} else if (!a2dp->IsAvrcpConnected()) {
|
||||
DispatchBluetoothReply(aRunnable, BluetoothValue(),
|
||||
NS_LITERAL_STRING(ERR_AVRCP_IS_DISCONNECTED));
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString address;
|
||||
a2dp->GetAddress(address);
|
||||
nsString objectPath =
|
||||
|
Loading…
Reference in New Issue
Block a user