Bug 851046: Patch 5 - Apply BluetoothSocket to BluetoothHfpManager; r=mrbkap

This commit is contained in:
Eric Chou 2013-04-04 17:54:22 -07:00
Родитель 3185e0f46b
Коммит aa28265e8c
3 изменённых файлов: 100 добавлений и 94 удалений

Просмотреть файл

@ -11,6 +11,7 @@
#include "BluetoothReplyRunnable.h" #include "BluetoothReplyRunnable.h"
#include "BluetoothScoManager.h" #include "BluetoothScoManager.h"
#include "BluetoothService.h" #include "BluetoothService.h"
#include "BluetoothSocket.h"
#include "BluetoothUtils.h" #include "BluetoothUtils.h"
#include "BluetoothUuid.h" #include "BluetoothUuid.h"
@ -39,17 +40,19 @@
#define TOA_UNKNOWN 0x81 #define TOA_UNKNOWN 0x81
#define TOA_INTERNATIONAL 0x91 #define TOA_INTERNATIONAL 0x91
#define CR_LF "\xd\xa";
using namespace mozilla; using namespace mozilla;
using namespace mozilla::ipc; using namespace mozilla::ipc;
USING_BLUETOOTH_NAMESPACE USING_BLUETOOTH_NAMESPACE
namespace { namespace {
StaticRefPtr<BluetoothHfpManager> gBluetoothHfpManager; StaticAutoPtr<BluetoothHfpManager> gBluetoothHfpManager;
StaticRefPtr<BluetoothHfpManagerObserver> sHfpObserver; StaticRefPtr<BluetoothHfpManagerObserver> sHfpObserver;
bool gInShutdown = false; bool gInShutdown = false;
static bool sStopSendingRingFlag = true; static bool sStopSendingRingFlag = true;
static int sRingInterval = 3000; //unit: ms static int sRingInterval = 3000; //unit: ms
static const char kHfpCrlf[] = "\xd\xa";
} // anonymous namespace } // anonymous namespace
/* CallState for sCINDItems[CINDType::CALL].value /* CallState for sCINDItems[CINDType::CALL].value
@ -260,7 +263,7 @@ BluetoothHfpManagerObserver::Observe(nsISupports* aSubject,
NS_IMPL_ISUPPORTS1(BluetoothHfpManagerObserver, nsIObserver) NS_IMPL_ISUPPORTS1(BluetoothHfpManagerObserver, nsIObserver)
class SendRingIndicatorTask : public Task class BluetoothHfpManager::SendRingIndicatorTask : public Task
{ {
public: public:
SendRingIndicatorTask(const nsAString& aNumber, int aType) SendRingIndicatorTask(const nsAString& aNumber, int aType)
@ -284,20 +287,19 @@ public:
return; return;
} }
const char* kHfpCrlf = "\xd\xa";
nsAutoCString ringMsg(kHfpCrlf); nsAutoCString ringMsg(kHfpCrlf);
ringMsg += "RING"; ringMsg.AppendLiteral("RING");
ringMsg += kHfpCrlf; ringMsg.AppendLiteral(kHfpCrlf);
gBluetoothHfpManager->SendSocketData(ringMsg); gBluetoothHfpManager->SendLine(ringMsg.get());
if (!mNumber.IsEmpty()) { if (!mNumber.IsEmpty()) {
nsAutoCString clipMsg(kHfpCrlf); nsAutoCString clipMsg(kHfpCrlf);
clipMsg += "+CLIP: \""; clipMsg.AppendLiteral("+CLIP: \"");
clipMsg += NS_ConvertUTF16toUTF8(mNumber).get(); clipMsg.Append(NS_ConvertUTF16toUTF8(mNumber).get());
clipMsg += "\","; clipMsg.AppendLiteral("\",");
clipMsg.AppendInt(mType); clipMsg.AppendInt(mType);
clipMsg += kHfpCrlf; clipMsg.AppendLiteral(kHfpCrlf);
gBluetoothHfpManager->SendSocketData(clipMsg); gBluetoothHfpManager->SendLine(clipMsg.get());
} }
MessageLoop::current()-> MessageLoop::current()->
@ -391,7 +393,11 @@ BluetoothHfpManager::Init()
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
mSocketStatus = GetConnectionStatus(); mSocket = new BluetoothSocket(this,
BluetoothSocketType::RFCOMM,
true,
true);
mSocketStatus = mSocket->GetConnectionStatus();
sHfpObserver = new BluetoothHfpManagerObserver(); sHfpObserver = new BluetoothHfpManagerObserver();
if (!sHfpObserver->Init()) { if (!sHfpObserver->Init()) {
@ -454,12 +460,9 @@ BluetoothHfpManager::Get()
} }
// Create new instance, register, return // Create new instance, register, return
nsRefPtr<BluetoothHfpManager> manager = new BluetoothHfpManager(); BluetoothHfpManager* manager = new BluetoothHfpManager();
NS_ENSURE_TRUE(manager, nullptr); NS_ENSURE_TRUE(manager, nullptr);
NS_ENSURE_TRUE(manager->Init(), nullptr);
if (!manager->Init()) {
return nullptr;
}
gBluetoothHfpManager = manager; gBluetoothHfpManager = manager;
return gBluetoothHfpManager; return gBluetoothHfpManager;
@ -474,8 +477,8 @@ BluetoothHfpManager::NotifySettings()
type.AssignLiteral("bluetooth-hfp-status-changed"); type.AssignLiteral("bluetooth-hfp-status-changed");
name.AssignLiteral("connected"); name.AssignLiteral("connected");
v = (GetConnectionStatus() == SocketConnectionStatus::SOCKET_CONNECTED) v = (mSocket->GetConnectionStatus() ==
? true : false ; SocketConnectionStatus::SOCKET_CONNECTED);
parameters.AppendElement(BluetoothNamedValue(name, v)); parameters.AppendElement(BluetoothNamedValue(name, v));
name.AssignLiteral("address"); name.AssignLiteral("address");
@ -571,7 +574,7 @@ BluetoothHfpManager::HandleVolumeChanged(const nsAString& aData)
} }
// Only send volume back when there's a connected headset // Only send volume back when there's a connected headset
if (GetConnectionStatus() == SocketConnectionStatus::SOCKET_CONNECTED) { if (mSocket->GetConnectionStatus() == SocketConnectionStatus::SOCKET_CONNECTED) {
SendCommand("+VGS: ", mCurrentVgs); SendCommand("+VGS: ", mCurrentVgs);
} }
@ -663,7 +666,7 @@ BluetoothHfpManager::HandleShutdown()
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
gInShutdown = true; gInShutdown = true;
CloseSocket(); Disconnect();
gBluetoothHfpManager = nullptr; gBluetoothHfpManager = nullptr;
return NS_OK; return NS_OK;
} }
@ -742,9 +745,9 @@ BluetoothHfpManager::ReceiveSocketData(nsAutoPtr<UnixSocketRawData>& aMessage)
} else if (msg.Find("AT+COPS?") != -1) { } else if (msg.Find("AT+COPS?") != -1) {
nsAutoCString message("+COPS: "); nsAutoCString message("+COPS: ");
message.AppendInt(mNetworkSelectionMode); message.AppendInt(mNetworkSelectionMode);
message += ",0,\""; message.AppendLiteral(",0,\"");
message += NS_ConvertUTF16toUTF8(mOperatorName); message.Append(NS_ConvertUTF16toUTF8(mOperatorName));
message += "\""; message.AppendLiteral("\"");
SendLine(message.get()); SendLine(message.get());
return; return;
} else if (msg.Find("AT+VTS=") != -1) { } else if (msg.Find("AT+VTS=") != -1) {
@ -908,10 +911,10 @@ BluetoothHfpManager::ReceiveSocketData(nsAutoPtr<UnixSocketRawData>& aMessage)
} else if (msg.Find("AT+CNUM") != -1) { } else if (msg.Find("AT+CNUM") != -1) {
if (!mMsisdn.IsEmpty()) { if (!mMsisdn.IsEmpty()) {
nsAutoCString message("+CNUM: ,\""); nsAutoCString message("+CNUM: ,\"");
message += NS_ConvertUTF16toUTF8(mMsisdn).get(); message.Append(NS_ConvertUTF16toUTF8(mMsisdn).get());
message += "\","; message.AppendLiteral("\",");
message.AppendInt(TOA_UNKNOWN); message.AppendInt(TOA_UNKNOWN);
message += ",,4"; message.AppendLiteral(",,4");
SendLine(message.get()); SendLine(message.get());
} }
} else { } else {
@ -942,13 +945,15 @@ BluetoothHfpManager::Connect(const nsAString& aDevicePath,
return false; return false;
} }
if (GetConnectionStatus() == SocketConnectionStatus::SOCKET_CONNECTED || SocketConnectionStatus s = mSocket->GetConnectionStatus();
GetConnectionStatus() == SocketConnectionStatus::SOCKET_CONNECTING) {
NS_WARNING("BluetoothHfpManager has connected/is connecting to a headset!"); if (s == SocketConnectionStatus::SOCKET_CONNECTED ||
s == SocketConnectionStatus::SOCKET_CONNECTING) {
NS_WARNING("BluetoothHfpManager has been already connected");
return false; return false;
} }
CloseSocket(); mSocket->Disconnect();
BluetoothService* bs = BluetoothService::Get(); BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE(bs, false); NS_ENSURE_TRUE(bs, false);
@ -967,7 +972,7 @@ BluetoothHfpManager::Connect(const nsAString& aDevicePath,
BluetoothSocketType::RFCOMM, BluetoothSocketType::RFCOMM,
true, true,
true, true,
this, mSocket,
mRunnable); mRunnable);
return NS_FAILED(rv) ? false : true; return NS_FAILED(rv) ? false : true;
@ -983,50 +988,39 @@ BluetoothHfpManager::Listen()
return false; return false;
} }
if (GetConnectionStatus() == SocketConnectionStatus::SOCKET_LISTENING) { if (mSocket->GetConnectionStatus() ==
SocketConnectionStatus::SOCKET_LISTENING) {
NS_WARNING("BluetoothHfpManager has been already listening"); NS_WARNING("BluetoothHfpManager has been already listening");
return true; return true;
} }
CloseSocket(); mSocket->Disconnect();
BluetoothService* bs = BluetoothService::Get(); if (!mSocket->Listen(BluetoothReservedChannels::CHANNEL_HANDSFREE_AG)) {
NS_ENSURE_TRUE(bs, false); NS_WARNING("[HFP] Can't listen on socket!");
return false;
}
nsresult rv = mSocketStatus = mSocket->GetConnectionStatus();
bs->ListenSocketViaService(BluetoothReservedChannels::CHANNEL_HANDSFREE_AG, return true;
BluetoothSocketType::RFCOMM,
true,
true,
this);
mSocketStatus = GetConnectionStatus();
return NS_FAILED(rv) ? false : true;
} }
void void
BluetoothHfpManager::Disconnect() BluetoothHfpManager::Disconnect()
{ {
if (GetConnectionStatus() == SocketConnectionStatus::SOCKET_DISCONNECTED) { mSocket->Disconnect();
NS_WARNING("BluetoothHfpManager has been disconnected!");
return;
}
CloseSocket();
} }
bool bool
BluetoothHfpManager::SendLine(const char* aMessage) BluetoothHfpManager::SendLine(const char* aMessage)
{ {
const char* kHfpCrlf = "\xd\xa";
nsAutoCString msg; nsAutoCString msg;
msg += kHfpCrlf; msg.AppendLiteral(kHfpCrlf);
msg += aMessage; msg.Append(aMessage);
msg += kHfpCrlf; msg.AppendLiteral(kHfpCrlf);
return SendSocketData(msg); return mSocket->SendSocketData(msg);
} }
bool bool
@ -1052,22 +1046,22 @@ BluetoothHfpManager::SendCommand(const char* aCommand, uint8_t aValue)
} }
message.AppendInt(aValue); message.AppendInt(aValue);
message += ","; message.AppendLiteral(",");
message.AppendInt(sCINDItems[aValue].value); message.AppendInt(sCINDItems[aValue].value);
} else if (!strcmp(aCommand, "+CIND: ")) { } else if (!strcmp(aCommand, "+CIND: ")) {
if (!aValue) { if (!aValue) {
// Query for range // Query for range
for (uint8_t i = 1; i < ArrayLength(sCINDItems); i++) { for (uint8_t i = 1; i < ArrayLength(sCINDItems); i++) {
message += "(\""; message.AppendLiteral("(\"");
message += sCINDItems[i].name; message.Append(sCINDItems[i].name);
message += "\",("; message.AppendLiteral("\",(");
message += sCINDItems[i].range; message.Append(sCINDItems[i].range);
message += ")"; message.AppendLiteral(")");
if (i == (ArrayLength(sCINDItems) - 1)) { if (i == (ArrayLength(sCINDItems) - 1)) {
message +=")"; message.AppendLiteral(")");
break; break;
} }
message += "),"; message.AppendLiteral("),");
} }
} else { } else {
// Query for value // Query for value
@ -1076,7 +1070,7 @@ BluetoothHfpManager::SendCommand(const char* aCommand, uint8_t aValue)
if (i == (ArrayLength(sCINDItems) - 1)) { if (i == (ArrayLength(sCINDItems) - 1)) {
break; break;
} }
message += ","; message.AppendLiteral(",");
} }
} }
} else if (!strcmp(aCommand, "+CLCC: ")) { } else if (!strcmp(aCommand, "+CLCC: ")) {
@ -1090,9 +1084,9 @@ BluetoothHfpManager::SendCommand(const char* aCommand, uint8_t aValue)
message.AssignLiteral("+CLCC: "); message.AssignLiteral("+CLCC: ");
message.AppendInt(i); message.AppendInt(i);
message += ","; message.AppendLiteral(",");
message.AppendInt(call.mDirection); message.AppendInt(call.mDirection);
message += ","; message.AppendLiteral(",");
switch (call.mState) { switch (call.mState) {
case nsITelephonyProvider::CALL_STATE_CONNECTED: 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"); NS_WARNING("Not handling call status for CLCC");
break; break;
} }
message += ",0,0,\""; message.AppendLiteral(",0,0,\"");
message += NS_ConvertUTF16toUTF8(call.mNumber).get(); message.Append(NS_ConvertUTF16toUTF8(call.mNumber));
message += "\","; message.AppendLiteral("\",");
message.AppendInt(call.mType); message.AppendInt(call.mType);
rv &= SendLine(message.get()); rv &= SendLine(message.get());
@ -1147,7 +1141,8 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
const nsAString& aNumber, const nsAString& aNumber,
bool aSend) bool aSend)
{ {
if (GetConnectionStatus() != SocketConnectionStatus::SOCKET_CONNECTED) { if (mSocket->GetConnectionStatus() !=
SocketConnectionStatus::SOCKET_CONNECTED) {
return; return;
} }
@ -1181,8 +1176,8 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
if (mCurrentCallIndex) { if (mCurrentCallIndex) {
if (mCCWA) { if (mCCWA) {
nsAutoCString ccwaMsg("+CCWA: \""); nsAutoCString ccwaMsg("+CCWA: \"");
ccwaMsg += NS_ConvertUTF16toUTF8(aNumber).get(); ccwaMsg.Append(NS_ConvertUTF16toUTF8(aNumber));
ccwaMsg += "\","; ccwaMsg.AppendLiteral("\",");
ccwaMsg.AppendInt(mCurrentCallArray[aCallIndex].mType); ccwaMsg.AppendInt(mCurrentCallArray[aCallIndex].mType);
SendLine(ccwaMsg.get()); SendLine(ccwaMsg.get());
} }
@ -1206,7 +1201,7 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
mCurrentCallArray[aCallIndex].mDirection = false; mCurrentCallArray[aCallIndex].mDirection = false;
UpdateCIND(CINDType::CALLSETUP, CallSetupState::OUTGOING, aSend); UpdateCIND(CINDType::CALLSETUP, CallSetupState::OUTGOING, aSend);
GetSocketAddr(address); mSocket->GetAddress(address);
OpenScoSocket(address); OpenScoSocket(address);
break; break;
case nsITelephonyProvider::CALL_STATE_ALERTING: 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 // If there's an ongoing call when the headset is just connected, we have
// to open a sco socket here. // to open a sco socket here.
GetSocketAddr(address); mSocket->GetAddress(address);
OpenScoSocket(address); OpenScoSocket(address);
break; break;
case nsITelephonyProvider::CALL_STATE_CONNECTED: case nsITelephonyProvider::CALL_STATE_CONNECTED:
@ -1226,7 +1221,7 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
// Incoming call, no break // Incoming call, no break
sStopSendingRingFlag = true; sStopSendingRingFlag = true;
GetSocketAddr(address); mSocket->GetAddress(address);
OpenScoSocket(address); OpenScoSocket(address);
case nsITelephonyProvider::CALL_STATE_ALERTING: case nsITelephonyProvider::CALL_STATE_ALERTING:
// Outgoing call // Outgoing call
@ -1328,8 +1323,8 @@ BluetoothHfpManager::OnConnectSuccess()
// Cache device path for NotifySettings() since we can't get socket address // Cache device path for NotifySettings() since we can't get socket address
// when a headset disconnect with us // when a headset disconnect with us
GetSocketAddr(mDevicePath); mSocket->GetAddress(mDevicePath);
mSocketStatus = GetConnectionStatus(); mSocketStatus = mSocket->GetConnectionStatus();
NotifySettings(); NotifySettings();
} }
@ -1348,8 +1343,6 @@ BluetoothHfpManager::OnConnectError()
} }
// If connecting for some reason didn't work, restart listening // If connecting for some reason didn't work, restart listening
CloseSocket();
mSocketStatus = GetConnectionStatus();
Listen(); Listen();
} }
@ -1368,3 +1361,10 @@ BluetoothHfpManager::OnDisconnect()
CloseScoSocket(); CloseScoSocket();
Reset(); Reset();
} }
bool
BluetoothHfpManager::IsConnected()
{
return mSocket->GetConnectionStatus() ==
SocketConnectionStatus::SOCKET_CONNECTED;
}

Просмотреть файл

@ -8,14 +8,16 @@
#define mozilla_dom_bluetooth_bluetoothhfpmanager_h__ #define mozilla_dom_bluetooth_bluetoothhfpmanager_h__
#include "BluetoothCommon.h" #include "BluetoothCommon.h"
#include "BluetoothSocketObserver.h"
#include "BluetoothTelephonyListener.h" #include "BluetoothTelephonyListener.h"
#include "mozilla/ipc/UnixSocket.h" #include "mozilla/ipc/UnixSocket.h"
#include "nsIObserver.h" #include "nsIObserver.h"
BEGIN_BLUETOOTH_NAMESPACE BEGIN_BLUETOOTH_NAMESPACE
class BluetoothReplyRunnable;
class BluetoothHfpManagerObserver; class BluetoothHfpManagerObserver;
class BluetoothReplyRunnable;
class BluetoothSocket;
class Call; class Call;
/** /**
@ -48,12 +50,17 @@ enum BluetoothCmeError {
NETWORK_NOT_ALLOWED = 32 NETWORK_NOT_ALLOWED = 32
}; };
class BluetoothHfpManager : public mozilla::ipc::UnixSocketConsumer class BluetoothHfpManager : public BluetoothSocketObserver
{ {
public: public:
static BluetoothHfpManager* Get(); static BluetoothHfpManager* Get();
virtual void ReceiveSocketData(nsAutoPtr<mozilla::ipc::UnixSocketRawData>& aMessage) ~BluetoothHfpManager();
MOZ_OVERRIDE;
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, bool Connect(const nsAString& aDeviceObjectPath,
const bool aIsHandsfree, const bool aIsHandsfree,
@ -66,14 +73,17 @@ public:
*/ */
void HandleCallStateChanged(uint32_t aCallIndex, uint16_t aCallState, void HandleCallStateChanged(uint32_t aCallIndex, uint16_t aCallState,
const nsAString& aNumber, bool aSend); const nsAString& aNumber, bool aSend);
bool IsConnected();
private: private:
class GetVolumeTask; class GetVolumeTask;
class SendRingIndicatorTask;
friend class GetVolumeTask; friend class GetVolumeTask;
friend class SendRingIndicatorTask;
friend class BluetoothHfpManagerObserver; friend class BluetoothHfpManagerObserver;
BluetoothHfpManager(); BluetoothHfpManager();
~BluetoothHfpManager();
nsresult HandleIccInfoChanged(); nsresult HandleIccInfoChanged();
nsresult HandleShutdown(); nsresult HandleShutdown();
nsresult HandleVolumeChanged(const nsAString& aData); nsresult HandleVolumeChanged(const nsAString& aData);
@ -91,10 +101,6 @@ private:
bool SendLine(const char* aMessage); bool SendLine(const char* aMessage);
void UpdateCIND(uint8_t aType, uint8_t aValue, bool aSend); 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 mCurrentVgs;
int mCurrentVgm; int mCurrentVgm;
uint32_t mCurrentCallIndex; uint32_t mCurrentCallIndex;
@ -107,11 +113,12 @@ private:
nsString mDevicePath; nsString mDevicePath;
nsString mMsisdn; nsString mMsisdn;
nsString mOperatorName; nsString mOperatorName;
enum mozilla::ipc::SocketConnectionStatus mSocketStatus; enum SocketConnectionStatus mSocketStatus;
nsTArray<Call> mCurrentCallArray; nsTArray<Call> mCurrentCallArray;
nsAutoPtr<BluetoothTelephonyListener> mListener; nsAutoPtr<BluetoothTelephonyListener> mListener;
nsRefPtr<BluetoothReplyRunnable> mRunnable; nsRefPtr<BluetoothReplyRunnable> mRunnable;
nsRefPtr<BluetoothSocket> mSocket;
}; };
END_BLUETOOTH_NAMESPACE END_BLUETOOTH_NAMESPACE

Просмотреть файл

@ -2547,8 +2547,7 @@ BluetoothDBusService::IsConnected(const uint16_t aProfileId)
if (aProfileId == BluetoothServiceClass::HANDSFREE || if (aProfileId == BluetoothServiceClass::HANDSFREE ||
aProfileId == BluetoothServiceClass::HEADSET) { aProfileId == BluetoothServiceClass::HEADSET) {
BluetoothHfpManager* hfp = BluetoothHfpManager::Get(); BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
return (hfp->GetConnectionStatus() == return (hfp->IsConnected());
SocketConnectionStatus::SOCKET_CONNECTED);
} else if (aProfileId == BluetoothServiceClass::OBJECT_PUSH) { } else if (aProfileId == BluetoothServiceClass::OBJECT_PUSH) {
BluetoothOppManager* opp = BluetoothOppManager::Get(); BluetoothOppManager* opp = BluetoothOppManager::Get();
return opp->IsTransferring(); return opp->IsTransferring();