diff --git a/dom/bluetooth/BluetoothHfpManager.cpp b/dom/bluetooth/BluetoothHfpManager.cpp index a316446592e8..8d16589b54b4 100644 --- a/dom/bluetooth/BluetoothHfpManager.cpp +++ b/dom/bluetooth/BluetoothHfpManager.cpp @@ -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 gBluetoothHfpManager; + StaticAutoPtr gBluetoothHfpManager; StaticRefPtr 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 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& 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& 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; +} diff --git a/dom/bluetooth/BluetoothHfpManager.h b/dom/bluetooth/BluetoothHfpManager.h index 2e3cc0cc3573..d20934a92053 100644 --- a/dom/bluetooth/BluetoothHfpManager.h +++ b/dom/bluetooth/BluetoothHfpManager.h @@ -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& aMessage) - MOZ_OVERRIDE; + ~BluetoothHfpManager(); + + virtual void ReceiveSocketData( + nsAutoPtr& 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 mCurrentCallArray; nsAutoPtr mListener; nsRefPtr mRunnable; + nsRefPtr mSocket; }; END_BLUETOOTH_NAMESPACE diff --git a/dom/bluetooth/linux/BluetoothDBusService.cpp b/dom/bluetooth/linux/BluetoothDBusService.cpp index 602d7e5758ae..b763a9147a1c 100644 --- a/dom/bluetooth/linux/BluetoothDBusService.cpp +++ b/dom/bluetooth/linux/BluetoothDBusService.cpp @@ -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();