Loading proto/src/persist_atoms.proto +3 −0 Original line number Diff line number Diff line Loading @@ -277,6 +277,9 @@ message VoiceCallSession { optional int32 fold_state = 34; optional int64 rat_switch_count_after_connected = 35; optional bool handover_in_progress = 36; optional bool is_iwlan_cross_sim_at_start = 37; optional bool is_iwlan_cross_sim_at_end = 38; optional bool is_iwlan_cross_sim_at_connected = 39; // Internal use only optional int64 setup_begin_millis = 10001; Loading src/java/com/android/internal/telephony/metrics/MetricsCollector.java +4 −1 Original line number Diff line number Diff line Loading @@ -981,7 +981,10 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback { session.lastKnownRat, session.foldState, session.ratSwitchCountAfterConnected, session.handoverInProgress); session.handoverInProgress, session.isIwlanCrossSimAtStart, session.isIwlanCrossSimAtEnd, session.isIwlanCrossSimAtConnected); } private static StatsEvent buildStatsEvent(IncomingSms sms) { Loading src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java +25 −1 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.ImsStreamMediaProfile; import android.telephony.ims.stub.ImsRegistrationImplBase; import android.util.LongSparseArray; import android.util.SparseArray; import android.util.SparseIntArray; Loading Loading @@ -469,6 +470,11 @@ public class VoiceCallSessionStats { proto.videoEnabled = videoState != VideoProfile.STATE_AUDIO_ONLY ? true : false; proto.handoverInProgress = isHandoverInProgress(bearer, proto.isEmergency); boolean isCrossSimCall = isCrossSimCall(conn); proto.isIwlanCrossSimAtStart = isCrossSimCall; proto.isIwlanCrossSimAtEnd = isCrossSimCall; proto.isIwlanCrossSimAtConnected = isCrossSimCall; // internal fields for tracking if (getDirection(conn) == VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT) { // MT call setup hasn't begun hence set to 0 Loading Loading @@ -594,7 +600,9 @@ public class VoiceCallSessionStats { proto.setupFailed = false; // Track RAT when voice call is connected. ServiceState serviceState = getServiceState(); proto.ratAtConnected = getVoiceRatWithVoNRFix(mPhone, serviceState, proto.bearerAtEnd); @NetworkType int rat = getVoiceRatWithVoNRFix(mPhone, serviceState, proto.bearerAtEnd); proto.ratAtConnected = rat; proto.isIwlanCrossSimAtConnected = isCrossSimCall(conn); // Reset list of codecs with the last codec at the present time. In this way, we // track codec quality only after call is connected and not while ringing. resetCodecList(conn); Loading Loading @@ -631,6 +639,7 @@ public class VoiceCallSessionStats { proto.lastKnownRat = rat; } } proto.isIwlanCrossSimAtEnd = isCrossSimCall(mPhone); } private void finishImsCall(int id, ImsReasonInfo reasonInfo, long durationMillis) { Loading Loading @@ -878,6 +887,21 @@ public class VoiceCallSessionStats { return conn == null ? 0 : (int) conn.getCreateTime(); } private boolean isCrossSimCall(Connection conn) { if (conn instanceof ImsPhoneConnection) { return ((ImsPhoneConnection) conn).isCrossSimCall(); } return false; } private boolean isCrossSimCall(Phone phone) { if (phone.getImsPhone() != null) { return phone.getImsPhone().getImsRegistrationTech() == ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM; } return false; } @VisibleForTesting protected long getTimeMillis() { return SystemClock.elapsedRealtime(); Loading tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java +78 −1 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.ImsStreamMediaProfile; import android.telephony.ims.stub.ImsRegistrationImplBase; import android.test.suitebuilder.annotation.SmallTest; import com.android.internal.telephony.Call; Loading Loading @@ -190,6 +191,7 @@ public class VoiceCallSessionStatsTest extends TelephonyTest { doReturn(PhoneConstants.PHONE_TYPE_IMS).when(mImsConnection0).getPhoneType(); doReturn(false).when(mImsConnection0).isEmergencyCall(); doReturn(false).when(mImsConnection0).isCrossSimCall(); doReturn(PhoneConstants.PHONE_TYPE_IMS).when(mImsConnection1).getPhoneType(); doReturn(false).when(mImsConnection1).isEmergencyCall(); doReturn(PhoneConstants.PHONE_TYPE_GSM).when(mGsmConnection0).getPhoneType(); Loading @@ -197,6 +199,9 @@ public class VoiceCallSessionStatsTest extends TelephonyTest { doReturn(PhoneConstants.PHONE_TYPE_GSM).when(mGsmConnection1).getPhoneType(); doReturn(false).when(mGsmConnection1).isEmergencyCall(); doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_LTE).when(mImsPhone) .getImsRegistrationTech(); if (Looper.myLooper() == null) { Looper.prepare(); } Loading Loading @@ -235,7 +240,6 @@ public class VoiceCallSessionStatsTest extends TelephonyTest { ImsReasonInfo.CODE_REMOTE_CALL_DECLINE); expectedCall.setupDurationMillis = 200; expectedCall.setupFailed = true; expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN; expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_EVS_SWB; expectedCall.mainCodecQuality = VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_SUPER_WIDEBAND; Loading Loading @@ -1511,6 +1515,75 @@ public class VoiceCallSessionStatsTest extends TelephonyTest { ratUsage.get()); } @Test @SmallTest public void singleCrossSimCall_moAccepted() { setServiceStateWithWifiCalling(mServiceState, TelephonyManager.NETWORK_TYPE_LTE); doReturn(mImsPhone).when(mPhone).getImsPhone(); doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM).when(mImsPhone) .getImsRegistrationTech(); doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech(); doReturn(false).when(mImsConnection0).isIncoming(); doReturn(true).when(mImsConnection0).isCrossSimCall(); doReturn(2000L).when(mImsConnection0).getCreateTime(); doReturn(1000L).when(mImsConnection0).getDurationMillis(); doReturn(mImsCall0).when(mImsConnection0).getCall(); doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections(); VoiceCallSession expectedCall = makeSlot0CallProto( VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS, VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO, TelephonyManager.NETWORK_TYPE_IWLAN, ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE); expectedCall.isIwlanCrossSimAtStart = true; expectedCall.isIwlanCrossSimAtEnd = true; expectedCall.isIwlanCrossSimAtConnected = true; expectedCall.bandAtEnd = 0; // not configured for IWLAN expectedCall.setupDurationMillis = 200; expectedCall.setupFailed = false; expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_EVS_SWB; expectedCall.mainCodecQuality = VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_SUPER_WIDEBAND; expectedCall.disconnectExtraMessage = "normal call clearing"; expectedCall.callDuration = VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_MINUTE; VoiceCallRatUsage expectedRatUsage = makeRatUsageProto( CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_IWLAN, 2000L, 100000L, 1L); final AtomicReference<VoiceCallRatUsage[]> ratUsage = setupRatUsageCapture(); mVoiceCallSessionStats0.setTimeMillis(2000L); doReturn(Call.State.DIALING).when(mImsCall0).getState(); doReturn(Call.State.DIALING).when(mImsConnection0).getState(); mVoiceCallSessionStats0.onImsDial(mImsConnection0); mVoiceCallSessionStats0.setTimeMillis(2100L); mVoiceCallSessionStats0.onAudioCodecChanged( mImsConnection0, ImsStreamMediaProfile.AUDIO_QUALITY_EVS_SWB); mVoiceCallSessionStats0.setTimeMillis(2200L); doReturn(Call.State.ALERTING).when(mImsCall0).getState(); doReturn(Call.State.ALERTING).when(mImsConnection0).getState(); mVoiceCallSessionStats0.onCallStateChanged(mImsCall0); mVoiceCallSessionStats0.setTimeMillis(12000L); doReturn(Call.State.ACTIVE).when(mImsCall0).getState(); doReturn(Call.State.ACTIVE).when(mImsConnection0).getState(); mVoiceCallSessionStats0.onCallStateChanged(mImsCall0); mVoiceCallSessionStats0.setTimeMillis(100000L); mVoiceCallSessionStats0.onImsCallTerminated( mImsConnection0, new ImsReasonInfo( ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE, 0, "normal call clearing")); ArgumentCaptor<VoiceCallSession> callCaptor = ArgumentCaptor.forClass(VoiceCallSession.class); verify(mPersistAtomsStorage, times(1)).addVoiceCallSession(callCaptor.capture()); verify(mPersistAtomsStorage, times(1)).addVoiceCallRatUsage(any()); verifyNoMoreInteractions(mPersistAtomsStorage); assertProtoEquals(expectedCall, callCaptor.getValue()); assertThat(ratUsage.get()).hasLength(1); assertProtoEquals(expectedRatUsage, ratUsage.get()[0]); } @Test @SmallTest public void singleCsCall_moRejected() { Loading Loading @@ -2512,6 +2585,8 @@ public class VoiceCallSessionStatsTest extends TelephonyTest { public void singleWifiCall_preferred() { setServiceStateWithWifiCalling(mServiceState, TelephonyManager.NETWORK_TYPE_LTE); doReturn(mImsPhone).when(mPhone).getImsPhone(); doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN).when(mImsPhone) .getImsRegistrationTech(); doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech(); doReturn(true).when(mImsConnection0).isIncoming(); doReturn(2000L).when(mImsConnection0).getCreateTime(); Loading Loading @@ -2560,6 +2635,8 @@ public class VoiceCallSessionStatsTest extends TelephonyTest { public void singleWifiCall_airPlaneMode() { setServiceStateWithWifiCalling(mServiceState, TelephonyManager.NETWORK_TYPE_UNKNOWN); doReturn(mImsPhone).when(mPhone).getImsPhone(); doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN).when(mImsPhone) .getImsRegistrationTech(); doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech(); doReturn(true).when(mImsConnection0).isIncoming(); doReturn(2000L).when(mImsConnection0).getCreateTime(); Loading Loading
proto/src/persist_atoms.proto +3 −0 Original line number Diff line number Diff line Loading @@ -277,6 +277,9 @@ message VoiceCallSession { optional int32 fold_state = 34; optional int64 rat_switch_count_after_connected = 35; optional bool handover_in_progress = 36; optional bool is_iwlan_cross_sim_at_start = 37; optional bool is_iwlan_cross_sim_at_end = 38; optional bool is_iwlan_cross_sim_at_connected = 39; // Internal use only optional int64 setup_begin_millis = 10001; Loading
src/java/com/android/internal/telephony/metrics/MetricsCollector.java +4 −1 Original line number Diff line number Diff line Loading @@ -981,7 +981,10 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback { session.lastKnownRat, session.foldState, session.ratSwitchCountAfterConnected, session.handoverInProgress); session.handoverInProgress, session.isIwlanCrossSimAtStart, session.isIwlanCrossSimAtEnd, session.isIwlanCrossSimAtConnected); } private static StatsEvent buildStatsEvent(IncomingSms sms) { Loading
src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java +25 −1 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.ImsStreamMediaProfile; import android.telephony.ims.stub.ImsRegistrationImplBase; import android.util.LongSparseArray; import android.util.SparseArray; import android.util.SparseIntArray; Loading Loading @@ -469,6 +470,11 @@ public class VoiceCallSessionStats { proto.videoEnabled = videoState != VideoProfile.STATE_AUDIO_ONLY ? true : false; proto.handoverInProgress = isHandoverInProgress(bearer, proto.isEmergency); boolean isCrossSimCall = isCrossSimCall(conn); proto.isIwlanCrossSimAtStart = isCrossSimCall; proto.isIwlanCrossSimAtEnd = isCrossSimCall; proto.isIwlanCrossSimAtConnected = isCrossSimCall; // internal fields for tracking if (getDirection(conn) == VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT) { // MT call setup hasn't begun hence set to 0 Loading Loading @@ -594,7 +600,9 @@ public class VoiceCallSessionStats { proto.setupFailed = false; // Track RAT when voice call is connected. ServiceState serviceState = getServiceState(); proto.ratAtConnected = getVoiceRatWithVoNRFix(mPhone, serviceState, proto.bearerAtEnd); @NetworkType int rat = getVoiceRatWithVoNRFix(mPhone, serviceState, proto.bearerAtEnd); proto.ratAtConnected = rat; proto.isIwlanCrossSimAtConnected = isCrossSimCall(conn); // Reset list of codecs with the last codec at the present time. In this way, we // track codec quality only after call is connected and not while ringing. resetCodecList(conn); Loading Loading @@ -631,6 +639,7 @@ public class VoiceCallSessionStats { proto.lastKnownRat = rat; } } proto.isIwlanCrossSimAtEnd = isCrossSimCall(mPhone); } private void finishImsCall(int id, ImsReasonInfo reasonInfo, long durationMillis) { Loading Loading @@ -878,6 +887,21 @@ public class VoiceCallSessionStats { return conn == null ? 0 : (int) conn.getCreateTime(); } private boolean isCrossSimCall(Connection conn) { if (conn instanceof ImsPhoneConnection) { return ((ImsPhoneConnection) conn).isCrossSimCall(); } return false; } private boolean isCrossSimCall(Phone phone) { if (phone.getImsPhone() != null) { return phone.getImsPhone().getImsRegistrationTech() == ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM; } return false; } @VisibleForTesting protected long getTimeMillis() { return SystemClock.elapsedRealtime(); Loading
tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java +78 −1 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.ImsStreamMediaProfile; import android.telephony.ims.stub.ImsRegistrationImplBase; import android.test.suitebuilder.annotation.SmallTest; import com.android.internal.telephony.Call; Loading Loading @@ -190,6 +191,7 @@ public class VoiceCallSessionStatsTest extends TelephonyTest { doReturn(PhoneConstants.PHONE_TYPE_IMS).when(mImsConnection0).getPhoneType(); doReturn(false).when(mImsConnection0).isEmergencyCall(); doReturn(false).when(mImsConnection0).isCrossSimCall(); doReturn(PhoneConstants.PHONE_TYPE_IMS).when(mImsConnection1).getPhoneType(); doReturn(false).when(mImsConnection1).isEmergencyCall(); doReturn(PhoneConstants.PHONE_TYPE_GSM).when(mGsmConnection0).getPhoneType(); Loading @@ -197,6 +199,9 @@ public class VoiceCallSessionStatsTest extends TelephonyTest { doReturn(PhoneConstants.PHONE_TYPE_GSM).when(mGsmConnection1).getPhoneType(); doReturn(false).when(mGsmConnection1).isEmergencyCall(); doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_LTE).when(mImsPhone) .getImsRegistrationTech(); if (Looper.myLooper() == null) { Looper.prepare(); } Loading Loading @@ -235,7 +240,6 @@ public class VoiceCallSessionStatsTest extends TelephonyTest { ImsReasonInfo.CODE_REMOTE_CALL_DECLINE); expectedCall.setupDurationMillis = 200; expectedCall.setupFailed = true; expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN; expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_EVS_SWB; expectedCall.mainCodecQuality = VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_SUPER_WIDEBAND; Loading Loading @@ -1511,6 +1515,75 @@ public class VoiceCallSessionStatsTest extends TelephonyTest { ratUsage.get()); } @Test @SmallTest public void singleCrossSimCall_moAccepted() { setServiceStateWithWifiCalling(mServiceState, TelephonyManager.NETWORK_TYPE_LTE); doReturn(mImsPhone).when(mPhone).getImsPhone(); doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM).when(mImsPhone) .getImsRegistrationTech(); doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech(); doReturn(false).when(mImsConnection0).isIncoming(); doReturn(true).when(mImsConnection0).isCrossSimCall(); doReturn(2000L).when(mImsConnection0).getCreateTime(); doReturn(1000L).when(mImsConnection0).getDurationMillis(); doReturn(mImsCall0).when(mImsConnection0).getCall(); doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections(); VoiceCallSession expectedCall = makeSlot0CallProto( VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS, VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO, TelephonyManager.NETWORK_TYPE_IWLAN, ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE); expectedCall.isIwlanCrossSimAtStart = true; expectedCall.isIwlanCrossSimAtEnd = true; expectedCall.isIwlanCrossSimAtConnected = true; expectedCall.bandAtEnd = 0; // not configured for IWLAN expectedCall.setupDurationMillis = 200; expectedCall.setupFailed = false; expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_EVS_SWB; expectedCall.mainCodecQuality = VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_SUPER_WIDEBAND; expectedCall.disconnectExtraMessage = "normal call clearing"; expectedCall.callDuration = VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_MINUTE; VoiceCallRatUsage expectedRatUsage = makeRatUsageProto( CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_IWLAN, 2000L, 100000L, 1L); final AtomicReference<VoiceCallRatUsage[]> ratUsage = setupRatUsageCapture(); mVoiceCallSessionStats0.setTimeMillis(2000L); doReturn(Call.State.DIALING).when(mImsCall0).getState(); doReturn(Call.State.DIALING).when(mImsConnection0).getState(); mVoiceCallSessionStats0.onImsDial(mImsConnection0); mVoiceCallSessionStats0.setTimeMillis(2100L); mVoiceCallSessionStats0.onAudioCodecChanged( mImsConnection0, ImsStreamMediaProfile.AUDIO_QUALITY_EVS_SWB); mVoiceCallSessionStats0.setTimeMillis(2200L); doReturn(Call.State.ALERTING).when(mImsCall0).getState(); doReturn(Call.State.ALERTING).when(mImsConnection0).getState(); mVoiceCallSessionStats0.onCallStateChanged(mImsCall0); mVoiceCallSessionStats0.setTimeMillis(12000L); doReturn(Call.State.ACTIVE).when(mImsCall0).getState(); doReturn(Call.State.ACTIVE).when(mImsConnection0).getState(); mVoiceCallSessionStats0.onCallStateChanged(mImsCall0); mVoiceCallSessionStats0.setTimeMillis(100000L); mVoiceCallSessionStats0.onImsCallTerminated( mImsConnection0, new ImsReasonInfo( ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE, 0, "normal call clearing")); ArgumentCaptor<VoiceCallSession> callCaptor = ArgumentCaptor.forClass(VoiceCallSession.class); verify(mPersistAtomsStorage, times(1)).addVoiceCallSession(callCaptor.capture()); verify(mPersistAtomsStorage, times(1)).addVoiceCallRatUsage(any()); verifyNoMoreInteractions(mPersistAtomsStorage); assertProtoEquals(expectedCall, callCaptor.getValue()); assertThat(ratUsage.get()).hasLength(1); assertProtoEquals(expectedRatUsage, ratUsage.get()[0]); } @Test @SmallTest public void singleCsCall_moRejected() { Loading Loading @@ -2512,6 +2585,8 @@ public class VoiceCallSessionStatsTest extends TelephonyTest { public void singleWifiCall_preferred() { setServiceStateWithWifiCalling(mServiceState, TelephonyManager.NETWORK_TYPE_LTE); doReturn(mImsPhone).when(mPhone).getImsPhone(); doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN).when(mImsPhone) .getImsRegistrationTech(); doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech(); doReturn(true).when(mImsConnection0).isIncoming(); doReturn(2000L).when(mImsConnection0).getCreateTime(); Loading Loading @@ -2560,6 +2635,8 @@ public class VoiceCallSessionStatsTest extends TelephonyTest { public void singleWifiCall_airPlaneMode() { setServiceStateWithWifiCalling(mServiceState, TelephonyManager.NETWORK_TYPE_UNKNOWN); doReturn(mImsPhone).when(mPhone).getImsPhone(); doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN).when(mImsPhone) .getImsRegistrationTech(); doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech(); doReturn(true).when(mImsConnection0).isIncoming(); doReturn(2000L).when(mImsConnection0).getCreateTime(); Loading