Bug 851046 - Apply BluetoothSocket to BluetoothHfpManager. r=mrbkap

This commit is contained in:
Eric Chou 2013-03-15 18:45:59 +08:00
parent a328096a8e
commit 4b31e39c03
3 changed files with 100 additions and 94 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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();