зеркало из https://github.com/mozilla/gecko-dev.git
Bug 851046: Patch 5 - Apply BluetoothSocket to BluetoothHfpManager; r=mrbkap
This commit is contained in:
Родитель
3185e0f46b
Коммит
aa28265e8c
|
@ -11,6 +11,7 @@
|
|||
#include "BluetoothReplyRunnable.h"
|
||||
#include "BluetoothScoManager.h"
|
||||
#include "BluetoothService.h"
|
||||
#include "BluetoothSocket.h"
|
||||
#include "BluetoothUtils.h"
|
||||
#include "BluetoothUuid.h"
|
||||
|
||||
|
@ -39,17 +40,19 @@
|
|||
#define TOA_UNKNOWN 0x81
|
||||
#define TOA_INTERNATIONAL 0x91
|
||||
|
||||
#define CR_LF "\xd\xa";
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::ipc;
|
||||
USING_BLUETOOTH_NAMESPACE
|
||||
|
||||
namespace {
|
||||
StaticRefPtr<BluetoothHfpManager> gBluetoothHfpManager;
|
||||
StaticAutoPtr<BluetoothHfpManager> gBluetoothHfpManager;
|
||||
StaticRefPtr<BluetoothHfpManagerObserver> sHfpObserver;
|
||||
bool gInShutdown = false;
|
||||
static bool sStopSendingRingFlag = true;
|
||||
|
||||
static int sRingInterval = 3000; //unit: ms
|
||||
static const char kHfpCrlf[] = "\xd\xa";
|
||||
} // anonymous namespace
|
||||
|
||||
/* CallState for sCINDItems[CINDType::CALL].value
|
||||
|
@ -260,7 +263,7 @@ BluetoothHfpManagerObserver::Observe(nsISupports* aSubject,
|
|||
|
||||
NS_IMPL_ISUPPORTS1(BluetoothHfpManagerObserver, nsIObserver)
|
||||
|
||||
class SendRingIndicatorTask : public Task
|
||||
class BluetoothHfpManager::SendRingIndicatorTask : public Task
|
||||
{
|
||||
public:
|
||||
SendRingIndicatorTask(const nsAString& aNumber, int aType)
|
||||
|
@ -284,20 +287,19 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
const char* kHfpCrlf = "\xd\xa";
|
||||
nsAutoCString ringMsg(kHfpCrlf);
|
||||
ringMsg += "RING";
|
||||
ringMsg += kHfpCrlf;
|
||||
gBluetoothHfpManager->SendSocketData(ringMsg);
|
||||
ringMsg.AppendLiteral("RING");
|
||||
ringMsg.AppendLiteral(kHfpCrlf);
|
||||
gBluetoothHfpManager->SendLine(ringMsg.get());
|
||||
|
||||
if (!mNumber.IsEmpty()) {
|
||||
nsAutoCString clipMsg(kHfpCrlf);
|
||||
clipMsg += "+CLIP: \"";
|
||||
clipMsg += NS_ConvertUTF16toUTF8(mNumber).get();
|
||||
clipMsg += "\",";
|
||||
clipMsg.AppendLiteral("+CLIP: \"");
|
||||
clipMsg.Append(NS_ConvertUTF16toUTF8(mNumber).get());
|
||||
clipMsg.AppendLiteral("\",");
|
||||
clipMsg.AppendInt(mType);
|
||||
clipMsg += kHfpCrlf;
|
||||
gBluetoothHfpManager->SendSocketData(clipMsg);
|
||||
clipMsg.AppendLiteral(kHfpCrlf);
|
||||
gBluetoothHfpManager->SendLine(clipMsg.get());
|
||||
}
|
||||
|
||||
MessageLoop::current()->
|
||||
|
@ -391,7 +393,11 @@ BluetoothHfpManager::Init()
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mSocketStatus = GetConnectionStatus();
|
||||
mSocket = new BluetoothSocket(this,
|
||||
BluetoothSocketType::RFCOMM,
|
||||
true,
|
||||
true);
|
||||
mSocketStatus = mSocket->GetConnectionStatus();
|
||||
|
||||
sHfpObserver = new BluetoothHfpManagerObserver();
|
||||
if (!sHfpObserver->Init()) {
|
||||
|
@ -454,12 +460,9 @@ BluetoothHfpManager::Get()
|
|||
}
|
||||
|
||||
// Create new instance, register, return
|
||||
nsRefPtr<BluetoothHfpManager> manager = new BluetoothHfpManager();
|
||||
BluetoothHfpManager* manager = new BluetoothHfpManager();
|
||||
NS_ENSURE_TRUE(manager, nullptr);
|
||||
|
||||
if (!manager->Init()) {
|
||||
return nullptr;
|
||||
}
|
||||
NS_ENSURE_TRUE(manager->Init(), nullptr);
|
||||
|
||||
gBluetoothHfpManager = manager;
|
||||
return gBluetoothHfpManager;
|
||||
|
@ -474,8 +477,8 @@ BluetoothHfpManager::NotifySettings()
|
|||
type.AssignLiteral("bluetooth-hfp-status-changed");
|
||||
|
||||
name.AssignLiteral("connected");
|
||||
v = (GetConnectionStatus() == SocketConnectionStatus::SOCKET_CONNECTED)
|
||||
? true : false ;
|
||||
v = (mSocket->GetConnectionStatus() ==
|
||||
SocketConnectionStatus::SOCKET_CONNECTED);
|
||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||
|
||||
name.AssignLiteral("address");
|
||||
|
@ -571,7 +574,7 @@ BluetoothHfpManager::HandleVolumeChanged(const nsAString& aData)
|
|||
}
|
||||
|
||||
// Only send volume back when there's a connected headset
|
||||
if (GetConnectionStatus() == SocketConnectionStatus::SOCKET_CONNECTED) {
|
||||
if (mSocket->GetConnectionStatus() == SocketConnectionStatus::SOCKET_CONNECTED) {
|
||||
SendCommand("+VGS: ", mCurrentVgs);
|
||||
}
|
||||
|
||||
|
@ -663,7 +666,7 @@ BluetoothHfpManager::HandleShutdown()
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
gInShutdown = true;
|
||||
CloseSocket();
|
||||
Disconnect();
|
||||
gBluetoothHfpManager = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -742,9 +745,9 @@ BluetoothHfpManager::ReceiveSocketData(nsAutoPtr<UnixSocketRawData>& aMessage)
|
|||
} else if (msg.Find("AT+COPS?") != -1) {
|
||||
nsAutoCString message("+COPS: ");
|
||||
message.AppendInt(mNetworkSelectionMode);
|
||||
message += ",0,\"";
|
||||
message += NS_ConvertUTF16toUTF8(mOperatorName);
|
||||
message += "\"";
|
||||
message.AppendLiteral(",0,\"");
|
||||
message.Append(NS_ConvertUTF16toUTF8(mOperatorName));
|
||||
message.AppendLiteral("\"");
|
||||
SendLine(message.get());
|
||||
return;
|
||||
} else if (msg.Find("AT+VTS=") != -1) {
|
||||
|
@ -908,10 +911,10 @@ BluetoothHfpManager::ReceiveSocketData(nsAutoPtr<UnixSocketRawData>& aMessage)
|
|||
} else if (msg.Find("AT+CNUM") != -1) {
|
||||
if (!mMsisdn.IsEmpty()) {
|
||||
nsAutoCString message("+CNUM: ,\"");
|
||||
message += NS_ConvertUTF16toUTF8(mMsisdn).get();
|
||||
message += "\",";
|
||||
message.Append(NS_ConvertUTF16toUTF8(mMsisdn).get());
|
||||
message.AppendLiteral("\",");
|
||||
message.AppendInt(TOA_UNKNOWN);
|
||||
message += ",,4";
|
||||
message.AppendLiteral(",,4");
|
||||
SendLine(message.get());
|
||||
}
|
||||
} else {
|
||||
|
@ -942,13 +945,15 @@ BluetoothHfpManager::Connect(const nsAString& aDevicePath,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (GetConnectionStatus() == SocketConnectionStatus::SOCKET_CONNECTED ||
|
||||
GetConnectionStatus() == SocketConnectionStatus::SOCKET_CONNECTING) {
|
||||
NS_WARNING("BluetoothHfpManager has connected/is connecting to a headset!");
|
||||
SocketConnectionStatus s = mSocket->GetConnectionStatus();
|
||||
|
||||
if (s == SocketConnectionStatus::SOCKET_CONNECTED ||
|
||||
s == SocketConnectionStatus::SOCKET_CONNECTING) {
|
||||
NS_WARNING("BluetoothHfpManager has been already connected");
|
||||
return false;
|
||||
}
|
||||
|
||||
CloseSocket();
|
||||
mSocket->Disconnect();
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
NS_ENSURE_TRUE(bs, false);
|
||||
|
@ -967,7 +972,7 @@ BluetoothHfpManager::Connect(const nsAString& aDevicePath,
|
|||
BluetoothSocketType::RFCOMM,
|
||||
true,
|
||||
true,
|
||||
this,
|
||||
mSocket,
|
||||
mRunnable);
|
||||
|
||||
return NS_FAILED(rv) ? false : true;
|
||||
|
@ -983,50 +988,39 @@ BluetoothHfpManager::Listen()
|
|||
return false;
|
||||
}
|
||||
|
||||
if (GetConnectionStatus() == SocketConnectionStatus::SOCKET_LISTENING) {
|
||||
if (mSocket->GetConnectionStatus() ==
|
||||
SocketConnectionStatus::SOCKET_LISTENING) {
|
||||
NS_WARNING("BluetoothHfpManager has been already listening");
|
||||
return true;
|
||||
}
|
||||
|
||||
CloseSocket();
|
||||
mSocket->Disconnect();
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
NS_ENSURE_TRUE(bs, false);
|
||||
if (!mSocket->Listen(BluetoothReservedChannels::CHANNEL_HANDSFREE_AG)) {
|
||||
NS_WARNING("[HFP] Can't listen on socket!");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult rv =
|
||||
bs->ListenSocketViaService(BluetoothReservedChannels::CHANNEL_HANDSFREE_AG,
|
||||
BluetoothSocketType::RFCOMM,
|
||||
true,
|
||||
true,
|
||||
this);
|
||||
|
||||
mSocketStatus = GetConnectionStatus();
|
||||
|
||||
return NS_FAILED(rv) ? false : true;
|
||||
mSocketStatus = mSocket->GetConnectionStatus();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::Disconnect()
|
||||
{
|
||||
if (GetConnectionStatus() == SocketConnectionStatus::SOCKET_DISCONNECTED) {
|
||||
NS_WARNING("BluetoothHfpManager has been disconnected!");
|
||||
return;
|
||||
}
|
||||
|
||||
CloseSocket();
|
||||
mSocket->Disconnect();
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothHfpManager::SendLine(const char* aMessage)
|
||||
{
|
||||
const char* kHfpCrlf = "\xd\xa";
|
||||
nsAutoCString msg;
|
||||
|
||||
msg += kHfpCrlf;
|
||||
msg += aMessage;
|
||||
msg += kHfpCrlf;
|
||||
msg.AppendLiteral(kHfpCrlf);
|
||||
msg.Append(aMessage);
|
||||
msg.AppendLiteral(kHfpCrlf);
|
||||
|
||||
return SendSocketData(msg);
|
||||
return mSocket->SendSocketData(msg);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1052,22 +1046,22 @@ BluetoothHfpManager::SendCommand(const char* aCommand, uint8_t aValue)
|
|||
}
|
||||
|
||||
message.AppendInt(aValue);
|
||||
message += ",";
|
||||
message.AppendLiteral(",");
|
||||
message.AppendInt(sCINDItems[aValue].value);
|
||||
} else if (!strcmp(aCommand, "+CIND: ")) {
|
||||
if (!aValue) {
|
||||
// Query for range
|
||||
for (uint8_t i = 1; i < ArrayLength(sCINDItems); i++) {
|
||||
message += "(\"";
|
||||
message += sCINDItems[i].name;
|
||||
message += "\",(";
|
||||
message += sCINDItems[i].range;
|
||||
message += ")";
|
||||
message.AppendLiteral("(\"");
|
||||
message.Append(sCINDItems[i].name);
|
||||
message.AppendLiteral("\",(");
|
||||
message.Append(sCINDItems[i].range);
|
||||
message.AppendLiteral(")");
|
||||
if (i == (ArrayLength(sCINDItems) - 1)) {
|
||||
message +=")";
|
||||
message.AppendLiteral(")");
|
||||
break;
|
||||
}
|
||||
message += "),";
|
||||
message.AppendLiteral("),");
|
||||
}
|
||||
} else {
|
||||
// Query for value
|
||||
|
@ -1076,7 +1070,7 @@ BluetoothHfpManager::SendCommand(const char* aCommand, uint8_t aValue)
|
|||
if (i == (ArrayLength(sCINDItems) - 1)) {
|
||||
break;
|
||||
}
|
||||
message += ",";
|
||||
message.AppendLiteral(",");
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(aCommand, "+CLCC: ")) {
|
||||
|
@ -1090,9 +1084,9 @@ BluetoothHfpManager::SendCommand(const char* aCommand, uint8_t aValue)
|
|||
|
||||
message.AssignLiteral("+CLCC: ");
|
||||
message.AppendInt(i);
|
||||
message += ",";
|
||||
message.AppendLiteral(",");
|
||||
message.AppendInt(call.mDirection);
|
||||
message += ",";
|
||||
message.AppendLiteral(",");
|
||||
|
||||
switch (call.mState) {
|
||||
case nsITelephonyProvider::CALL_STATE_CONNECTED:
|
||||
|
@ -1114,9 +1108,9 @@ BluetoothHfpManager::SendCommand(const char* aCommand, uint8_t aValue)
|
|||
NS_WARNING("Not handling call status for CLCC");
|
||||
break;
|
||||
}
|
||||
message += ",0,0,\"";
|
||||
message += NS_ConvertUTF16toUTF8(call.mNumber).get();
|
||||
message += "\",";
|
||||
message.AppendLiteral(",0,0,\"");
|
||||
message.Append(NS_ConvertUTF16toUTF8(call.mNumber));
|
||||
message.AppendLiteral("\",");
|
||||
message.AppendInt(call.mType);
|
||||
|
||||
rv &= SendLine(message.get());
|
||||
|
@ -1147,7 +1141,8 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
|
|||
const nsAString& aNumber,
|
||||
bool aSend)
|
||||
{
|
||||
if (GetConnectionStatus() != SocketConnectionStatus::SOCKET_CONNECTED) {
|
||||
if (mSocket->GetConnectionStatus() !=
|
||||
SocketConnectionStatus::SOCKET_CONNECTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1181,8 +1176,8 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
|
|||
if (mCurrentCallIndex) {
|
||||
if (mCCWA) {
|
||||
nsAutoCString ccwaMsg("+CCWA: \"");
|
||||
ccwaMsg += NS_ConvertUTF16toUTF8(aNumber).get();
|
||||
ccwaMsg += "\",";
|
||||
ccwaMsg.Append(NS_ConvertUTF16toUTF8(aNumber));
|
||||
ccwaMsg.AppendLiteral("\",");
|
||||
ccwaMsg.AppendInt(mCurrentCallArray[aCallIndex].mType);
|
||||
SendLine(ccwaMsg.get());
|
||||
}
|
||||
|
@ -1206,7 +1201,7 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
|
|||
mCurrentCallArray[aCallIndex].mDirection = false;
|
||||
UpdateCIND(CINDType::CALLSETUP, CallSetupState::OUTGOING, aSend);
|
||||
|
||||
GetSocketAddr(address);
|
||||
mSocket->GetAddress(address);
|
||||
OpenScoSocket(address);
|
||||
break;
|
||||
case nsITelephonyProvider::CALL_STATE_ALERTING:
|
||||
|
@ -1215,7 +1210,7 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
|
|||
|
||||
// If there's an ongoing call when the headset is just connected, we have
|
||||
// to open a sco socket here.
|
||||
GetSocketAddr(address);
|
||||
mSocket->GetAddress(address);
|
||||
OpenScoSocket(address);
|
||||
break;
|
||||
case nsITelephonyProvider::CALL_STATE_CONNECTED:
|
||||
|
@ -1226,7 +1221,7 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
|
|||
// Incoming call, no break
|
||||
sStopSendingRingFlag = true;
|
||||
|
||||
GetSocketAddr(address);
|
||||
mSocket->GetAddress(address);
|
||||
OpenScoSocket(address);
|
||||
case nsITelephonyProvider::CALL_STATE_ALERTING:
|
||||
// Outgoing call
|
||||
|
@ -1328,8 +1323,8 @@ BluetoothHfpManager::OnConnectSuccess()
|
|||
|
||||
// Cache device path for NotifySettings() since we can't get socket address
|
||||
// when a headset disconnect with us
|
||||
GetSocketAddr(mDevicePath);
|
||||
mSocketStatus = GetConnectionStatus();
|
||||
mSocket->GetAddress(mDevicePath);
|
||||
mSocketStatus = mSocket->GetConnectionStatus();
|
||||
|
||||
NotifySettings();
|
||||
}
|
||||
|
@ -1348,8 +1343,6 @@ BluetoothHfpManager::OnConnectError()
|
|||
}
|
||||
|
||||
// If connecting for some reason didn't work, restart listening
|
||||
CloseSocket();
|
||||
mSocketStatus = GetConnectionStatus();
|
||||
Listen();
|
||||
}
|
||||
|
||||
|
@ -1368,3 +1361,10 @@ BluetoothHfpManager::OnDisconnect()
|
|||
CloseScoSocket();
|
||||
Reset();
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothHfpManager::IsConnected()
|
||||
{
|
||||
return mSocket->GetConnectionStatus() ==
|
||||
SocketConnectionStatus::SOCKET_CONNECTED;
|
||||
}
|
||||
|
|
|
@ -8,14 +8,16 @@
|
|||
#define mozilla_dom_bluetooth_bluetoothhfpmanager_h__
|
||||
|
||||
#include "BluetoothCommon.h"
|
||||
#include "BluetoothSocketObserver.h"
|
||||
#include "BluetoothTelephonyListener.h"
|
||||
#include "mozilla/ipc/UnixSocket.h"
|
||||
#include "nsIObserver.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothReplyRunnable;
|
||||
class BluetoothHfpManagerObserver;
|
||||
class BluetoothReplyRunnable;
|
||||
class BluetoothSocket;
|
||||
class Call;
|
||||
|
||||
/**
|
||||
|
@ -48,12 +50,17 @@ enum BluetoothCmeError {
|
|||
NETWORK_NOT_ALLOWED = 32
|
||||
};
|
||||
|
||||
class BluetoothHfpManager : public mozilla::ipc::UnixSocketConsumer
|
||||
class BluetoothHfpManager : public BluetoothSocketObserver
|
||||
{
|
||||
public:
|
||||
static BluetoothHfpManager* Get();
|
||||
virtual void ReceiveSocketData(nsAutoPtr<mozilla::ipc::UnixSocketRawData>& aMessage)
|
||||
MOZ_OVERRIDE;
|
||||
~BluetoothHfpManager();
|
||||
|
||||
virtual void ReceiveSocketData(
|
||||
nsAutoPtr<mozilla::ipc::UnixSocketRawData>& aMessage) MOZ_OVERRIDE;
|
||||
virtual void OnConnectSuccess() MOZ_OVERRIDE;
|
||||
virtual void OnConnectError() MOZ_OVERRIDE;
|
||||
virtual void OnDisconnect() MOZ_OVERRIDE;
|
||||
|
||||
bool Connect(const nsAString& aDeviceObjectPath,
|
||||
const bool aIsHandsfree,
|
||||
|
@ -66,14 +73,17 @@ public:
|
|||
*/
|
||||
void HandleCallStateChanged(uint32_t aCallIndex, uint16_t aCallState,
|
||||
const nsAString& aNumber, bool aSend);
|
||||
bool IsConnected();
|
||||
|
||||
private:
|
||||
class GetVolumeTask;
|
||||
class SendRingIndicatorTask;
|
||||
|
||||
friend class GetVolumeTask;
|
||||
friend class SendRingIndicatorTask;
|
||||
friend class BluetoothHfpManagerObserver;
|
||||
|
||||
BluetoothHfpManager();
|
||||
~BluetoothHfpManager();
|
||||
nsresult HandleIccInfoChanged();
|
||||
nsresult HandleShutdown();
|
||||
nsresult HandleVolumeChanged(const nsAString& aData);
|
||||
|
@ -91,10 +101,6 @@ private:
|
|||
bool SendLine(const char* aMessage);
|
||||
void UpdateCIND(uint8_t aType, uint8_t aValue, bool aSend);
|
||||
|
||||
virtual void OnConnectSuccess() MOZ_OVERRIDE;
|
||||
virtual void OnConnectError() MOZ_OVERRIDE;
|
||||
virtual void OnDisconnect() MOZ_OVERRIDE;
|
||||
|
||||
int mCurrentVgs;
|
||||
int mCurrentVgm;
|
||||
uint32_t mCurrentCallIndex;
|
||||
|
@ -107,11 +113,12 @@ private:
|
|||
nsString mDevicePath;
|
||||
nsString mMsisdn;
|
||||
nsString mOperatorName;
|
||||
enum mozilla::ipc::SocketConnectionStatus mSocketStatus;
|
||||
enum SocketConnectionStatus mSocketStatus;
|
||||
|
||||
nsTArray<Call> mCurrentCallArray;
|
||||
nsAutoPtr<BluetoothTelephonyListener> mListener;
|
||||
nsRefPtr<BluetoothReplyRunnable> mRunnable;
|
||||
nsRefPtr<BluetoothSocket> mSocket;
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
|
|
@ -2547,8 +2547,7 @@ BluetoothDBusService::IsConnected(const uint16_t aProfileId)
|
|||
if (aProfileId == BluetoothServiceClass::HANDSFREE ||
|
||||
aProfileId == BluetoothServiceClass::HEADSET) {
|
||||
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
|
||||
return (hfp->GetConnectionStatus() ==
|
||||
SocketConnectionStatus::SOCKET_CONNECTED);
|
||||
return (hfp->IsConnected());
|
||||
} else if (aProfileId == BluetoothServiceClass::OBJECT_PUSH) {
|
||||
BluetoothOppManager* opp = BluetoothOppManager::Get();
|
||||
return opp->IsTransferring();
|
||||
|
|
Загрузка…
Ссылка в новой задаче