mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 830213 - Patch 2: Implementation of ConnectSco/DisconnectSco/IsScoConnected in BluetoothHfpManager, r=echou, sr=mrbkap
This commit is contained in:
parent
4fada6d52b
commit
0d6b87eddd
@ -31,6 +31,7 @@
|
||||
#define MOZSETTINGS_CHANGED_ID "mozsettings-changed"
|
||||
#define MOBILE_CONNECTION_ICCINFO_CHANGED "mobile-connection-iccinfo-changed"
|
||||
#define MOBILE_CONNECTION_VOICE_CHANGED "mobile-connection-voice-changed"
|
||||
#define BLUETOOTH_SCO_STATUS_CHANGED "bluetooth-sco-status-changed"
|
||||
|
||||
/**
|
||||
* These constants are used in result code such as +CLIP and +CCWA. The value
|
||||
@ -125,7 +126,7 @@ class mozilla::dom::bluetooth::Call {
|
||||
public:
|
||||
Call(uint16_t aState = nsITelephonyProvider::CALL_STATE_DISCONNECTED,
|
||||
bool aDirection = false,
|
||||
const nsAString& aNumber = NS_LITERAL_STRING(""),
|
||||
const nsAString& aNumber = EmptyString(),
|
||||
int aType = TOA_UNKNOWN)
|
||||
: mState(aState), mDirection(aDirection), mNumber(aNumber), mType(aType)
|
||||
{
|
||||
@ -439,6 +440,12 @@ BluetoothHfpManager::Init()
|
||||
|
||||
Listen();
|
||||
|
||||
mScoSocket = new BluetoothSocket(this,
|
||||
BluetoothSocketType::SCO,
|
||||
true,
|
||||
false);
|
||||
mScoSocketStatus = mScoSocket->GetConnectionStatus();
|
||||
ListenSco();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -497,7 +504,7 @@ BluetoothHfpManager::NotifySettings()
|
||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||
|
||||
name.AssignLiteral("address");
|
||||
v = mDevicePath;
|
||||
v = mDeviceAddress;
|
||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||
|
||||
if (!BroadcastSystemMessage(type, parameters)) {
|
||||
@ -524,6 +531,22 @@ BluetoothHfpManager::NotifyDialer(const nsAString& aCommand)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::NotifyAudioManager(const nsAString& aAddress)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs =
|
||||
do_GetService("@mozilla.org/observer-service;1");
|
||||
NS_ENSURE_TRUE_VOID(obs);
|
||||
|
||||
if (NS_FAILED(obs->NotifyObservers(nullptr,
|
||||
BLUETOOTH_SCO_STATUS_CHANGED,
|
||||
aAddress.BeginReading()))) {
|
||||
NS_WARNING("Failed to notify bluetooth-sco-status-changed observsers!");
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothHfpManager::HandleVolumeChanged(const nsAString& aData)
|
||||
{
|
||||
@ -682,6 +705,7 @@ BluetoothHfpManager::HandleShutdown()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
gInShutdown = true;
|
||||
Disconnect();
|
||||
DisconnectSco();
|
||||
gBluetoothHfpManager = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1030,7 +1054,7 @@ BluetoothHfpManager::Listen()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (gInShutdown) {
|
||||
MOZ_ASSERT(false, "Listen called while in shutdown!");
|
||||
NS_WARNING("Listen called while in shutdown!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1383,6 +1407,12 @@ BluetoothHfpManager::OnConnectSuccess(BluetoothSocket* aSocket)
|
||||
{
|
||||
MOZ_ASSERT(aSocket);
|
||||
|
||||
// Success to create a SCO socket
|
||||
if (aSocket == mScoSocket) {
|
||||
OnScoConnectSuccess();
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the created connection is an inbound connection, close another server
|
||||
* socket because currently only one SLC is allowed. After that, we need to
|
||||
@ -1415,27 +1445,35 @@ BluetoothHfpManager::OnConnectSuccess(BluetoothSocket* aSocket)
|
||||
nsString errorStr;
|
||||
DispatchBluetoothReply(mRunnable, v, errorStr);
|
||||
|
||||
mRunnable.forget();
|
||||
mRunnable = nullptr;
|
||||
}
|
||||
|
||||
mFirstCKPD = true;
|
||||
|
||||
// Cache device path for NotifySettings() since we can't get socket address
|
||||
// when a headset disconnect with us
|
||||
mSocket->GetAddress(mDevicePath);
|
||||
|
||||
mSocket->GetAddress(mDeviceAddress);
|
||||
NotifySettings();
|
||||
|
||||
ListenSco();
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::OnConnectError(BluetoothSocket* aSocket)
|
||||
{
|
||||
// Failed to create a SCO socket
|
||||
if (aSocket == mScoSocket) {
|
||||
OnScoConnectError();
|
||||
return;
|
||||
}
|
||||
|
||||
// For active connection request, we need to reply the DOMRequest
|
||||
if (mRunnable) {
|
||||
BluetoothValue v;
|
||||
DispatchBluetoothReply(mRunnable, v,
|
||||
NS_LITERAL_STRING("OnConnectError:no runnable"));
|
||||
mRunnable.forget();
|
||||
NS_NAMED_LITERAL_STRING(replyError,
|
||||
"Failed to connect with a bluetooth headset!");
|
||||
DispatchBluetoothReply(mRunnable, BluetoothValue(), replyError);
|
||||
|
||||
mRunnable = nullptr;
|
||||
}
|
||||
|
||||
mSocket = nullptr;
|
||||
@ -1451,13 +1489,19 @@ BluetoothHfpManager::OnDisconnect(BluetoothSocket* aSocket)
|
||||
{
|
||||
MOZ_ASSERT(aSocket);
|
||||
|
||||
if (aSocket == mScoSocket) {
|
||||
// SCO socket is closed
|
||||
OnScoDisconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
if (aSocket != mSocket) {
|
||||
// Do nothing when a listening server socket is closed.
|
||||
return;
|
||||
}
|
||||
|
||||
mSocket = nullptr;
|
||||
CloseScoSocket();
|
||||
DisconnectSco();
|
||||
|
||||
Listen();
|
||||
NotifySettings();
|
||||
@ -1491,6 +1535,43 @@ BluetoothHfpManager::OnGetServiceChannel(const nsAString& aDeviceAddress,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::OnScoConnectSuccess()
|
||||
{
|
||||
// For active connection request, we need to reply the DOMRequest
|
||||
if (mScoRunnable) {
|
||||
DispatchBluetoothReply(mScoRunnable,
|
||||
BluetoothValue(true), EmptyString());
|
||||
mScoRunnable = nullptr;
|
||||
}
|
||||
|
||||
NotifyAudioManager(mDeviceAddress);
|
||||
|
||||
mScoSocketStatus = mScoSocket->GetConnectionStatus();
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::OnScoConnectError()
|
||||
{
|
||||
if (mScoRunnable) {
|
||||
NS_NAMED_LITERAL_STRING(replyError, "Failed to create SCO socket!");
|
||||
DispatchBluetoothReply(mScoRunnable, BluetoothValue(), replyError);
|
||||
|
||||
mScoRunnable = nullptr;
|
||||
}
|
||||
|
||||
ListenSco();
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::OnScoDisconnect()
|
||||
{
|
||||
if (mScoSocketStatus == SocketConnectionStatus::SOCKET_CONNECTED) {
|
||||
ListenSco();
|
||||
NotifyAudioManager(EmptyString());
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothHfpManager::IsConnected()
|
||||
{
|
||||
@ -1507,3 +1588,86 @@ BluetoothHfpManager::GetAddress(nsAString& aDeviceAddress)
|
||||
{
|
||||
return mSocket->GetAddress(aDeviceAddress);
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothHfpManager::ConnectSco(BluetoothReplyRunnable* aRunnable)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (gInShutdown) {
|
||||
NS_WARNING("ConnecteSco called while in shutdown!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsConnected()) {
|
||||
NS_WARNING("BluetoothHfpManager is not connected");
|
||||
return false;
|
||||
}
|
||||
|
||||
SocketConnectionStatus status = mScoSocket->GetConnectionStatus();
|
||||
if (status == SocketConnectionStatus::SOCKET_CONNECTED ||
|
||||
status == SocketConnectionStatus::SOCKET_CONNECTING ||
|
||||
(mScoRunnable && (mScoRunnable != aRunnable))) {
|
||||
NS_WARNING("SCO connection exists or is being established");
|
||||
return false;
|
||||
}
|
||||
|
||||
mScoSocket->Disconnect();
|
||||
|
||||
mScoRunnable = aRunnable;
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
NS_ENSURE_TRUE(bs, false);
|
||||
nsresult rv = bs->GetScoSocket(mDeviceAddress, true, false, mScoSocket);
|
||||
|
||||
return NS_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothHfpManager::DisconnectSco()
|
||||
{
|
||||
if (!mScoSocket) {
|
||||
NS_WARNING("BluetoothHfpManager is not connected");
|
||||
return false;
|
||||
}
|
||||
|
||||
mScoSocket->Disconnect();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothHfpManager::ListenSco()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (gInShutdown) {
|
||||
NS_WARNING("ListenSco called while in shutdown!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mScoSocket->GetConnectionStatus() ==
|
||||
SocketConnectionStatus::SOCKET_LISTENING) {
|
||||
NS_WARNING("SCO socket has been already listening");
|
||||
return false;
|
||||
}
|
||||
|
||||
mScoSocket->Disconnect();
|
||||
|
||||
if (!mScoSocket->Listen(-1)) {
|
||||
NS_WARNING("Can't listen on SCO socket!");
|
||||
return false;
|
||||
}
|
||||
|
||||
mScoSocketStatus = mScoSocket->GetConnectionStatus();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothHfpManager::IsScoConnected()
|
||||
{
|
||||
if (mScoSocket) {
|
||||
return mScoSocket->GetConnectionStatus() ==
|
||||
SocketConnectionStatus::SOCKET_CONNECTED;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -73,6 +73,9 @@ public:
|
||||
BluetoothReplyRunnable* aRunnable);
|
||||
void Disconnect();
|
||||
bool Listen();
|
||||
bool ConnectSco(BluetoothReplyRunnable* aRunnable = nullptr);
|
||||
bool DisconnectSco();
|
||||
bool ListenSco();
|
||||
|
||||
/**
|
||||
* @param aSend A boolean indicates whether we need to notify headset or not
|
||||
@ -82,6 +85,7 @@ public:
|
||||
bool aSend);
|
||||
|
||||
bool IsConnected();
|
||||
bool IsScoConnected();
|
||||
void GetAddress(nsAString& aDeviceAddress);
|
||||
|
||||
private:
|
||||
@ -107,10 +111,14 @@ private:
|
||||
|
||||
void NotifyDialer(const nsAString& aCommand);
|
||||
void NotifySettings();
|
||||
void NotifyAudioManager(const nsAString& aAddress);
|
||||
|
||||
bool SendCommand(const char* aCommand, uint8_t aValue = 0);
|
||||
bool SendLine(const char* aMessage);
|
||||
void UpdateCIND(uint8_t aType, uint8_t aValue, bool aSend);
|
||||
void OnScoConnectSuccess();
|
||||
void OnScoConnectError();
|
||||
void OnScoDisconnect();
|
||||
|
||||
int mCurrentVgs;
|
||||
int mCurrentVgm;
|
||||
@ -123,13 +131,14 @@ private:
|
||||
int mNetworkSelectionMode;
|
||||
bool mReceiveVgsFlag;
|
||||
bool mBLDNProcessed;
|
||||
nsString mDevicePath;
|
||||
nsString mDeviceAddress;
|
||||
nsString mMsisdn;
|
||||
nsString mOperatorName;
|
||||
|
||||
nsTArray<Call> mCurrentCallArray;
|
||||
nsAutoPtr<BluetoothTelephonyListener> mListener;
|
||||
nsRefPtr<BluetoothReplyRunnable> mRunnable;
|
||||
nsRefPtr<BluetoothReplyRunnable> mScoRunnable;
|
||||
|
||||
// If a connection has been established, mSocket will be the socket
|
||||
// communicating with the remote socket. We maintain the invariant that if
|
||||
@ -142,6 +151,8 @@ private:
|
||||
// is called.
|
||||
nsRefPtr<BluetoothSocket> mHandsfreeSocket;
|
||||
nsRefPtr<BluetoothSocket> mHeadsetSocket;
|
||||
nsRefPtr<BluetoothSocket> mScoSocket;
|
||||
SocketConnectionStatus mScoSocketStatus;
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
Loading…
Reference in New Issue
Block a user