Bug 920551 - 2.i/2: fix Bluetooth. r=echou

This commit is contained in:
Vicamo Yang 2013-10-29 16:12:46 +08:00
parent 17e058673d
commit 5d8c284fed
10 changed files with 120 additions and 5 deletions

View File

@ -881,6 +881,7 @@ BluetoothAdapter::IsScoConnected(ErrorResult& aRv)
already_AddRefed<DOMRequest>
BluetoothAdapter::AnswerWaitingCall(ErrorResult& aRv)
{
#ifdef MOZ_B2G_RIL
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
if (!win) {
aRv.Throw(NS_ERROR_FAILURE);
@ -899,11 +900,16 @@ BluetoothAdapter::AnswerWaitingCall(ErrorResult& aRv)
bs->AnswerWaitingCall(results);
return request.forget();
#else
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return nullptr;
#endif // MOZ_B2G_RIL
}
already_AddRefed<DOMRequest>
BluetoothAdapter::IgnoreWaitingCall(ErrorResult& aRv)
{
#ifdef MOZ_B2G_RIL
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
if (!win) {
aRv.Throw(NS_ERROR_FAILURE);
@ -922,11 +928,16 @@ BluetoothAdapter::IgnoreWaitingCall(ErrorResult& aRv)
bs->IgnoreWaitingCall(results);
return request.forget();
#else
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return nullptr;
#endif // MOZ_B2G_RIL
}
already_AddRefed<DOMRequest>
BluetoothAdapter::ToggleCalls(ErrorResult& aRv)
{
#ifdef MOZ_B2G_RIL
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
if (!win) {
aRv.Throw(NS_ERROR_FAILURE);
@ -945,6 +956,10 @@ BluetoothAdapter::ToggleCalls(ErrorResult& aRv)
bs->ToggleCalls(results);
return request.forget();
#else
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return nullptr;
#endif // MOZ_B2G_RIL
}
already_AddRefed<DOMRequest>

View File

@ -15,19 +15,24 @@
#include "BluetoothUtils.h"
#include "BluetoothUuid.h"
#include "MobileConnection.h"
#include "jsapi.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"
#include "nsContentUtils.h"
#include "nsIAudioManager.h"
#include "nsIDOMIccInfo.h"
#include "nsIIccProvider.h"
#include "nsIObserverService.h"
#include "nsISettingsService.h"
#include "nsServiceManagerUtils.h"
#ifdef MOZ_B2G_RIL
#include "nsIDOMIccInfo.h"
#include "nsIDOMMobileConnection.h"
#include "nsIIccProvider.h"
#include "nsIMobileConnectionProvider.h"
#include "nsITelephonyProvider.h"
#include "nsRadioInterfaceLayer.h"
#include "nsServiceManagerUtils.h"
#endif
/**
* BRSF bitmask of AG supported features. See 4.34.1 "Bluetooth Defined AT
@ -44,6 +49,7 @@
#define BRSF_BIT_EXTENDED_ERR_RESULT_CODES (1 << 8)
#define BRSF_BIT_CODEC_NEGOTIATION (1 << 9)
#ifdef MOZ_B2G_RIL
/**
* These constants are used in result code such as +CLIP and +CCWA. The value
* of these constants is the same as TOA_INTERNATIONAL/TOA_UNKNOWN defined in
@ -51,6 +57,7 @@
*/
#define TOA_UNKNOWN 0x81
#define TOA_INTERNATIONAL 0x91
#endif
#define CR_LF "\xd\xa";
@ -66,6 +73,7 @@ namespace {
bool sInShutdown = false;
static const char kHfpCrlf[] = "\xd\xa";
#ifdef MOZ_B2G_RIL
// Sending ringtone related
static bool sStopSendingRingFlag = true;
static int sRingInterval = 3000; //unit: ms
@ -79,8 +87,10 @@ namespace {
// The mechanism should be revised once we know the exact time at which
// Dialer stops playing.
static int sBusyToneInterval = 3700; //unit: ms
#endif // MOZ_B2G_RIL
} // anonymous namespace
#ifdef MOZ_B2G_RIL
/* CallState for sCINDItems[CINDType::CALL].value
* - NO_CALL: there are no calls in progress
* - IN_PROGRESS: at least one call is in progress
@ -113,6 +123,7 @@ enum CallHeldState {
ONHOLD_ACTIVE,
ONHOLD_NOACTIVE
};
#endif // MOZ_B2G_RIL
typedef struct {
const char* name;
@ -123,23 +134,27 @@ typedef struct {
enum CINDType {
BATTCHG = 1,
#ifdef MOZ_B2G_RIL
CALL,
CALLHELD,
CALLSETUP,
SERVICE,
SIGNAL,
ROAM
#endif
};
static CINDItem sCINDItems[] = {
{},
{"battchg", "0-5", 5, true},
#ifdef MOZ_B2G_RIL
{"call", "0,1", CallState::NO_CALL, true},
{"callheld", "0-2", CallHeldState::NO_CALLHELD, true},
{"callsetup", "0-3", CallSetupState::NO_CALLSETUP, true},
{"service", "0,1", 0, true},
{"signal", "0-5", 0, true},
{"roam", "0,1", 0, true}
#endif
};
class BluetoothHfpManager::GetVolumeTask : public nsISettingsServiceCallback
@ -206,6 +221,7 @@ BluetoothHfpManager::Notify(const hal::BatteryInformation& aBatteryInfo)
}
}
#ifdef MOZ_B2G_RIL
class BluetoothHfpManager::RespondToBLDNTask : public Task
{
private:
@ -265,6 +281,7 @@ private:
nsString mNumber;
int mType;
};
#endif // MOZ_B2G_RIL
class BluetoothHfpManager::CloseScoTask : public Task
{
@ -277,6 +294,7 @@ private:
}
};
#ifdef MOZ_B2G_RIL
static bool
IsValidDtmf(const char aChar) {
// Valid DTMF: [*#0-9ABCD]
@ -319,6 +337,7 @@ Call::IsActive()
{
return (mState == nsITelephonyProvider::CALL_STATE_CONNECTED);
}
#endif // MOZ_B2G_RIL
/**
* BluetoothHfpManager
@ -328,6 +347,7 @@ BluetoothHfpManager::BluetoothHfpManager() : mController(nullptr)
Reset();
}
#ifdef MOZ_B2G_RIL
void
BluetoothHfpManager::ResetCallArray()
{
@ -341,25 +361,31 @@ BluetoothHfpManager::ResetCallArray()
mCdmaSecondCall.Reset();
}
}
#endif // MOZ_B2G_RIL
void
BluetoothHfpManager::Reset()
{
#ifdef MOZ_B2G_RIL
sStopSendingRingFlag = true;
sCINDItems[CINDType::CALL].value = CallState::NO_CALL;
sCINDItems[CINDType::CALLSETUP].value = CallSetupState::NO_CALLSETUP;
sCINDItems[CINDType::CALLHELD].value = CallHeldState::NO_CALLHELD;
#endif
for (uint8_t i = 1; i < ArrayLength(sCINDItems); i++) {
sCINDItems[i].activated = true;
}
#ifdef MOZ_B2G_RIL
mCCWA = false;
mCLIP = false;
mDialingRequestProcessed = true;
#endif
mCMEE = false;
mCMER = false;
mReceiveVgsFlag = false;
mDialingRequestProcessed = true;
#ifdef MOZ_B2G_RIL
// We disable BSIR by default as it requires OEM implement BT SCO + SPEAKER
// output audio path in audio driver. OEM can enable BSIR by setting
// mBSIR=true here.
@ -368,6 +394,7 @@ BluetoothHfpManager::Reset()
mBSIR = false;
ResetCallArray();
#endif
}
bool
@ -386,11 +413,13 @@ BluetoothHfpManager::Init()
hal::RegisterBatteryObserver(this);
#ifdef MOZ_B2G_RIL
mListener = new BluetoothRilListener();
if (!mListener->StartListening()) {
BT_WARNING("Failed to start listening RIL");
return false;
}
#endif
nsCOMPtr<nsISettingsService> settings =
do_GetService("@mozilla.org/settingsService;1");
@ -417,10 +446,12 @@ BluetoothHfpManager::Init()
BluetoothHfpManager::~BluetoothHfpManager()
{
#ifdef MOZ_B2G_RIL
if (!mListener->StopListening()) {
BT_WARNING("Failed to stop listening RIL");
}
mListener = nullptr;
#endif
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE_VOID(obs);
@ -486,6 +517,7 @@ BluetoothHfpManager::NotifyConnectionStatusChanged(const nsAString& aType)
DispatchStatusChangedEvent(eventName, mDeviceAddress, status);
}
#ifdef MOZ_B2G_RIL
void
BluetoothHfpManager::NotifyDialer(const nsAString& aCommand)
{
@ -502,6 +534,7 @@ BluetoothHfpManager::NotifyDialer(const nsAString& aCommand)
BT_WARNING("Failed to broadcast system message to dialer");
}
}
#endif // MOZ_B2G_RIL
void
BluetoothHfpManager::HandleVolumeChanged(const nsAString& aData)
@ -551,6 +584,7 @@ BluetoothHfpManager::HandleVolumeChanged(const nsAString& aData)
}
}
#ifdef MOZ_B2G_RIL
void
BluetoothHfpManager::HandleVoiceConnectionChanged()
{
@ -636,6 +670,7 @@ BluetoothHfpManager::HandleIccInfoChanged()
NS_ENSURE_TRUE_VOID(gsmIccInfo);
gsmIccInfo->GetMsisdn(mMsisdn);
}
#endif // MOZ_B2G_RIL
void
BluetoothHfpManager::HandleShutdown()
@ -663,6 +698,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
// For more information, please refer to 4.34.1 "Bluetooth Defined AT
// Capabilities" in Bluetooth hands-free profile 1.6
if (msg.Find("AT+BRSF=") != -1) {
#ifdef MOZ_B2G_RIL
uint32_t brsf = BRSF_BIT_ABILITY_TO_REJECT_CALL |
BRSF_BIT_ENHANCED_CALL_STATUS;
@ -675,6 +711,9 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
if (mBSIR) {
brsf |= BRSF_BIT_IN_BAND_RING_TONE;
}
#else
uint32_t brsf = 0;
#endif // MOZ_B2G_RIL
SendCommand("+BRSF: ", brsf);
} else if (msg.Find("AT+CIND=?") != -1) {
@ -715,6 +754,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
// AT+CMEE = 1: use numeric <err>
// AT+CMEE = 2: use verbose <err>
mCMEE = !atCommandValues[0].EqualsLiteral("0");
#ifdef MOZ_B2G_RIL
} else if (msg.Find("AT+COPS=") != -1) {
ParseAtCommand(msg, 8, atCommandValues);
@ -753,6 +793,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
message += atCommandValues[0].get()[0];
NotifyDialer(NS_ConvertUTF8toUTF16(message));
}
#endif // MOZ_B2G_RIL
} else if (msg.Find("AT+VGM=") != -1) {
ParseAtCommand(msg, 7, atCommandValues);
@ -770,6 +811,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
NS_ASSERTION(vgm >= 0 && vgm <= 15, "Received invalid VGM value");
mCurrentVgm = vgm;
#ifdef MOZ_B2G_RIL
} else if (msg.Find("AT+CHLD=?") != -1) {
SendLine("+CHLD: (0,1,2)");
} else if (msg.Find("AT+CHLD=") != -1) {
@ -820,6 +862,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
SendLine("ERROR");
return;
}
#endif // MOZ_B2G_RIL
} else if (msg.Find("AT+VGS=") != -1) {
// Adjust volume by headset
mReceiveVgsFlag = true;
@ -847,6 +890,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
data.AppendInt(newVgs);
os->NotifyObservers(nullptr, "bluetooth-volume-change", data.get());
#ifdef MOZ_B2G_RIL
} else if ((msg.Find("AT+BLDN") != -1) || (msg.Find("ATD>") != -1)) {
// Dialer app of FFOS v1 does not have plan to support Memory Dailing.
// However, in order to pass Bluetooth HFP certification, we still have to
@ -972,6 +1016,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
// Ignore requests to activate/deactivate mandatory indicators
}
}
#endif // MOZ_B2G_RIL
} else {
nsCString warningMsg;
warningMsg.Append(NS_LITERAL_CSTRING("Unsupported AT command: "));
@ -1096,6 +1141,7 @@ BluetoothHfpManager::Disconnect(BluetoothProfileController* aController)
mSocket->Disconnect();
}
#ifdef MOZ_B2G_RIL
void
BluetoothHfpManager::SendCCWA(const nsAString& aNumber, int aType)
{
@ -1157,6 +1203,7 @@ BluetoothHfpManager::SendCLCC(const Call& aCall, int aIndex)
return SendLine(message.get());
}
#endif // MOZ_B2G_RIL
bool
BluetoothHfpManager::SendLine(const char* aMessage)
@ -1222,6 +1269,7 @@ BluetoothHfpManager::SendCommand(const char* aCommand, uint32_t aValue)
message.AppendLiteral(",");
}
}
#ifdef MOZ_B2G_RIL
} else if (!strcmp(aCommand, "+CLCC: ")) {
bool rv = true;
uint32_t callNumbers = mCurrentCallArray.Length();
@ -1238,6 +1286,7 @@ BluetoothHfpManager::SendCommand(const char* aCommand, uint32_t aValue)
}
return rv;
#endif // MOZ_B2G_RIL
} else {
message.AppendInt(aValue);
}
@ -1245,6 +1294,7 @@ BluetoothHfpManager::SendCommand(const char* aCommand, uint32_t aValue)
return SendLine(message.get());
}
#ifdef MOZ_B2G_RIL
void
BluetoothHfpManager::UpdateCIND(uint8_t aType, uint8_t aValue, bool aSend)
{
@ -1525,12 +1575,15 @@ BluetoothHfpManager::ToggleCalls()
nsITelephonyProvider::CALL_STATE_HELD :
nsITelephonyProvider::CALL_STATE_CONNECTED;
}
#endif // MOZ_B2G_RIL
void
BluetoothHfpManager::OnSocketConnectSuccess(BluetoothSocket* aSocket)
{
MOZ_ASSERT(aSocket);
#ifdef MOZ_B2G_RIL
MOZ_ASSERT(mListener);
#endif
// Success to create a SCO socket
if (aSocket == mScoSocket) {
@ -1559,10 +1612,12 @@ BluetoothHfpManager::OnSocketConnectSuccess(BluetoothSocket* aSocket)
mHandsfreeSocket = nullptr;
}
#ifdef MOZ_B2G_RIL
// Enumerate current calls
mListener->EnumerateCalls();
mFirstCKPD = true;
#endif
// Cache device path for NotifySettings() since we can't get socket address
// when a headset disconnect with us

View File

@ -9,7 +9,9 @@
#include "BluetoothCommon.h"
#include "BluetoothProfileManagerBase.h"
#ifdef MOZ_B2G_RIL
#include "BluetoothRilListener.h"
#endif
#include "BluetoothSocketObserver.h"
#include "mozilla/ipc/UnixSocket.h"
#include "mozilla/Hal.h"
@ -18,6 +20,8 @@ BEGIN_BLUETOOTH_NAMESPACE
class BluetoothReplyRunnable;
class BluetoothSocket;
#ifdef MOZ_B2G_RIL
class Call;
/**
@ -67,6 +71,7 @@ public:
nsString mNumber;
int mType;
};
#endif // MOZ_B2G_RIL
class BluetoothHfpManager : public BluetoothSocketObserver
, public BluetoothProfileManagerBase
@ -109,6 +114,7 @@ public:
bool DisconnectSco();
bool ListenSco();
#ifdef MOZ_B2G_RIL
/**
* @param aSend A boolean indicates whether we need to notify headset or not
*/
@ -117,26 +123,33 @@ public:
const bool aIsOutgoing, bool aSend);
void HandleIccInfoChanged();
void HandleVoiceConnectionChanged();
#endif
bool IsConnected();
bool IsScoConnected();
#ifdef MOZ_B2G_RIL
// CDMA-specific functions
void UpdateSecondNumber(const nsAString& aNumber);
void AnswerWaitingCall();
void IgnoreWaitingCall();
void ToggleCalls();
#endif
private:
class CloseScoTask;
class GetVolumeTask;
#ifdef MOZ_B2G_RIL
class RespondToBLDNTask;
class SendRingIndicatorTask;
#endif
friend class CloseScoTask;
friend class GetVolumeTask;
#ifdef MOZ_B2G_RIL
friend class RespondToBLDNTask;
friend class SendRingIndicatorTask;
#endif
friend class BluetoothHfpManagerObserver;
BluetoothHfpManager();
@ -146,41 +159,55 @@ private:
bool Init();
void Notify(const hal::BatteryInformation& aBatteryInfo);
void Reset();
#ifdef MOZ_B2G_RIL
void ResetCallArray();
uint32_t FindFirstCall(uint16_t aState);
uint32_t GetNumberOfCalls(uint16_t aState);
PhoneType GetPhoneType(const nsAString& aType);
#endif
void NotifyConnectionStatusChanged(const nsAString& aType);
void NotifyDialer(const nsAString& aCommand);
#ifdef MOZ_B2G_RIL
void SendCCWA(const nsAString& aNumber, int aType);
bool SendCLCC(const Call& aCall, int aIndex);
#endif
bool SendCommand(const char* aCommand, uint32_t aValue = 0);
bool SendLine(const char* aMessage);
#ifdef MOZ_B2G_RIL
void UpdateCIND(uint8_t aType, uint8_t aValue, bool aSend = true);
#endif
void OnScoConnectSuccess();
void OnScoConnectError();
void OnScoDisconnect();
int mCurrentVgs;
int mCurrentVgm;
#ifdef MOZ_B2G_RIL
bool mBSIR;
bool mCCWA;
bool mCLIP;
#endif
bool mCMEE;
bool mCMER;
#ifdef MOZ_B2G_RIL
bool mFirstCKPD;
int mNetworkSelectionMode;
PhoneType mPhoneType;
#endif
bool mReceiveVgsFlag;
#ifdef MOZ_B2G_RIL
bool mDialingRequestProcessed;
#endif
nsString mDeviceAddress;
#ifdef MOZ_B2G_RIL
nsString mMsisdn;
nsString mOperatorName;
nsTArray<Call> mCurrentCallArray;
nsAutoPtr<BluetoothRilListener> mListener;
#endif
nsRefPtr<BluetoothProfileController> mController;
nsRefPtr<BluetoothReplyRunnable> mScoRunnable;
@ -198,8 +225,10 @@ private:
nsRefPtr<BluetoothSocket> mScoSocket;
SocketConnectionStatus mScoSocketStatus;
#ifdef MOZ_B2G_RIL
// CDMA-specific variable
Call mCdmaSecondCall;
#endif
};
END_BLUETOOTH_NAMESPACE

View File

@ -266,6 +266,7 @@ public:
virtual void
IsScoConnected(BluetoothReplyRunnable* aRunnable) = 0;
#ifdef MOZ_B2G_RIL
virtual void
AnswerWaitingCall(BluetoothReplyRunnable* aRunnable) = 0;
@ -274,6 +275,7 @@ public:
virtual void
ToggleCalls(BluetoothReplyRunnable* aRunnable) = 0;
#endif
virtual void
SendMetaData(const nsAString& aTitle,

View File

@ -226,12 +226,14 @@ BluetoothParent::RecvPBluetoothRequestConstructor(
return actor->DoRequest(aRequest.get_DisconnectScoRequest());
case Request::TIsScoConnectedRequest:
return actor->DoRequest(aRequest.get_IsScoConnectedRequest());
#ifdef MOZ_B2G_RIL
case Request::TAnswerWaitingCallRequest:
return actor->DoRequest(aRequest.get_AnswerWaitingCallRequest());
case Request::TIgnoreWaitingCallRequest:
return actor->DoRequest(aRequest.get_IgnoreWaitingCallRequest());
case Request::TToggleCallsRequest:
return actor->DoRequest(aRequest.get_ToggleCallsRequest());
#endif
case Request::TSendMetaDataRequest:
return actor->DoRequest(aRequest.get_SendMetaDataRequest());
case Request::TSendPlayStatusRequest:
@ -581,6 +583,7 @@ BluetoothRequestParent::DoRequest(const IsScoConnectedRequest& aRequest)
return true;
}
#ifdef MOZ_B2G_RIL
bool
BluetoothRequestParent::DoRequest(const AnswerWaitingCallRequest& aRequest)
{
@ -613,6 +616,7 @@ BluetoothRequestParent::DoRequest(const ToggleCallsRequest& aRequest)
return true;
}
#endif // MOZ_B2G_RIL
bool
BluetoothRequestParent::DoRequest(const SendMetaDataRequest& aRequest)

View File

@ -190,6 +190,7 @@ protected:
bool
DoRequest(const IsScoConnectedRequest& aRequest);
#ifdef MOZ_B2G_RIL
bool
DoRequest(const AnswerWaitingCallRequest& aRequest);
@ -198,6 +199,7 @@ protected:
bool
DoRequest(const ToggleCallsRequest& aRequest);
#endif
bool
DoRequest(const SendMetaDataRequest& aRequest);

View File

@ -328,6 +328,7 @@ BluetoothServiceChildProcess::IsScoConnected(BluetoothReplyRunnable* aRunnable)
SendRequest(aRunnable, IsScoConnectedRequest());
}
#ifdef MOZ_B2G_RIL
void
BluetoothServiceChildProcess::AnswerWaitingCall(
BluetoothReplyRunnable* aRunnable)
@ -348,6 +349,7 @@ BluetoothServiceChildProcess::ToggleCalls(
{
SendRequest(aRunnable, ToggleCallsRequest());
}
#endif // MOZ_B2G_RIL
void
BluetoothServiceChildProcess::SendMetaData(const nsAString& aTitle,

View File

@ -149,6 +149,7 @@ public:
virtual void
IsScoConnected(BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
#ifdef MOZ_B2G_RIL
virtual void
AnswerWaitingCall(BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
@ -157,6 +158,7 @@ public:
virtual void
ToggleCalls(BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
#endif
virtual void
SendMetaData(const nsAString& aTitle,

View File

@ -2627,6 +2627,7 @@ BluetoothDBusService::IsConnected(const uint16_t aServiceUuid)
return profile->IsConnected();
}
#ifdef MOZ_B2G_RIL
void
BluetoothDBusService::AnswerWaitingCall(BluetoothReplyRunnable* aRunnable)
{
@ -2659,6 +2660,7 @@ BluetoothDBusService::ToggleCalls(BluetoothReplyRunnable* aRunnable)
DispatchBluetoothReply(aRunnable, BluetoothValue(true), EmptyString());
}
#endif // MOZ_B2G_RIL
class OnUpdateSdpRecordsRunnable : public nsRunnable
{

View File

@ -135,6 +135,7 @@ public:
virtual void
IsScoConnected(BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
#ifdef MOZ_B2G_RIL
virtual void
AnswerWaitingCall(BluetoothReplyRunnable* aRunnable);
@ -143,6 +144,7 @@ public:
virtual void
ToggleCalls(BluetoothReplyRunnable* aRunnable);
#endif
virtual void
SendMetaData(const nsAString& aTitle,