Snap for 5450365 from 4ea0190392fe4d8c18c9c9c3599c9a68cdd67e59 to pi-platform-release
Change-Id: I837a785109be1555a6787f5b04addb3314323eb1
diff --git a/proto/src/telephony.proto b/proto/src/telephony.proto
index 36f1883..6f26b07 100644
--- a/proto/src/telephony.proto
+++ b/proto/src/telephony.proto
@@ -571,6 +571,21 @@
RIL_E_INVALID_RESPONSE = 67;
}
+// Errors returned by ImsService
+enum ImsServiceErrno {
+
+ // The operation error is unknown
+ IMS_E_UNKNOWN = 0;
+ // The operation has succeeded
+ IMS_E_SUCCESS = 1;
+ // Sending SMS over IMS failed. Do not retry over IMS again or fallback to CS.
+ IMS_E_SMS_SEND_STATUS_ERROR = 2;
+ // Sending SMS over IMS failed. Retry over IMS again.
+ IMS_E_SMS_SEND_STATUS_ERROR_RETRY = 3;
+ // Sending SMS over IMS failed. Fallback to sending the SMS over CS.
+ IMS_E_SMS_SEND_STATUS_ERROR_FALLBACK = 4;
+}
+
// PDP_type values in TS 27.007 section 10.1.1.
enum PdpType {
@@ -1070,6 +1085,9 @@
// System time overwritten by NITZ (Network time)
NITZ_TIME = 21;
+
+ // Change of audio codec
+ AUDIO_CODEC = 22;
}
enum RilRequest {
@@ -1162,6 +1180,53 @@
CALL_DISCONNECTING = 9;
}
+ // Audio codecs
+ enum AudioCodec {
+
+ // Unknown codec
+ AUDIO_CODEC_UNKNOWN = 0;
+
+ AUDIO_CODEC_AMR = 1;
+
+ AUDIO_CODEC_AMR_WB = 2;
+
+ AUDIO_CODEC_QCELP13K = 3;
+
+ AUDIO_CODEC_EVRC = 4;
+
+ AUDIO_CODEC_EVRC_B = 5;
+
+ AUDIO_CODEC_EVRC_WB = 6;
+
+ AUDIO_CODEC_EVRC_NW = 7;
+
+ AUDIO_CODEC_GSM_EFR = 8;
+
+ AUDIO_CODEC_GSM_FR = 9;
+
+ AUDIO_CODEC_GSM_HR = 10;
+
+ AUDIO_CODEC_G711U = 11;
+
+ AUDIO_CODEC_G723 = 12;
+
+ AUDIO_CODEC_G711A = 13;
+
+ AUDIO_CODEC_G722 = 14;
+
+ AUDIO_CODEC_G711AB = 15;
+
+ AUDIO_CODEC_G729 = 16;
+
+ AUDIO_CODEC_EVS_NB = 17;
+
+ AUDIO_CODEC_EVS_WB = 18;
+
+ AUDIO_CODEC_EVS_SWB = 19;
+
+ AUDIO_CODEC_EVS_FB = 20;
+ }
+
// The information about a voice call
message RilCall {
@@ -1269,6 +1334,9 @@
// NITZ time in milliseconds
optional int64 nitz_timestamp_millis = 21;
+
+ // Audio codec at the beginning of the session or when changed
+ optional AudioCodec audio_codec = 22;
}
// Time when call has started, in minutes since epoch,
@@ -1310,13 +1378,13 @@
// or old data call has removed.
DATA_CALL_LIST_CHANGED = 5;
- // Send a SMS message
+ // Send a SMS message over RIL
SMS_SEND = 6;
- // Message has been sent to network
+ // Message has been sent to network using RIL
SMS_SEND_RESULT = 7;
- // Notification about received SMS
+ // Notification about received SMS using RIL
SMS_RECEIVED = 8;
// CB message received
@@ -1426,7 +1494,9 @@
// See 3GPP 27.005, 3.2.5 for GSM/UMTS,
// 3GPP2 N.S0005 (IS-41C) Table 171 for CDMA,
- // -1 if unknown or not applicable
+ // Will map to a SmsManager.RESULT_* code if ims_error is populated
+ // SmsManager can be accessed from
+ // frameworks/base/telephony/java/android/telephony/SmsManager.java
optional int32 error_code = 10;
// RIL error code
@@ -1437,6 +1507,9 @@
// Cellbroadcast message content
optional CBMessage cell_broadcast_message = 13;
+
+ // ImsService error code.
+ optional ImsServiceErrno ims_error = 14;
}
// Time when session has started, in minutes since epoch,
diff --git a/src/java/com/android/internal/telephony/CarrierActionAgent.java b/src/java/com/android/internal/telephony/CarrierActionAgent.java
index 4582404..f72822f 100644
--- a/src/java/com/android/internal/telephony/CarrierActionAgent.java
+++ b/src/java/com/android/internal/telephony/CarrierActionAgent.java
@@ -217,7 +217,7 @@
sendMessage(obtainMessage(CARRIER_ACTION_REPORT_DEFAULT_NETWORK_STATUS, report));
}
- private void carrierActionReset() {
+ public void carrierActionReset() {
carrierActionReportDefaultNetworkStatus(false);
carrierActionSetMeteredApnsEnabled(true);
carrierActionSetRadioEnabled(true);
diff --git a/src/java/com/android/internal/telephony/GsmCdmaConnection.java b/src/java/com/android/internal/telephony/GsmCdmaConnection.java
index c0f67e2..753c0b6 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaConnection.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaConnection.java
@@ -33,6 +33,7 @@
import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
+import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
import com.android.internal.telephony.uicc.UiccCardApplication;
@@ -75,6 +76,11 @@
// The cached delay to be used between DTMF tones fetched from carrier config.
private int mDtmfToneDelay = 0;
+ // Store the current audio codec
+ private int mAudioCodec = DriverCall.AUDIO_QUALITY_UNSPECIFIED;
+
+ private TelephonyMetrics mMetrics = TelephonyMetrics.getInstance();
+
//***** Event Constants
static final int EVENT_DTMF_DONE = 1;
static final int EVENT_PAUSE_DONE = 2;
@@ -654,6 +660,12 @@
changed = true;
}
+ // Metrics for audio codec
+ if (dc.audioQuality != mAudioCodec) {
+ mAudioCodec = dc.audioQuality;
+ mMetrics.writeAudioCodecGsmCdma(mOwner.getPhone().getPhoneId(), dc.audioQuality);
+ }
+
// A null cnapName should be the same as ""
if (TextUtils.isEmpty(dc.name)) {
if (!TextUtils.isEmpty(mCnapName)) {
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 2a94fc5..13f8b0b 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -641,11 +641,16 @@
intent.putExtra(PhoneConstants.PHONE_IN_ECM_STATE, isInEcm());
SubscriptionManager.putPhoneIdAndSubIdExtra(intent, getPhoneId());
ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_ALL);
- if (DBG) logd("sendEmergencyCallbackModeChange");
+ logi("sendEmergencyCallbackModeChange");
}
@Override
public void sendEmergencyCallStateChange(boolean callActive) {
+ if (!isPhoneTypeCdma()) {
+ // It possible that this method got called from ImsPhoneCallTracker#
+ logi("sendEmergencyCallbackModeChange - skip for non-cdma");
+ return;
+ }
if (mBroadcastEmergencyCallStateChanges) {
Intent intent = new Intent(TelephonyIntents.ACTION_EMERGENCY_CALL_STATE_CHANGED);
intent.putExtra(PhoneConstants.PHONE_IN_EMERGENCY_CALL, callActive);
@@ -1400,7 +1405,7 @@
}
}
- if (!isPhoneTypeGsm() && TextUtils.isEmpty(number)) {
+ if (TextUtils.isEmpty(number)) {
// Read platform settings for dynamic voicemail number
CarrierConfigManager configManager = (CarrierConfigManager)
getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
@@ -1408,7 +1413,7 @@
if (b != null && b.getBoolean(
CarrierConfigManager.KEY_CONFIG_TELEPHONY_USE_OWN_NUMBER_FOR_VOICEMAIL_BOOL)) {
number = getLine1Number();
- } else {
+ } else if (!isPhoneTypeGsm()) {
number = "*86";
}
}
@@ -1605,6 +1610,13 @@
IccRecords r = mIccRecords.get();
return (r != null) ? r.getMsisdnNumber() : null;
} else {
+ CarrierConfigManager configManager = (CarrierConfigManager)
+ mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ boolean use_usim = configManager.getConfigForSubId(getSubId()).getBoolean(
+ CarrierConfigManager.KEY_USE_USIM_BOOL);
+ if (use_usim) {
+ return (mSimRecords != null) ? mSimRecords.getMsisdnNumber() : null;
+ }
return mSST.getMdnNumber();
}
}
diff --git a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
index 79ea8d2..56cceb0 100644
--- a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
+++ b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
@@ -32,6 +32,7 @@
import com.android.ims.ImsManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
+import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.internal.telephony.util.SMSDispatcherUtil;
import java.util.HashMap;
@@ -57,6 +58,9 @@
private volatile boolean mIsImsServiceUp;
private volatile boolean mIsRegistered;
private final ImsManager.Connector mImsManagerConnector;
+ /** Telephony metrics instance for logging metrics event */
+ private TelephonyMetrics mMetrics = TelephonyMetrics.getInstance();
+
/**
* Listen to the IMS service state change
*
@@ -107,6 +111,7 @@
int reason) throws RemoteException {
Rlog.d(TAG, "onSendSmsResult token=" + token + " messageRef=" + messageRef
+ " status=" + status + " reason=" + reason);
+ mMetrics.writeOnImsServiceSmsSolicitedResponse(mPhone.getPhoneId(), status, reason);
SmsTracker tracker = mTrackers.get(token);
if (tracker == null) {
throw new IllegalArgumentException("Invalid token.");
@@ -159,8 +164,7 @@
}
@Override
- public void onSmsReceived(int token, String format, byte[] pdu)
- throws RemoteException {
+ public void onSmsReceived(int token, String format, byte[] pdu) {
Rlog.d(TAG, "SMS received.");
android.telephony.SmsMessage message =
android.telephony.SmsMessage.createFromPdu(pdu, format);
@@ -169,7 +173,7 @@
int mappedResult;
switch (result) {
case Intents.RESULT_SMS_HANDLED:
- mappedResult = ImsSmsImplBase.STATUS_REPORT_STATUS_OK;
+ mappedResult = ImsSmsImplBase.DELIVER_STATUS_OK;
break;
case Intents.RESULT_SMS_OUT_OF_MEMORY:
mappedResult = ImsSmsImplBase.DELIVER_STATUS_ERROR_NO_MEMORY;
@@ -189,8 +193,11 @@
Rlog.w(TAG, "SMS Received with a PDU that could not be parsed.");
getImsManager().acknowledgeSms(token, 0, mappedResult);
}
+ mMetrics.writeImsServiceNewSms(mPhone.getPhoneId(), format, mappedResult);
} catch (ImsException e) {
Rlog.e(TAG, "Failed to acknowledgeSms(). Error: " + e.getMessage());
+ mMetrics.writeImsServiceNewSms(mPhone.getPhoneId(), format,
+ ImsSmsImplBase.DELIVER_STATUS_ERROR_GENERIC);
}
}, true);
}
@@ -289,8 +296,9 @@
byte[] pdu = (byte[]) map.get(MAP_KEY_PDU);
byte smsc[] = (byte[]) map.get(MAP_KEY_SMSC);
boolean isRetry = tracker.mRetryCount > 0;
+ String format = getFormat();
- if (SmsConstants.FORMAT_3GPP.equals(getFormat()) && tracker.mRetryCount > 0) {
+ if (SmsConstants.FORMAT_3GPP.equals(format) && tracker.mRetryCount > 0) {
// per TS 23.040 Section 9.2.3.6: If TP-MTI SMS-SUBMIT (0x01) type
// TP-RD (bit 2) is 1 for retry
// and TP-MR is set to previously failed sms TP-MR
@@ -306,13 +314,17 @@
getImsManager().sendSms(
token,
tracker.mMessageRef,
- getFormat(),
+ format,
smsc != null ? new String(smsc) : null,
isRetry,
pdu);
+ mMetrics.writeImsServiceSendSms(mPhone.getPhoneId(), format,
+ ImsSmsImplBase.SEND_STATUS_OK);
} catch (ImsException e) {
Rlog.e(TAG, "sendSms failed. Falling back to PSTN. Error: " + e.getMessage());
fallbackToPstn(token, tracker);
+ mMetrics.writeImsServiceSendSms(mPhone.getPhoneId(), format,
+ ImsSmsImplBase.SEND_STATUS_ERROR_FALLBACK);
}
}
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 0f431ef..c2446e4 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -2784,8 +2784,7 @@
}
/**
- * Check if TETHER_DUN_APN setting or config_tether_apndata includes APN that matches
- * current operator.
+ * Check if there are matching tethering (i.e DUN) for the carrier.
* @return true if there is a matching DUN APN.
*/
public boolean hasMatchedTetherApnSetting() {
@@ -2856,6 +2855,13 @@
}
/**
+ * Action set from carrier signalling broadcast receivers to reset all carrier actions
+ */
+ public void carrierActionResetAll() {
+ mCarrierActionAgent.carrierActionReset();
+ }
+
+ /**
* Notify registrants of a new ringing Connection.
* Subclasses of Phone probably want to replace this with a
* version scoped to their packages
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index fc9dd86..ea6fa81 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -76,7 +76,6 @@
import android.util.SparseArray;
import android.view.WindowManager;
-import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.CarrierActionAgent;
import com.android.internal.telephony.DctConstants;
@@ -248,6 +247,7 @@
if (DBG) log("Provisioning apn alarm");
onActionIntentProvisioningApnAlarm(intent);
} else if (action.equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
+ if (DBG) log("received carrier config change");
if (mIccRecords.get() != null && mIccRecords.get().getRecordsLoaded()) {
setDefaultDataRoamingEnabled();
}
@@ -864,6 +864,14 @@
} else {
onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);
}
+ // Update sharedPreference to false when exits new device provisioning, indicating no users
+ // modifications on the settings for new devices. Thus carrier specific
+ // default roaming settings can be applied for new devices till user modification.
+ final SharedPreferences sp = PreferenceManager
+ .getDefaultSharedPreferences(mPhone.getContext());
+ if (!sp.contains(Phone.DATA_ROAMING_IS_USER_SETTING_KEY)) {
+ sp.edit().putBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, false).commit();
+ }
}
@@ -1736,29 +1744,13 @@
ArrayList<ApnSetting> retDunSettings = new ArrayList<ApnSetting>();
// Places to look for tether APN in order: TETHER_DUN_APN setting (to be deprecated soon),
- // APN database, and config_tether_apndata resource (to be deprecated soon).
+ // APN database
String apnData = Settings.Global.getString(mResolver, Settings.Global.TETHER_DUN_APN);
if (!TextUtils.isEmpty(apnData)) {
dunCandidates.addAll(ApnSetting.arrayFromString(apnData));
if (VDBG) log("fetchDunApns: dunCandidates from Setting: " + dunCandidates);
}
- // todo: remove this and config_tether_apndata after APNs are moved from overlay to apns xml
- // If TETHER_DUN_APN isn't set or APN database doesn't have dun APN,
- // try the resource as last resort.
- if (dunCandidates.isEmpty()) {
- String[] apnArrayData = mPhone.getContext().getResources()
- .getStringArray(R.array.config_tether_apndata);
- if (!ArrayUtils.isEmpty(apnArrayData)) {
- for (String apnString : apnArrayData) {
- ApnSetting apn = ApnSetting.fromString(apnString);
- // apn may be null if apnString isn't valid or has error parsing
- if (apn != null) dunCandidates.add(apn);
- }
- if (VDBG) log("fetchDunApns: dunCandidates from resource: " + dunCandidates);
- }
- }
-
if (dunCandidates.isEmpty()) {
if (!ArrayUtils.isEmpty(mAllApnSettings)) {
for (ApnSetting apn : mAllApnSettings) {
@@ -2714,6 +2706,8 @@
// for single sim device, update to carrier default if user action is not set
useCarrierSpecificDefault = true;
}
+ log("setDefaultDataRoamingEnabled: useCarrierSpecificDefault "
+ + useCarrierSpecificDefault);
if (useCarrierSpecificDefault) {
boolean defaultVal = getDefaultDataRoamingEnabled();
log("setDefaultDataRoamingEnabled: " + setting + "default value: " + defaultVal);
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index 7127eba..a776816 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -1937,9 +1937,11 @@
@VisibleForTesting
public int maybeRemapReasonCode(ImsReasonInfo reasonInfo) {
int code = reasonInfo.getCode();
+ String extraMessage =
+ reasonInfo.getExtraMessage() == null ? "" : reasonInfo.getExtraMessage();
- Pair<Integer, String> toCheck = new Pair<>(code, reasonInfo.getExtraMessage());
- Pair<Integer, String> wildcardToCheck = new Pair<>(null, reasonInfo.getExtraMessage());
+ Pair<Integer, String> toCheck = new Pair<>(code, extraMessage);
+ Pair<Integer, String> wildcardToCheck = new Pair<>(null, extraMessage);
if (mImsReasonCodeMap.containsKey(toCheck)) {
int toCode = mImsReasonCodeMap.get(toCheck);
@@ -1993,6 +1995,7 @@
return DisconnectCause.INCOMING_REJECTED;
case ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE:
+ case ImsReasonInfo.CODE_SIP_USER_REJECTED:
return DisconnectCause.NORMAL;
case ImsReasonInfo.CODE_SIP_FORBIDDEN:
@@ -2001,7 +2004,6 @@
case ImsReasonInfo.CODE_SIP_REDIRECTED:
case ImsReasonInfo.CODE_SIP_BAD_REQUEST:
case ImsReasonInfo.CODE_SIP_NOT_ACCEPTABLE:
- case ImsReasonInfo.CODE_SIP_USER_REJECTED:
case ImsReasonInfo.CODE_SIP_GLOBAL_ERROR:
return DisconnectCause.SERVER_ERROR;
@@ -2652,9 +2654,20 @@
@Override
public void onCallHandover(ImsCall imsCall, int srcAccessTech, int targetAccessTech,
ImsReasonInfo reasonInfo) {
+ // Check with the DCTracker to see if data is enabled; there may be a case when
+ // ImsPhoneCallTracker isn't being informed of the right data enabled state via its
+ // registration, so we'll refresh now.
+ boolean isDataEnabled = mPhone.getDefaultPhone().mDcTracker.isDataEnabled();
if (DBG) {
- log("onCallHandover :: srcAccessTech=" + srcAccessTech + ", targetAccessTech=" +
- targetAccessTech + ", reasonInfo=" + reasonInfo);
+ log("onCallHandover :: srcAccessTech=" + srcAccessTech + ", targetAccessTech="
+ + targetAccessTech + ", reasonInfo=" + reasonInfo + ", dataEnabled="
+ + mIsDataEnabled + "/" + isDataEnabled + ", dataMetered="
+ + mIsViLteDataMetered);
+ }
+ if (mIsDataEnabled != isDataEnabled) {
+ loge("onCallHandover: data enabled state doesn't match! (was=" + mIsDataEnabled
+ + ", actually=" + isDataEnabled);
+ mIsDataEnabled = isDataEnabled;
}
// Only consider it a valid handover to WIFI if the source radio tech is known.
@@ -2691,7 +2704,7 @@
}
if (isHandoverFromWifi && imsCall.isVideoCall()) {
- if (mNotifyHandoverVideoFromWifiToLTE && mIsDataEnabled) {
+ if (mNotifyHandoverVideoFromWifiToLTE && mIsDataEnabled) {
if (conn.getDisconnectCause() == DisconnectCause.NOT_DISCONNECTED) {
log("onCallHandover :: notifying of WIFI to LTE handover.");
conn.onConnectionEvent(
@@ -2708,6 +2721,7 @@
if (!mIsDataEnabled && mIsViLteDataMetered) {
// Call was downgraded from WIFI to LTE and data is metered; downgrade the
// call now.
+ log("onCallHandover :: data is not enabled; attempt to downgrade.");
downgradeVideoCall(ImsReasonInfo.CODE_WIFI_LOST, conn);
}
}
@@ -3744,16 +3758,21 @@
if (conn.hasCapabilities(
Connection.Capability.SUPPORTS_DOWNGRADE_TO_VOICE_LOCAL |
Connection.Capability.SUPPORTS_DOWNGRADE_TO_VOICE_REMOTE)) {
-
+ log("downgradeVideoCall :: callId=" + conn.getTelecomCallId()
+ + " Downgrade to audio");
// If the carrier supports downgrading to voice, then we can simply issue a
// downgrade to voice instead of terminating the call.
modifyVideoCall(imsCall, VideoProfile.STATE_AUDIO_ONLY);
} else if (mSupportPauseVideo && reasonCode != ImsReasonInfo.CODE_WIFI_LOST) {
// The carrier supports video pause signalling, so pause the video if we didn't just
// lose wifi; in that case just disconnect.
+ log("downgradeVideoCall :: callId=" + conn.getTelecomCallId()
+ + " Pause audio");
mShouldUpdateImsConfigOnDisconnect = true;
conn.pauseVideo(VideoPauseTracker.SOURCE_DATA_ENABLED);
} else {
+ log("downgradeVideoCall :: callId=" + conn.getTelecomCallId()
+ + " Disconnect call.");
// At this point the only choice we have is to terminate the call.
try {
imsCall.terminate(ImsReasonInfo.CODE_USER_TERMINATED, reasonCode);
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
index 47b3624..5ab89b9 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
@@ -46,6 +46,7 @@
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.UUSInfo;
+import com.android.internal.telephony.metrics.TelephonyMetrics;
import java.util.Objects;
@@ -64,6 +65,7 @@
private ImsPhoneCall mParent;
private ImsCall mImsCall;
private Bundle mExtras = new Bundle();
+ private TelephonyMetrics mMetrics = TelephonyMetrics.getInstance();
private boolean mDisconnected;
@@ -123,6 +125,9 @@
*/
private boolean mIsVideoEnabled = true;
+ // Store the current audio codec
+ private int mAudioCodec = ImsStreamMediaProfile.AUDIO_QUALITY_NONE;
+
//***** Event Constants
private static final int EVENT_DTMF_DONE = 1;
private static final int EVENT_PAUSE_DONE = 2;
@@ -955,6 +960,13 @@
changed = true;
}
+ // Metrics for audio codec
+ if (localCallProfile != null
+ && localCallProfile.mMediaProfile.mAudioQuality != mAudioCodec) {
+ mAudioCodec = localCallProfile.mMediaProfile.mAudioQuality;
+ mMetrics.writeAudioCodecIms(mOwner.mPhone.getPhoneId(), imsCall.getCallSession());
+ }
+
int newAudioQuality =
getAudioQualityFromCallProfile(localCallProfile, remoteCallProfile);
if (getAudioQuality() != newAudioQuality) {
diff --git a/src/java/com/android/internal/telephony/metrics/CallSessionEventBuilder.java b/src/java/com/android/internal/telephony/metrics/CallSessionEventBuilder.java
index a8221b4..b4a5e6e 100644
--- a/src/java/com/android/internal/telephony/metrics/CallSessionEventBuilder.java
+++ b/src/java/com/android/internal/telephony/metrics/CallSessionEventBuilder.java
@@ -130,4 +130,10 @@
mEvent.calls = rilCalls;
return this;
}
+
+ /** Set the audio codec. */
+ public CallSessionEventBuilder setAudioCodec(int audioCodec) {
+ mEvent.audioCodec = audioCodec;
+ return this;
+ }
}
diff --git a/src/java/com/android/internal/telephony/metrics/SmsSessionEventBuilder.java b/src/java/com/android/internal/telephony/metrics/SmsSessionEventBuilder.java
index 5004ce7..45d8061 100644
--- a/src/java/com/android/internal/telephony/metrics/SmsSessionEventBuilder.java
+++ b/src/java/com/android/internal/telephony/metrics/SmsSessionEventBuilder.java
@@ -54,6 +54,11 @@
return this;
}
+ public SmsSessionEventBuilder setImsServiceErrno(int errno) {
+ mEvent.imsError = errno;
+ return this;
+ }
+
public SmsSessionEventBuilder setSettings(TelephonySettings settings) {
mEvent.settings = settings;
return this;
diff --git a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
index 75ea68f..c4b0e73 100644
--- a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
+++ b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
@@ -41,18 +41,24 @@
import android.os.SystemProperties;
import android.telephony.Rlog;
import android.telephony.ServiceState;
+import android.telephony.SmsManager;
+import android.telephony.SmsMessage;
import android.telephony.TelephonyHistogram;
import android.telephony.TelephonyManager;
import android.telephony.data.DataCallResponse;
import android.telephony.data.DataService;
+import android.telephony.ims.ImsCallProfile;
import android.telephony.ims.ImsCallSession;
import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsStreamMediaProfile;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.telephony.ims.stub.ImsSmsImplBase;
import android.text.TextUtils;
import android.util.Base64;
import android.util.SparseArray;
+import com.android.internal.telephony.DriverCall;
import com.android.internal.telephony.GsmCdmaConnection;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.RIL;
@@ -297,6 +303,8 @@
return "PHONE_STATE_CHANGED";
case TelephonyCallSession.Event.Type.NITZ_TIME:
return "NITZ_TIME";
+ case TelephonyCallSession.Event.Type.AUDIO_CODEC:
+ return "AUDIO_CODEC";
default:
return Integer.toString(event);
}
@@ -386,6 +394,9 @@
+ " isMultiparty = " + call.isMultiparty);
}
pw.decreaseIndent();
+ } else if (event.type == TelephonyCallSession.Event.Type.AUDIO_CODEC) {
+ pw.println(callSessionEventToString(event.type)
+ + "(" + event.audioCodec + ")");
} else {
pw.println(callSessionEventToString(event.type));
}
@@ -412,6 +423,19 @@
pw.print(event.delay);
pw.print(" T=");
pw.println(smsSessionEventToString(event.type));
+ // Only show more info for tx/rx sms
+ if (event.type == SmsSession.Event.Type.SMS_SEND
+ || event.type == SmsSession.Event.Type.SMS_RECEIVED
+ || event.type == SmsSession.Event.Type.SMS_SEND_RESULT) {
+ pw.print(" ReqId=");
+ pw.println(event.rilRequestId);
+ pw.print(" E=");
+ pw.println(event.errorCode);
+ pw.print(" RilE=");
+ pw.println(event.error);
+ pw.print(" ImsE=");
+ pw.println(event.imsError);
+ }
}
pw.decreaseIndent();
}
@@ -1456,6 +1480,31 @@
}
/**
+ * Write SMS related solicited response event
+ *
+ * @param phoneId Phone id
+ * @param errorReason Defined in {@link SmsManager} RESULT_XXX.
+ */
+ public synchronized void writeOnImsServiceSmsSolicitedResponse(int phoneId,
+ @ImsSmsImplBase.SendStatusResult int resultCode, int errorReason) {
+
+ InProgressSmsSession smsSession = mInProgressSmsSessions.get(phoneId);
+ if (smsSession == null) {
+ Rlog.e(TAG, "SMS session is missing");
+ } else {
+
+ smsSession.addEvent(new SmsSessionEventBuilder(
+ SmsSession.Event.Type.SMS_SEND_RESULT)
+ .setImsServiceErrno(resultCode)
+ .setErrorCode(errorReason)
+ );
+
+ smsSession.decreaseExpectedResponse();
+ finishSmsSessionIfNeeded(smsSession);
+ }
+ }
+
+ /**
* Write deactivate data call response event
*
* @param phoneId Phone id
@@ -1740,6 +1789,39 @@
}
/**
+ * Write Send SMS event using ImsService. Expecting response from
+ * {@link #writeOnSmsSolicitedResponse}.
+ *
+ * @param phoneId Phone id
+ * @param format SMS format. Either {@link SmsMessage#FORMAT_3GPP} or
+ * {@link SmsMessage#FORMAT_3GPP2}.
+ * @param resultCode The result of sending the new SMS to the vendor layer to be sent to the
+ * carrier network.
+ */
+ public synchronized void writeImsServiceSendSms(int phoneId, String format,
+ @ImsSmsImplBase.SendStatusResult int resultCode) {
+ InProgressSmsSession smsSession = startNewSmsSessionIfNeeded(phoneId);
+ int formatCode = SmsSession.Event.Format.SMS_FORMAT_UNKNOWN;
+ switch (format) {
+ case SmsMessage.FORMAT_3GPP : {
+ formatCode = SmsSession.Event.Format.SMS_FORMAT_3GPP;
+ break;
+ }
+ case SmsMessage.FORMAT_3GPP2: {
+ formatCode = SmsSession.Event.Format.SMS_FORMAT_3GPP2;
+ break;
+ }
+ }
+ smsSession.addEvent(new SmsSessionEventBuilder(SmsSession.Event.Type.SMS_SEND)
+ .setTech(SmsSession.Event.Tech.SMS_IMS)
+ .setImsServiceErrno(resultCode)
+ .setFormat(formatCode)
+ );
+
+ smsSession.increaseExpectedResponse();
+ }
+
+ /**
* Write incoming SMS event
*
* @param phoneId Phone id
@@ -1758,6 +1840,58 @@
}
/**
+ * Write incoming SMS event
+ *
+ * @param phoneId Phone id
+ * @param format SMS format. Either {@link SmsMessage#FORMAT_3GPP} or
+ * {@link SmsMessage#FORMAT_3GPP2}.
+ * @param result The result of processing the the newly received SMS message.
+ */
+ public synchronized void writeImsServiceNewSms(int phoneId, String format,
+ @ImsSmsImplBase.DeliverStatusResult int result) {
+ InProgressSmsSession smsSession = startNewSmsSessionIfNeeded(phoneId);
+ int formatCode = SmsSession.Event.Format.SMS_FORMAT_UNKNOWN;
+ switch (format) {
+ case SmsMessage.FORMAT_3GPP : {
+ formatCode = SmsSession.Event.Format.SMS_FORMAT_3GPP;
+ break;
+ }
+ case SmsMessage.FORMAT_3GPP2: {
+ formatCode = SmsSession.Event.Format.SMS_FORMAT_3GPP2;
+ break;
+ }
+ }
+ int smsError = SmsManager.RESULT_ERROR_GENERIC_FAILURE;
+ switch (result) {
+ case ImsSmsImplBase.DELIVER_STATUS_OK: {
+ smsError = SmsManager.RESULT_ERROR_NONE;
+ break;
+ }
+ case ImsSmsImplBase.DELIVER_STATUS_ERROR_NO_MEMORY: {
+ smsError = SmsManager.RESULT_NO_MEMORY;
+ break;
+ }
+ case ImsSmsImplBase.DELIVER_STATUS_ERROR_REQUEST_NOT_SUPPORTED: {
+ smsError = SmsManager.RESULT_REQUEST_NOT_SUPPORTED;
+ break;
+ }
+ case ImsSmsImplBase.DELIVER_STATUS_ERROR_GENERIC: {
+ smsError = SmsManager.RESULT_ERROR_GENERIC_FAILURE;
+ break;
+ }
+ }
+ smsSession.addEvent(new SmsSessionEventBuilder(
+ SmsSession.Event.Type.SMS_RECEIVED)
+ .setTech(SmsSession.Event.Tech.SMS_IMS)
+ .setFormat(formatCode)
+ .setErrorCode(smsError)
+ .setImsServiceErrno(TelephonyProto.ImsServiceErrno.IMS_E_SUCCESS)
+ );
+
+ finishSmsSessionIfNeeded(smsSession);
+ }
+
+ /**
* Write incoming Broadcast SMS event
*
* @param phoneId Phone id
@@ -1867,6 +2001,136 @@
addTelephonyEvent(event);
}
+ /**
+ * Convert IMS audio codec into proto defined value
+ *
+ * @param c IMS codec value
+ * @return Codec value defined in call session proto
+ */
+ private int convertImsCodec(int c) {
+ switch (c) {
+ case ImsStreamMediaProfile.AUDIO_QUALITY_AMR:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_AMR;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_AMR_WB:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_AMR_WB;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_QCELP13K:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_QCELP13K;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_EVRC:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_EVRC;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_EVRC_B:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_EVRC_B;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_EVRC_WB:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_EVRC_WB;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_EVRC_NW:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_EVRC_NW;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_GSM_EFR:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_GSM_EFR;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_GSM_FR:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_GSM_FR;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_GSM_HR:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_GSM_HR;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_G711U:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_G711U;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_G723:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_G723;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_G711A:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_G711A;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_G722:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_G722;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_G711AB:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_G711AB;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_G729:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_G729;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_EVS_NB:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_EVS_NB;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_EVS_WB:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_EVS_WB;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_EVS_SWB:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_EVS_SWB;
+ case ImsStreamMediaProfile.AUDIO_QUALITY_EVS_FB:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_EVS_FB;
+ default:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_UNKNOWN;
+ }
+ }
+
+ /**
+ * Convert GSM/CDMA audio codec into proto defined value
+ *
+ * @param c GSM/CDMA codec value
+ * @return Codec value defined in call session proto
+ */
+ private int convertGsmCdmaCodec(int c) {
+ switch (c) {
+ case DriverCall.AUDIO_QUALITY_AMR:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_AMR;
+ case DriverCall.AUDIO_QUALITY_AMR_WB:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_AMR_WB;
+ case DriverCall.AUDIO_QUALITY_GSM_EFR:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_GSM_EFR;
+ case DriverCall.AUDIO_QUALITY_GSM_FR:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_GSM_FR;
+ case DriverCall.AUDIO_QUALITY_GSM_HR:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_GSM_HR;
+ case DriverCall.AUDIO_QUALITY_EVRC:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_EVRC;
+ case DriverCall.AUDIO_QUALITY_EVRC_B:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_EVRC_B;
+ case DriverCall.AUDIO_QUALITY_EVRC_WB:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_EVRC_WB;
+ case DriverCall.AUDIO_QUALITY_EVRC_NW:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_EVRC_NW;
+ default:
+ return TelephonyCallSession.Event.AudioCodec.AUDIO_CODEC_UNKNOWN;
+ }
+ }
+
+ /**
+ * Write audio codec event
+ *
+ * @param phoneId Phone id
+ * @param session IMS call session
+ */
+ public void writeAudioCodecIms(int phoneId, ImsCallSession session) {
+ InProgressCallSession callSession = mInProgressCallSessions.get(phoneId);
+ if (callSession == null) {
+ Rlog.e(TAG, "Call session is missing");
+ return;
+ }
+
+ ImsCallProfile localCallProfile = session.getLocalCallProfile();
+ if (localCallProfile != null) {
+ int codec = convertImsCodec(localCallProfile.mMediaProfile.mAudioQuality);
+ callSession.addEvent(new CallSessionEventBuilder(
+ TelephonyCallSession.Event.Type.AUDIO_CODEC)
+ .setCallIndex(getCallId(session))
+ .setAudioCodec(codec));
+
+ if (VDBG) Rlog.v(TAG, "Logged Audio Codec event. Value: " + codec);
+ }
+ }
+
+ /**
+ * Write audio codec event
+ *
+ * @param phoneId Phone id
+ * @param audioQuality Audio quality value
+ */
+ public void writeAudioCodecGsmCdma(int phoneId, int audioQuality) {
+ InProgressCallSession callSession = mInProgressCallSessions.get(phoneId);
+ if (callSession == null) {
+ Rlog.e(TAG, "Call session is missing");
+ return;
+ }
+
+ int codec = convertGsmCdmaCodec(audioQuality);
+ callSession.addEvent(new CallSessionEventBuilder(
+ TelephonyCallSession.Event.Type.AUDIO_CODEC)
+ .setAudioCodec(codec));
+
+ if (VDBG) Rlog.v(TAG, "Logged Audio Codec event. Value: " + codec);
+ }
+
//TODO: Expand the proto in the future
public void writeOnImsCallProgressing(int phoneId, ImsCallSession session) {}
public void writeOnImsCallStarted(int phoneId, ImsCallSession session) {}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
index 60bc61f..3a18223 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
@@ -957,4 +957,30 @@
assertEquals(EVENT_SET_ICC_LOCK_ENABLED, message.what);
assertTrue(ret.exception != null);
}
+
+ @Test
+ @SmallTest
+ public void testGetLine1NumberForGsmPhone() {
+ final String msisdn = "+1234567890";
+ doReturn(msisdn).when(mSimRecords).getMsisdnNumber();
+
+ switchToGsm();
+ assertEquals(msisdn, mPhoneUT.getLine1Number());
+ }
+
+ @Test
+ @SmallTest
+ public void testGetLine1NumberForCdmaPhone() {
+ final String mdn = "1234567890";
+ final String msisdn = "+1234567890";
+ doReturn(mdn).when(mSST).getMdnNumber();
+ doReturn(msisdn).when(mSimRecords).getMsisdnNumber();
+
+ switchToCdma();
+ assertEquals(mdn, mPhoneUT.getLine1Number());
+
+ mContextFixture.getCarrierConfigBundle().putBoolean(
+ CarrierConfigManager.KEY_USE_USIM_BOOL, true);
+ assertEquals(msisdn, mPhoneUT.getLine1Number());
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index 89d8143..b4d1916 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -383,6 +383,8 @@
doReturn(mServiceState).when(mPhone).getServiceState();
doReturn(mServiceState).when(mImsPhone).getServiceState();
doReturn(mPhone).when(mImsPhone).getDefaultPhone();
+ mPhone.mDcTracker = mDcTracker;
+ doReturn(true).when(mDcTracker).isDataEnabled();
doReturn(true).when(mPhone).isPhoneTypeGsm();
doReturn(PhoneConstants.PHONE_TYPE_GSM).when(mPhone).getPhoneType();
doReturn(mCT).when(mPhone).getCallTracker();