зеркало из https://github.com/mozilla/gecko-dev.git
Bug 906305 - Patch 4: Fix BluetoothHfpManager, r=echou
This commit is contained in:
Родитель
53070ae399
Коммит
b49c5f26fd
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include "BluetoothHfpManager.h"
|
||||
|
||||
#include "BluetoothA2dpManager.h"
|
||||
#include "BluetoothProfileController.h"
|
||||
#include "BluetoothReplyRunnable.h"
|
||||
#include "BluetoothService.h"
|
||||
#include "BluetoothSocket.h"
|
||||
|
@ -358,6 +358,8 @@ BluetoothHfpManager::Reset()
|
|||
// Please see Bug 878728 for more information.
|
||||
mBSIR = false;
|
||||
|
||||
mController = nullptr;
|
||||
|
||||
ResetCallArray();
|
||||
}
|
||||
|
||||
|
@ -657,7 +659,7 @@ BluetoothHfpManager::HandleShutdown()
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
sInShutdown = true;
|
||||
Disconnect();
|
||||
Disconnect(nullptr);
|
||||
DisconnectSco();
|
||||
sBluetoothHfpManager = nullptr;
|
||||
}
|
||||
|
@ -1000,43 +1002,38 @@ respond_with_ok:
|
|||
|
||||
void
|
||||
BluetoothHfpManager::Connect(const nsAString& aDeviceAddress,
|
||||
const bool aIsHandsfree,
|
||||
BluetoothReplyRunnable* aRunnable)
|
||||
BluetoothProfileController* aController)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aController && !mController);
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
if (!bs || sInShutdown) {
|
||||
DispatchBluetoothReply(aRunnable, BluetoothValue(),
|
||||
NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
|
||||
aController->OnConnect(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSocket) {
|
||||
if (mDeviceAddress == aDeviceAddress) {
|
||||
DispatchBluetoothReply(aRunnable, BluetoothValue(),
|
||||
NS_LITERAL_STRING(ERR_ALREADY_CONNECTED));
|
||||
aController->OnConnect(NS_LITERAL_STRING(ERR_ALREADY_CONNECTED));
|
||||
} else {
|
||||
DispatchBluetoothReply(aRunnable, BluetoothValue(),
|
||||
NS_LITERAL_STRING(ERR_REACHED_CONNECTION_LIMIT));
|
||||
aController->OnConnect(NS_LITERAL_STRING(ERR_REACHED_CONNECTION_LIMIT));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
mNeedsUpdatingSdpRecords = true;
|
||||
mIsHandsfree = aIsHandsfree;
|
||||
mIsHandsfree = !IS_HEADSET(aController->GetCod());
|
||||
|
||||
nsString uuid;
|
||||
if (aIsHandsfree) {
|
||||
if (mIsHandsfree) {
|
||||
BluetoothUuidHelper::GetString(BluetoothServiceClass::HANDSFREE, uuid);
|
||||
} else {
|
||||
BluetoothUuidHelper::GetString(BluetoothServiceClass::HEADSET, uuid);
|
||||
}
|
||||
|
||||
if (NS_FAILED(bs->GetServiceChannel(aDeviceAddress, uuid, this))) {
|
||||
DispatchBluetoothReply(aRunnable, BluetoothValue(),
|
||||
NS_LITERAL_STRING(ERR_SERVICE_CHANNEL_NOT_FOUND));
|
||||
aController->OnConnect(NS_LITERAL_STRING(ERR_SERVICE_CHANNEL_NOT_FOUND));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1051,9 +1048,7 @@ BluetoothHfpManager::Connect(const nsAString& aDeviceAddress,
|
|||
mHeadsetSocket = nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mRunnable);
|
||||
|
||||
mRunnable = aRunnable;
|
||||
mController = aController;
|
||||
mSocket =
|
||||
new BluetoothSocket(this, BluetoothSocketType::RFCOMM, true, true);
|
||||
}
|
||||
|
@ -1103,16 +1098,22 @@ BluetoothHfpManager::Listen()
|
|||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::Disconnect()
|
||||
BluetoothHfpManager::Disconnect(BluetoothProfileController* aController)
|
||||
{
|
||||
if (mSocket) {
|
||||
mSocket->Disconnect();
|
||||
mSocket = nullptr;
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mSocket) {
|
||||
if (aController) {
|
||||
aController->OnDisconnect(NS_LITERAL_STRING(ERR_ALREADY_DISCONNECTED));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
|
||||
NS_ENSURE_TRUE_VOID(a2dp);
|
||||
a2dp->Disconnect();
|
||||
MOZ_ASSERT(!mController);
|
||||
|
||||
mController = aController;
|
||||
mSocket->Disconnect();
|
||||
mSocket = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1450,7 +1451,7 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
|
|||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::OnConnectSuccess(BluetoothSocket* aSocket)
|
||||
BluetoothHfpManager::OnSocketConnectSuccess(BluetoothSocket* aSocket)
|
||||
{
|
||||
MOZ_ASSERT(aSocket);
|
||||
|
||||
|
@ -1486,15 +1487,6 @@ BluetoothHfpManager::OnConnectSuccess(BluetoothSocket* aSocket)
|
|||
NS_ENSURE_TRUE_VOID(provider);
|
||||
provider->EnumerateCalls(mListener->GetListener());
|
||||
|
||||
// For active connection request, we need to reply the DOMRequest
|
||||
if (mRunnable) {
|
||||
BluetoothValue v = true;
|
||||
nsString errorStr;
|
||||
DispatchBluetoothReply(mRunnable, v, errorStr);
|
||||
|
||||
mRunnable = nullptr;
|
||||
}
|
||||
|
||||
mFirstCKPD = true;
|
||||
|
||||
// Cache device path for NotifySettings() since we can't get socket address
|
||||
|
@ -1505,13 +1497,11 @@ BluetoothHfpManager::OnConnectSuccess(BluetoothSocket* aSocket)
|
|||
|
||||
ListenSco();
|
||||
|
||||
BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
|
||||
NS_ENSURE_TRUE_VOID(a2dp);
|
||||
a2dp->Connect(mDeviceAddress);
|
||||
OnConnect(EmptyString());
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::OnConnectError(BluetoothSocket* aSocket)
|
||||
BluetoothHfpManager::OnSocketConnectError(BluetoothSocket* aSocket)
|
||||
{
|
||||
// Failed to create a SCO socket
|
||||
if (aSocket == mScoSocket) {
|
||||
|
@ -1519,25 +1509,14 @@ BluetoothHfpManager::OnConnectError(BluetoothSocket* aSocket)
|
|||
return;
|
||||
}
|
||||
|
||||
// For active connection request, we need to reply the DOMRequest
|
||||
if (mRunnable) {
|
||||
NS_NAMED_LITERAL_STRING(replyError,
|
||||
"Failed to connect with a bluetooth headset!");
|
||||
DispatchBluetoothReply(mRunnable, BluetoothValue(), replyError);
|
||||
|
||||
mRunnable = nullptr;
|
||||
}
|
||||
|
||||
mSocket = nullptr;
|
||||
mHandsfreeSocket = nullptr;
|
||||
mHeadsetSocket = nullptr;
|
||||
|
||||
// If connecting for some reason didn't work, restart listening
|
||||
Listen();
|
||||
OnConnect(NS_LITERAL_STRING("SocketConnectionError"));
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::OnDisconnect(BluetoothSocket* aSocket)
|
||||
BluetoothHfpManager::OnSocketDisconnect(BluetoothSocket* aSocket)
|
||||
{
|
||||
MOZ_ASSERT(aSocket);
|
||||
|
||||
|
@ -1552,12 +1531,12 @@ BluetoothHfpManager::OnDisconnect(BluetoothSocket* aSocket)
|
|||
return;
|
||||
}
|
||||
|
||||
mSocket = nullptr;
|
||||
DisconnectSco();
|
||||
|
||||
Listen();
|
||||
NotifyConnectionStatusChanged(NS_LITERAL_STRING(BLUETOOTH_HFP_STATUS_CHANGED_ID));
|
||||
DispatchConnectionStatusChanged(NS_LITERAL_STRING(HFP_STATUS_CHANGED_ID));
|
||||
OnDisconnect(EmptyString());
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
@ -1581,11 +1560,7 @@ BluetoothHfpManager::OnUpdateSdpRecords(const nsAString& aDeviceAddress)
|
|||
// Since we have updated SDP records of the target device, we should
|
||||
// try to get the channel of target service again.
|
||||
if (NS_FAILED(bs->GetServiceChannel(aDeviceAddress, uuid, this))) {
|
||||
DispatchBluetoothReply(mRunnable, BluetoothValue(),
|
||||
NS_LITERAL_STRING(ERR_SERVICE_CHANNEL_NOT_FOUND));
|
||||
mRunnable = nullptr;
|
||||
mSocket = nullptr;
|
||||
Listen();
|
||||
OnConnect(NS_LITERAL_STRING(ERR_SERVICE_CHANNEL_NOT_FOUND));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1596,7 +1571,6 @@ BluetoothHfpManager::OnGetServiceChannel(const nsAString& aDeviceAddress,
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!aDeviceAddress.IsEmpty());
|
||||
MOZ_ASSERT(mRunnable);
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
NS_ENSURE_TRUE_VOID(bs);
|
||||
|
@ -1608,22 +1582,14 @@ BluetoothHfpManager::OnGetServiceChannel(const nsAString& aDeviceAddress,
|
|||
mNeedsUpdatingSdpRecords = false;
|
||||
bs->UpdateSdpRecords(aDeviceAddress, this);
|
||||
} else {
|
||||
DispatchBluetoothReply(mRunnable, v,
|
||||
NS_LITERAL_STRING(ERR_SERVICE_CHANNEL_NOT_FOUND));
|
||||
mRunnable = nullptr;
|
||||
mSocket = nullptr;
|
||||
Listen();
|
||||
OnConnect(NS_LITERAL_STRING(ERR_SERVICE_CHANNEL_NOT_FOUND));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mSocket->Connect(NS_ConvertUTF16toUTF8(aDeviceAddress), aChannel)) {
|
||||
DispatchBluetoothReply(mRunnable, v,
|
||||
NS_LITERAL_STRING("SocketConnectionError"));
|
||||
mRunnable = nullptr;
|
||||
mSocket = nullptr;
|
||||
Listen();
|
||||
OnConnect(NS_LITERAL_STRING("SocketConnectionError"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1773,4 +1739,44 @@ BluetoothHfpManager::IsScoConnected()
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::OnConnect(const nsAString& aErrorStr)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// When we failed to create a socket, restart listening.
|
||||
if (!aErrorStr.IsEmpty()) {
|
||||
mSocket = nullptr;
|
||||
Listen();
|
||||
}
|
||||
|
||||
/**
|
||||
* On the one hand, notify the controller that we've done for outbound
|
||||
* connections. On the other hand, we do nothing for inbound connections.
|
||||
*/
|
||||
NS_ENSURE_TRUE_VOID(mController);
|
||||
|
||||
mController->OnConnect(aErrorStr);
|
||||
mController = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::OnDisconnect(const nsAString& aErrorStr)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Start listening
|
||||
mSocket = nullptr;
|
||||
Listen();
|
||||
|
||||
/**
|
||||
* On the one hand, notify the controller that we've done for outbound
|
||||
* connections. On the other hand, we do nothing for inbound connections.
|
||||
*/
|
||||
NS_ENSURE_TRUE_VOID(mController);
|
||||
|
||||
mController->OnDisconnect(aErrorStr);
|
||||
mController = nullptr;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(BluetoothHfpManager, nsIObserver)
|
||||
|
|
|
@ -61,22 +61,26 @@ public:
|
|||
static BluetoothHfpManager* Get();
|
||||
~BluetoothHfpManager();
|
||||
|
||||
// The following functions are inherited from BluetoothSocketObserver
|
||||
virtual void ReceiveSocketData(
|
||||
BluetoothSocket* aSocket,
|
||||
nsAutoPtr<mozilla::ipc::UnixSocketRawData>& aMessage) MOZ_OVERRIDE;
|
||||
virtual void OnConnectSuccess(BluetoothSocket* aSocket) MOZ_OVERRIDE;
|
||||
virtual void OnConnectError(BluetoothSocket* aSocket) MOZ_OVERRIDE;
|
||||
virtual void OnDisconnect(BluetoothSocket* aSocket) MOZ_OVERRIDE;
|
||||
virtual void OnSocketConnectSuccess(BluetoothSocket* aSocket) MOZ_OVERRIDE;
|
||||
virtual void OnSocketConnectError(BluetoothSocket* aSocket) MOZ_OVERRIDE;
|
||||
virtual void OnSocketDisconnect(BluetoothSocket* aSocket) MOZ_OVERRIDE;
|
||||
|
||||
// The following functions are inherited from 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 void Connect(const nsAString& aDeviceAddress,
|
||||
BluetoothProfileController* aController) MOZ_OVERRIDE;
|
||||
virtual void Disconnect(BluetoothProfileController* aController) MOZ_OVERRIDE;
|
||||
virtual void OnConnect(const nsAString& aErrorStr) MOZ_OVERRIDE;
|
||||
virtual void OnDisconnect(const nsAString& AErrorStr) MOZ_OVERRIDE;
|
||||
|
||||
void Connect(const nsAString& aDeviceAddress,
|
||||
const bool aIsHandsfree,
|
||||
BluetoothReplyRunnable* aRunnable);
|
||||
void Disconnect();
|
||||
bool Listen();
|
||||
bool ConnectSco(BluetoothReplyRunnable* aRunnable = nullptr);
|
||||
bool DisconnectSco();
|
||||
|
@ -148,6 +152,7 @@ private:
|
|||
nsTArray<Call> mCurrentCallArray;
|
||||
nsAutoPtr<BluetoothTelephonyListener> mListener;
|
||||
nsRefPtr<BluetoothReplyRunnable> mRunnable;
|
||||
BluetoothProfileController* mController;
|
||||
nsRefPtr<BluetoothReplyRunnable> mScoRunnable;
|
||||
|
||||
// If a connection has been established, mSocket will be the socket
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "nsIObserver.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
class BluetoothProfileController;
|
||||
|
||||
class BluetoothProfileManagerBase : public nsIObserver
|
||||
{
|
||||
|
@ -31,8 +32,35 @@ public:
|
|||
const nsAString& aServiceUuid,
|
||||
int aChannel) = 0;
|
||||
virtual void OnUpdateSdpRecords(const nsAString& aDeviceAddress) = 0;
|
||||
|
||||
/**
|
||||
* Returns the address of the connected device.
|
||||
*/
|
||||
virtual void GetAddress(nsAString& aDeviceAddress) = 0;
|
||||
|
||||
/**
|
||||
* Returns true if the profile is connected.
|
||||
*/
|
||||
virtual bool IsConnected() = 0;
|
||||
|
||||
/**
|
||||
* Connect to a specific remote device. When it has been done, the
|
||||
* callback "OnConnect" will be invoked.
|
||||
*/
|
||||
virtual void Connect(const nsAString& aDeviceAddress,
|
||||
BluetoothProfileController* aController) = 0;
|
||||
|
||||
/**
|
||||
* Close the socket and then invoke the callback "OnDisconnect".
|
||||
*/
|
||||
virtual void Disconnect(BluetoothProfileController* aController) = 0;
|
||||
|
||||
/**
|
||||
* If it establishes/releases a connection successfully, the error string
|
||||
* will be empty. Otherwise, the error string shows the failure reason.
|
||||
*/
|
||||
virtual void OnConnect(const nsAString& aErrorStr) = 0;
|
||||
virtual void OnDisconnect(const nsAString& aErrorStr) = 0;
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
|
Загрузка…
Ссылка в новой задаче