зеркало из https://github.com/mozilla/gecko-dev.git
Bug 925638 - Patch 1/3: hfp cdma-handling functions, r=echou
This commit is contained in:
Родитель
ea943ab17f
Коммит
e3f3bf600f
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче