Bug 925638 - Patch 1/3: hfp cdma-handling functions, r=echou

This commit is contained in:
Ben Tian 2013-10-17 12:40:17 +08:00
Родитель ea943ab17f
Коммит e3f3bf600f
3 изменённых файлов: 181 добавлений и 67 удалений

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

@ -142,22 +142,6 @@ static CINDItem sCINDItems[] = {
{"roam", "0,1", 0, true}
};
class mozilla::dom::bluetooth::Call {
public:
Call(uint16_t aState = nsITelephonyProvider::CALL_STATE_DISCONNECTED,
bool aDirection = false,
const nsAString& aNumber = EmptyString(),
int aType = TOA_UNKNOWN)
: mState(aState), mDirection(aDirection), mNumber(aNumber), mType(aType)
{
}
uint16_t mState;
bool mDirection; // true: incoming call; false: outgoing call
nsString mNumber;
int mType;
};
class BluetoothHfpManager::GetVolumeTask : public nsISettingsServiceCallback
{
public:
@ -313,6 +297,32 @@ IsMandatoryIndicator(const CINDType aType) {
(aType == CINDType::CALLSETUP);
}
/**
* Call
*/
Call::Call()
{
Reset();
}
void
Call::Reset()
{
mState = nsITelephonyProvider::CALL_STATE_DISCONNECTED;
mDirection = false;
mNumber.Truncate();
mType = TOA_UNKNOWN;
}
bool
Call::IsActive()
{
return (mState == nsITelephonyProvider::CALL_STATE_CONNECTED);
}
/**
* BluetoothHfpManager
*/
BluetoothHfpManager::BluetoothHfpManager()
{
Reset();
@ -326,6 +336,10 @@ BluetoothHfpManager::ResetCallArray()
// index from RIL starts at 1.
Call call;
mCurrentCallArray.AppendElement(call);
if (mPhoneType == PhoneType::CDMA) {
mCdmaSecondCall.Reset();
}
}
void
@ -550,6 +564,10 @@ BluetoothHfpManager::HandleVoiceConnectionChanged()
connection->GetVoiceConnectionInfo(getter_AddRefs(voiceInfo));
NS_ENSURE_TRUE_VOID(voiceInfo);
nsString type;
voiceInfo->GetType(type);
mPhoneType = GetPhoneType(type);
bool roaming;
voiceInfo->GetRoaming(&roaming);
UpdateCIND(CINDType::ROAM, roaming);
@ -647,10 +665,15 @@ 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) {
uint32_t brsf = BRSF_BIT_THREE_WAY_CALLING |
BRSF_BIT_ABILITY_TO_REJECT_CALL |
uint32_t brsf = BRSF_BIT_ABILITY_TO_REJECT_CALL |
BRSF_BIT_ENHANCED_CALL_STATUS;
// No support for three way calling in CDMA since
// CDMA disallows to hang existing call for CHLD=1
if (mPhoneType != PhoneType::CDMA) {
brsf |= BRSF_BIT_THREE_WAY_CALLING;
}
if (mBSIR) {
brsf |= BRSF_BIT_IN_BAND_RING_TONE;
}
@ -1076,6 +1099,68 @@ BluetoothHfpManager::Disconnect(BluetoothProfileController* aController)
mSocket = nullptr;
}
void
BluetoothHfpManager::SendCCWA(const nsAString& aNumber, int aType)
{
if (mCCWA) {
nsAutoCString ccwaMsg("+CCWA: \"");
ccwaMsg.Append(NS_ConvertUTF16toUTF8(aNumber));
ccwaMsg.AppendLiteral("\",");
ccwaMsg.AppendInt(aType);
SendLine(ccwaMsg.get());
}
}
bool
BluetoothHfpManager::SendCLCC(const Call& aCall, int aIndex)
{
if (aCall.mState == nsITelephonyProvider::CALL_STATE_DISCONNECTED) {
return true;
}
nsAutoCString message("+CLCC: ");
message.AppendInt(aIndex);
message.AppendLiteral(",");
message.AppendInt(aCall.mDirection);
message.AppendLiteral(",");
int status = 0;
switch (aCall.mState) {
case nsITelephonyProvider::CALL_STATE_CONNECTED:
if (mPhoneType == PhoneType::CDMA && aIndex == 1) {
status = (mCdmaSecondCall.IsActive()) ? 1 : 0;
}
message.AppendInt(status);
break;
case nsITelephonyProvider::CALL_STATE_HELD:
message.AppendInt(1);
break;
case nsITelephonyProvider::CALL_STATE_DIALING:
message.AppendInt(2);
break;
case nsITelephonyProvider::CALL_STATE_ALERTING:
message.AppendInt(3);
break;
case nsITelephonyProvider::CALL_STATE_INCOMING:
if (!FindFirstCall(nsITelephonyProvider::CALL_STATE_CONNECTED)) {
message.AppendInt(4);
} else {
message.AppendInt(5);
}
break;
default:
BT_WARNING("Not handling call status for CLCC");
break;
}
message.AppendLiteral(",0,0,\"");
message.Append(NS_ConvertUTF16toUTF8(aCall.mNumber));
message.AppendLiteral("\",");
message.AppendInt(aCall.mType);
return SendLine(message.get());
}
bool
BluetoothHfpManager::SendLine(const char* aMessage)
{
@ -1143,49 +1228,18 @@ BluetoothHfpManager::SendCommand(const char* aCommand, uint32_t aValue)
} else if (!strcmp(aCommand, "+CLCC: ")) {
bool rv = true;
uint32_t callNumbers = mCurrentCallArray.Length();
for (uint32_t i = 1; i < callNumbers; i++) {
Call& call = mCurrentCallArray[i];
if (call.mState == nsITelephonyProvider::CALL_STATE_DISCONNECTED) {
continue;
}
message.AssignLiteral("+CLCC: ");
message.AppendInt(i);
message.AppendLiteral(",");
message.AppendInt(call.mDirection);
message.AppendLiteral(",");
switch (call.mState) {
case nsITelephonyProvider::CALL_STATE_CONNECTED:
message.AppendInt(0);
break;
case nsITelephonyProvider::CALL_STATE_HELD:
message.AppendInt(1);
break;
case nsITelephonyProvider::CALL_STATE_DIALING:
message.AppendInt(2);
break;
case nsITelephonyProvider::CALL_STATE_ALERTING:
message.AppendInt(3);
break;
case nsITelephonyProvider::CALL_STATE_INCOMING:
if (!FindFirstCall(nsITelephonyProvider::CALL_STATE_CONNECTED)) {
message.AppendInt(4);
} else {
message.AppendInt(5);
}
break;
default:
BT_WARNING("Not handling call status for CLCC");
break;
}
message.AppendLiteral(",0,0,\"");
message.Append(NS_ConvertUTF16toUTF8(call.mNumber));
message.AppendLiteral("\",");
message.AppendInt(call.mType);
rv &= SendLine(message.get());
uint32_t i;
for (i = 1; i < callNumbers; i++) {
rv &= SendCLCC(mCurrentCallArray[i], i);
}
if (!mCdmaSecondCall.mNumber.IsEmpty()) {
MOZ_ASSERT(mPhoneType == PhoneType::CDMA);
MOZ_ASSERT(i == 2);
rv &= SendCLCC(mCdmaSecondCall, 2);
}
return rv;
} else {
message.AppendInt(aValue);
@ -1276,13 +1330,7 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
break;
case nsITelephonyProvider::CALL_STATE_INCOMING:
if (FindFirstCall(nsITelephonyProvider::CALL_STATE_CONNECTED)) {
if (mCCWA) {
nsAutoCString ccwaMsg("+CCWA: \"");
ccwaMsg.Append(NS_ConvertUTF16toUTF8(aNumber));
ccwaMsg.AppendLiteral("\",");
ccwaMsg.AppendInt(mCurrentCallArray[aCallIndex].mType);
SendLine(ccwaMsg.get());
}
SendCCWA(aNumber, mCurrentCallArray[aCallIndex].mType);
UpdateCIND(CINDType::CALLSETUP, CallSetupState::INCOMING, aSend);
} else {
// Start sending RING indicator to HF
@ -1410,6 +1458,41 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
}
}
PhoneType
BluetoothHfpManager::GetPhoneType(const nsAString& aType)
{
// FIXME: Query phone type from RIL after RIL implements new API (bug 912019)
if (aType.EqualsLiteral("gsm") || aType.EqualsLiteral("gprs") ||
aType.EqualsLiteral("edge") || aType.EqualsLiteral("umts") ||
aType.EqualsLiteral("hspa") || aType.EqualsLiteral("hsdpa") ||
aType.EqualsLiteral("hsupa") || aType.EqualsLiteral("hspa+")) {
return PhoneType::GSM;
} else if (aType.EqualsLiteral("is95a") || aType.EqualsLiteral("is95b") ||
aType.EqualsLiteral("1xrtt") || aType.EqualsLiteral("evdo0") ||
aType.EqualsLiteral("evdoa") || aType.EqualsLiteral("evdob")) {
return PhoneType::CDMA;
}
return PhoneType::NONE;
}
void
BluetoothHfpManager::UpdateSecondNumber(const nsAString& aNumber)
{
MOZ_ASSERT(mPhoneType == PhoneType::CDMA);
// Always regard second call as incoming call since v1.2 RIL
// doesn't support outgoing second call in CDMA.
mCdmaSecondCall.mDirection = true;
mCdmaSecondCall.mNumber = aNumber;
mCdmaSecondCall.mType = (aNumber[0] == '+') ? TOA_INTERNATIONAL :
TOA_UNKNOWN;
SendCCWA(aNumber, mCdmaSecondCall.mType);
UpdateCIND(CINDType::CALLSETUP, CallSetupState::INCOMING, true);
}
void
BluetoothHfpManager::OnSocketConnectSuccess(BluetoothSocket* aSocket)
{

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

@ -50,6 +50,24 @@ enum BluetoothCmeError {
NETWORK_NOT_ALLOWED = 32
};
enum PhoneType {
NONE, // no connection
GSM,
CDMA
};
class Call {
public:
Call();
void Reset();
bool IsActive();
uint16_t mState;
bool mDirection; // true: incoming call; false: outgoing call
nsString mNumber;
int mType;
};
class BluetoothHfpManager : public BluetoothSocketObserver
, public BluetoothProfileManagerBase
, public BatteryObserver
@ -103,6 +121,9 @@ public:
bool IsConnected();
bool IsScoConnected();
// CDMA-specific functions
void UpdateSecondNumber(const nsAString& aNumber);
private:
class CloseScoTask;
class GetVolumeTask;
@ -125,10 +146,13 @@ private:
void ResetCallArray();
uint32_t FindFirstCall(uint16_t aState);
uint32_t GetNumberOfCalls(uint16_t aState);
PhoneType GetPhoneType(const nsAString& aType);
void NotifyConnectionStatusChanged(const nsAString& aType);
void NotifyDialer(const nsAString& aCommand);
void SendCCWA(const nsAString& aNumber, int aType);
bool SendCLCC(const Call& aCall, int aIndex);
bool SendCommand(const char* aCommand, uint32_t aValue = 0);
bool SendLine(const char* aMessage);
void UpdateCIND(uint8_t aType, uint8_t aValue, bool aSend = true);
@ -145,6 +169,7 @@ private:
bool mCMER;
bool mFirstCKPD;
int mNetworkSelectionMode;
PhoneType mPhoneType;
bool mReceiveVgsFlag;
bool mDialingRequestProcessed;
nsString mDeviceAddress;
@ -170,6 +195,9 @@ private:
nsRefPtr<BluetoothSocket> mHeadsetSocket;
nsRefPtr<BluetoothSocket> mScoSocket;
SocketConnectionStatus mScoSocketStatus;
// CDMA-specific variable
Call mCdmaSecondCall;
};
END_BLUETOOTH_NAMESPACE

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

@ -214,6 +214,9 @@ TelephonyListener::SupplementaryServiceNotification(int32_t aCallIndex,
NS_IMETHODIMP
TelephonyListener::NotifyCdmaCallWaiting(const nsAString& aNumber)
{
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
hfp->UpdateSecondNumber(aNumber);
return NS_OK;
}