зеркало из 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 "BluetoothHfpManager.h"
|
||||||
|
|
||||||
#include "BluetoothA2dpManager.h"
|
#include "BluetoothProfileController.h"
|
||||||
#include "BluetoothReplyRunnable.h"
|
#include "BluetoothReplyRunnable.h"
|
||||||
#include "BluetoothService.h"
|
#include "BluetoothService.h"
|
||||||
#include "BluetoothSocket.h"
|
#include "BluetoothSocket.h"
|
||||||
|
@ -358,6 +358,8 @@ BluetoothHfpManager::Reset()
|
||||||
// Please see Bug 878728 for more information.
|
// Please see Bug 878728 for more information.
|
||||||
mBSIR = false;
|
mBSIR = false;
|
||||||
|
|
||||||
|
mController = nullptr;
|
||||||
|
|
||||||
ResetCallArray();
|
ResetCallArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,7 +659,7 @@ BluetoothHfpManager::HandleShutdown()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
sInShutdown = true;
|
sInShutdown = true;
|
||||||
Disconnect();
|
Disconnect(nullptr);
|
||||||
DisconnectSco();
|
DisconnectSco();
|
||||||
sBluetoothHfpManager = nullptr;
|
sBluetoothHfpManager = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -1000,43 +1002,38 @@ respond_with_ok:
|
||||||
|
|
||||||
void
|
void
|
||||||
BluetoothHfpManager::Connect(const nsAString& aDeviceAddress,
|
BluetoothHfpManager::Connect(const nsAString& aDeviceAddress,
|
||||||
const bool aIsHandsfree,
|
BluetoothProfileController* aController)
|
||||||
BluetoothReplyRunnable* aRunnable)
|
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
MOZ_ASSERT(aController && !mController);
|
||||||
|
|
||||||
BluetoothService* bs = BluetoothService::Get();
|
BluetoothService* bs = BluetoothService::Get();
|
||||||
if (!bs || sInShutdown) {
|
if (!bs || sInShutdown) {
|
||||||
DispatchBluetoothReply(aRunnable, BluetoothValue(),
|
aController->OnConnect(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
|
||||||
NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSocket) {
|
if (mSocket) {
|
||||||
if (mDeviceAddress == aDeviceAddress) {
|
if (mDeviceAddress == aDeviceAddress) {
|
||||||
DispatchBluetoothReply(aRunnable, BluetoothValue(),
|
aController->OnConnect(NS_LITERAL_STRING(ERR_ALREADY_CONNECTED));
|
||||||
NS_LITERAL_STRING(ERR_ALREADY_CONNECTED));
|
|
||||||
} else {
|
} else {
|
||||||
DispatchBluetoothReply(aRunnable, BluetoothValue(),
|
aController->OnConnect(NS_LITERAL_STRING(ERR_REACHED_CONNECTION_LIMIT));
|
||||||
NS_LITERAL_STRING(ERR_REACHED_CONNECTION_LIMIT));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mNeedsUpdatingSdpRecords = true;
|
mNeedsUpdatingSdpRecords = true;
|
||||||
mIsHandsfree = aIsHandsfree;
|
mIsHandsfree = !IS_HEADSET(aController->GetCod());
|
||||||
|
|
||||||
nsString uuid;
|
nsString uuid;
|
||||||
if (aIsHandsfree) {
|
if (mIsHandsfree) {
|
||||||
BluetoothUuidHelper::GetString(BluetoothServiceClass::HANDSFREE, uuid);
|
BluetoothUuidHelper::GetString(BluetoothServiceClass::HANDSFREE, uuid);
|
||||||
} else {
|
} else {
|
||||||
BluetoothUuidHelper::GetString(BluetoothServiceClass::HEADSET, uuid);
|
BluetoothUuidHelper::GetString(BluetoothServiceClass::HEADSET, uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_FAILED(bs->GetServiceChannel(aDeviceAddress, uuid, this))) {
|
if (NS_FAILED(bs->GetServiceChannel(aDeviceAddress, uuid, this))) {
|
||||||
DispatchBluetoothReply(aRunnable, BluetoothValue(),
|
aController->OnConnect(NS_LITERAL_STRING(ERR_SERVICE_CHANNEL_NOT_FOUND));
|
||||||
NS_LITERAL_STRING(ERR_SERVICE_CHANNEL_NOT_FOUND));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1051,9 +1048,7 @@ BluetoothHfpManager::Connect(const nsAString& aDeviceAddress,
|
||||||
mHeadsetSocket = nullptr;
|
mHeadsetSocket = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(!mRunnable);
|
mController = aController;
|
||||||
|
|
||||||
mRunnable = aRunnable;
|
|
||||||
mSocket =
|
mSocket =
|
||||||
new BluetoothSocket(this, BluetoothSocketType::RFCOMM, true, true);
|
new BluetoothSocket(this, BluetoothSocketType::RFCOMM, true, true);
|
||||||
}
|
}
|
||||||
|
@ -1103,16 +1098,22 @@ BluetoothHfpManager::Listen()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BluetoothHfpManager::Disconnect()
|
BluetoothHfpManager::Disconnect(BluetoothProfileController* aController)
|
||||||
{
|
{
|
||||||
if (mSocket) {
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
mSocket->Disconnect();
|
|
||||||
mSocket = nullptr;
|
if (!mSocket) {
|
||||||
|
if (aController) {
|
||||||
|
aController->OnDisconnect(NS_LITERAL_STRING(ERR_ALREADY_DISCONNECTED));
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
|
MOZ_ASSERT(!mController);
|
||||||
NS_ENSURE_TRUE_VOID(a2dp);
|
|
||||||
a2dp->Disconnect();
|
mController = aController;
|
||||||
|
mSocket->Disconnect();
|
||||||
|
mSocket = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -1450,7 +1451,7 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BluetoothHfpManager::OnConnectSuccess(BluetoothSocket* aSocket)
|
BluetoothHfpManager::OnSocketConnectSuccess(BluetoothSocket* aSocket)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aSocket);
|
MOZ_ASSERT(aSocket);
|
||||||
|
|
||||||
|
@ -1486,15 +1487,6 @@ BluetoothHfpManager::OnConnectSuccess(BluetoothSocket* aSocket)
|
||||||
NS_ENSURE_TRUE_VOID(provider);
|
NS_ENSURE_TRUE_VOID(provider);
|
||||||
provider->EnumerateCalls(mListener->GetListener());
|
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;
|
mFirstCKPD = true;
|
||||||
|
|
||||||
// Cache device path for NotifySettings() since we can't get socket address
|
// Cache device path for NotifySettings() since we can't get socket address
|
||||||
|
@ -1505,13 +1497,11 @@ BluetoothHfpManager::OnConnectSuccess(BluetoothSocket* aSocket)
|
||||||
|
|
||||||
ListenSco();
|
ListenSco();
|
||||||
|
|
||||||
BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
|
OnConnect(EmptyString());
|
||||||
NS_ENSURE_TRUE_VOID(a2dp);
|
|
||||||
a2dp->Connect(mDeviceAddress);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BluetoothHfpManager::OnConnectError(BluetoothSocket* aSocket)
|
BluetoothHfpManager::OnSocketConnectError(BluetoothSocket* aSocket)
|
||||||
{
|
{
|
||||||
// Failed to create a SCO socket
|
// Failed to create a SCO socket
|
||||||
if (aSocket == mScoSocket) {
|
if (aSocket == mScoSocket) {
|
||||||
|
@ -1519,25 +1509,14 @@ BluetoothHfpManager::OnConnectError(BluetoothSocket* aSocket)
|
||||||
return;
|
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;
|
mHandsfreeSocket = nullptr;
|
||||||
mHeadsetSocket = nullptr;
|
mHeadsetSocket = nullptr;
|
||||||
|
|
||||||
// If connecting for some reason didn't work, restart listening
|
OnConnect(NS_LITERAL_STRING("SocketConnectionError"));
|
||||||
Listen();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BluetoothHfpManager::OnDisconnect(BluetoothSocket* aSocket)
|
BluetoothHfpManager::OnSocketDisconnect(BluetoothSocket* aSocket)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aSocket);
|
MOZ_ASSERT(aSocket);
|
||||||
|
|
||||||
|
@ -1552,12 +1531,12 @@ BluetoothHfpManager::OnDisconnect(BluetoothSocket* aSocket)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mSocket = nullptr;
|
|
||||||
DisconnectSco();
|
DisconnectSco();
|
||||||
|
|
||||||
Listen();
|
|
||||||
NotifyConnectionStatusChanged(NS_LITERAL_STRING(BLUETOOTH_HFP_STATUS_CHANGED_ID));
|
NotifyConnectionStatusChanged(NS_LITERAL_STRING(BLUETOOTH_HFP_STATUS_CHANGED_ID));
|
||||||
DispatchConnectionStatusChanged(NS_LITERAL_STRING(HFP_STATUS_CHANGED_ID));
|
DispatchConnectionStatusChanged(NS_LITERAL_STRING(HFP_STATUS_CHANGED_ID));
|
||||||
|
OnDisconnect(EmptyString());
|
||||||
|
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1581,11 +1560,7 @@ BluetoothHfpManager::OnUpdateSdpRecords(const nsAString& aDeviceAddress)
|
||||||
// Since we have updated SDP records of the target device, we should
|
// Since we have updated SDP records of the target device, we should
|
||||||
// try to get the channel of target service again.
|
// try to get the channel of target service again.
|
||||||
if (NS_FAILED(bs->GetServiceChannel(aDeviceAddress, uuid, this))) {
|
if (NS_FAILED(bs->GetServiceChannel(aDeviceAddress, uuid, this))) {
|
||||||
DispatchBluetoothReply(mRunnable, BluetoothValue(),
|
OnConnect(NS_LITERAL_STRING(ERR_SERVICE_CHANNEL_NOT_FOUND));
|
||||||
NS_LITERAL_STRING(ERR_SERVICE_CHANNEL_NOT_FOUND));
|
|
||||||
mRunnable = nullptr;
|
|
||||||
mSocket = nullptr;
|
|
||||||
Listen();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1596,7 +1571,6 @@ BluetoothHfpManager::OnGetServiceChannel(const nsAString& aDeviceAddress,
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_ASSERT(!aDeviceAddress.IsEmpty());
|
MOZ_ASSERT(!aDeviceAddress.IsEmpty());
|
||||||
MOZ_ASSERT(mRunnable);
|
|
||||||
|
|
||||||
BluetoothService* bs = BluetoothService::Get();
|
BluetoothService* bs = BluetoothService::Get();
|
||||||
NS_ENSURE_TRUE_VOID(bs);
|
NS_ENSURE_TRUE_VOID(bs);
|
||||||
|
@ -1608,22 +1582,14 @@ BluetoothHfpManager::OnGetServiceChannel(const nsAString& aDeviceAddress,
|
||||||
mNeedsUpdatingSdpRecords = false;
|
mNeedsUpdatingSdpRecords = false;
|
||||||
bs->UpdateSdpRecords(aDeviceAddress, this);
|
bs->UpdateSdpRecords(aDeviceAddress, this);
|
||||||
} else {
|
} else {
|
||||||
DispatchBluetoothReply(mRunnable, v,
|
OnConnect(NS_LITERAL_STRING(ERR_SERVICE_CHANNEL_NOT_FOUND));
|
||||||
NS_LITERAL_STRING(ERR_SERVICE_CHANNEL_NOT_FOUND));
|
|
||||||
mRunnable = nullptr;
|
|
||||||
mSocket = nullptr;
|
|
||||||
Listen();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mSocket->Connect(NS_ConvertUTF16toUTF8(aDeviceAddress), aChannel)) {
|
if (!mSocket->Connect(NS_ConvertUTF16toUTF8(aDeviceAddress), aChannel)) {
|
||||||
DispatchBluetoothReply(mRunnable, v,
|
OnConnect(NS_LITERAL_STRING("SocketConnectionError"));
|
||||||
NS_LITERAL_STRING("SocketConnectionError"));
|
|
||||||
mRunnable = nullptr;
|
|
||||||
mSocket = nullptr;
|
|
||||||
Listen();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1773,4 +1739,44 @@ BluetoothHfpManager::IsScoConnected()
|
||||||
return false;
|
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)
|
NS_IMPL_ISUPPORTS1(BluetoothHfpManager, nsIObserver)
|
||||||
|
|
|
@ -61,22 +61,26 @@ public:
|
||||||
static BluetoothHfpManager* Get();
|
static BluetoothHfpManager* Get();
|
||||||
~BluetoothHfpManager();
|
~BluetoothHfpManager();
|
||||||
|
|
||||||
|
// The following functions are inherited from BluetoothSocketObserver
|
||||||
virtual void ReceiveSocketData(
|
virtual void ReceiveSocketData(
|
||||||
BluetoothSocket* aSocket,
|
BluetoothSocket* aSocket,
|
||||||
nsAutoPtr<mozilla::ipc::UnixSocketRawData>& aMessage) MOZ_OVERRIDE;
|
nsAutoPtr<mozilla::ipc::UnixSocketRawData>& aMessage) MOZ_OVERRIDE;
|
||||||
virtual void OnConnectSuccess(BluetoothSocket* aSocket) MOZ_OVERRIDE;
|
virtual void OnSocketConnectSuccess(BluetoothSocket* aSocket) MOZ_OVERRIDE;
|
||||||
virtual void OnConnectError(BluetoothSocket* aSocket) MOZ_OVERRIDE;
|
virtual void OnSocketConnectError(BluetoothSocket* aSocket) MOZ_OVERRIDE;
|
||||||
virtual void OnDisconnect(BluetoothSocket* aSocket) MOZ_OVERRIDE;
|
virtual void OnSocketDisconnect(BluetoothSocket* aSocket) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
// The following functions are inherited from BluetoothProfileManagerBase
|
||||||
virtual void OnGetServiceChannel(const nsAString& aDeviceAddress,
|
virtual void OnGetServiceChannel(const nsAString& aDeviceAddress,
|
||||||
const nsAString& aServiceUuid,
|
const nsAString& aServiceUuid,
|
||||||
int aChannel) MOZ_OVERRIDE;
|
int aChannel) MOZ_OVERRIDE;
|
||||||
virtual void OnUpdateSdpRecords(const nsAString& aDeviceAddress) MOZ_OVERRIDE;
|
virtual void OnUpdateSdpRecords(const nsAString& aDeviceAddress) MOZ_OVERRIDE;
|
||||||
virtual void GetAddress(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 Listen();
|
||||||
bool ConnectSco(BluetoothReplyRunnable* aRunnable = nullptr);
|
bool ConnectSco(BluetoothReplyRunnable* aRunnable = nullptr);
|
||||||
bool DisconnectSco();
|
bool DisconnectSco();
|
||||||
|
@ -148,6 +152,7 @@ private:
|
||||||
nsTArray<Call> mCurrentCallArray;
|
nsTArray<Call> mCurrentCallArray;
|
||||||
nsAutoPtr<BluetoothTelephonyListener> mListener;
|
nsAutoPtr<BluetoothTelephonyListener> mListener;
|
||||||
nsRefPtr<BluetoothReplyRunnable> mRunnable;
|
nsRefPtr<BluetoothReplyRunnable> mRunnable;
|
||||||
|
BluetoothProfileController* mController;
|
||||||
nsRefPtr<BluetoothReplyRunnable> mScoRunnable;
|
nsRefPtr<BluetoothReplyRunnable> mScoRunnable;
|
||||||
|
|
||||||
// If a connection has been established, mSocket will be the socket
|
// If a connection has been established, mSocket will be the socket
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
|
|
||||||
BEGIN_BLUETOOTH_NAMESPACE
|
BEGIN_BLUETOOTH_NAMESPACE
|
||||||
|
class BluetoothProfileController;
|
||||||
|
|
||||||
class BluetoothProfileManagerBase : public nsIObserver
|
class BluetoothProfileManagerBase : public nsIObserver
|
||||||
{
|
{
|
||||||
|
@ -31,8 +32,35 @@ public:
|
||||||
const nsAString& aServiceUuid,
|
const nsAString& aServiceUuid,
|
||||||
int aChannel) = 0;
|
int aChannel) = 0;
|
||||||
virtual void OnUpdateSdpRecords(const nsAString& aDeviceAddress) = 0;
|
virtual void OnUpdateSdpRecords(const nsAString& aDeviceAddress) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the address of the connected device.
|
||||||
|
*/
|
||||||
virtual void GetAddress(nsAString& aDeviceAddress) = 0;
|
virtual void GetAddress(nsAString& aDeviceAddress) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the profile is connected.
|
||||||
|
*/
|
||||||
virtual bool IsConnected() = 0;
|
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
|
END_BLUETOOTH_NAMESPACE
|
||||||
|
|
Загрузка…
Ссылка в новой задаче