Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c658275b authored by Kiwon Park's avatar Kiwon Park Committed by Automerger Merge Worker
Browse files

Merge "Add durations to voice call metrics" am: 8d8f7ee8

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/2037465

Change-Id: I4473015c5016a67d32a6cf334b2252eedbe2a6c2
parents fc0c5ca9 8d8f7ee8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -212,7 +212,7 @@ message VoiceCallSession {
    optional bool video_enabled = 29;
    optional int32 rat_at_connected = 30;
    optional bool is_multiparty = 31;

    optional int32 call_duration = 32;
    // Internal use only
    optional int64 setup_begin_millis = 10001;
}
+2 −1
Original line number Diff line number Diff line
@@ -714,7 +714,8 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback {
                session.mainCodecQuality,
                session.videoEnabled,
                session.ratAtConnected,
                session.isMultiparty);
                session.isMultiparty,
                session.callDuration);
    }

    private static StatsEvent buildStatsEvent(IncomingSms sms) {
+59 −4
Original line number Diff line number Diff line
@@ -19,6 +19,13 @@ package com.android.internal.telephony.metrics;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_UNKNOWN;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_FIVE_MINUTES;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_HOUR;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_MINUTE;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_TEN_MINUTES;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_THIRTY_MINUTES;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_MORE_THAN_ONE_HOUR;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_FULLBAND;
@@ -94,6 +101,13 @@ public class VoiceCallSessionStats {
    private static final int CALL_SETUP_DURATION_ULTRA_SLOW = 10000;
    // CALL_SETUP_DURATION_EXTREMELY_SLOW has no upper bound (it includes everything above 10000)

    // Upper bounds of each call duration category in milliseconds.
    private static final int CALL_DURATION_ONE_MINUTE = 60000;
    private static final int CALL_DURATION_FIVE_MINUTES = 300000;
    private static final int CALL_DURATION_TEN_MINUTES = 600000;
    private static final int CALL_DURATION_THIRTY_MINUTES = 1800000;
    private static final int CALL_DURATION_ONE_HOUR = 3600000;

    /** Number of buckets for codec quality, from UNKNOWN to FULLBAND. */
    private static final int CODEC_QUALITY_COUNT = 5;

@@ -114,6 +128,9 @@ public class VoiceCallSessionStats {
    /** Holds setup duration buckets with values as their upper bounds in milliseconds. */
    private static final SparseIntArray CALL_SETUP_DURATION_MAP = buildCallSetupDurationMap();

    /** Holds call duration buckets with values as their upper bounds in milliseconds. */
    private static final SparseIntArray CALL_DURATION_MAP = buildCallDurationMap();

    /**
     * Tracks statistics for each call connection, indexed with ID returned by {@link
     * #getConnectionId}.
@@ -189,6 +206,7 @@ public class VoiceCallSessionStats {
                    proto.disconnectReasonCode = conn.getDisconnectCause();
                    proto.disconnectExtraCode = conn.getPreciseDisconnectCause();
                    proto.disconnectExtraMessage = conn.getVendorDisconnectCause();
                    proto.callDuration = classifyCallDuration(conn.getDurationMillis());
                    finishCall(id);
                }
            }
@@ -229,19 +247,19 @@ public class VoiceCallSessionStats {
            List<Integer> imsConnIds = getImsConnectionIds();
            if (imsConnIds.size() == 1) {
                loge("onImsCallTerminated: ending IMS call w/ conn=null");
                finishImsCall(imsConnIds.get(0), reasonInfo);
                finishImsCall(imsConnIds.get(0), reasonInfo, 0);
            } else {
                loge("onImsCallTerminated: %d IMS calls w/ conn=null", imsConnIds.size());
            }
        } else {
            int id = getConnectionId(conn);
            if (mCallProtos.contains(id)) {
                finishImsCall(id, reasonInfo);
                finishImsCall(id, reasonInfo, conn.getDurationMillis());
            } else {
                loge("onImsCallTerminated: untracked connection, connectionId=%d", id);
                // fake a call so at least some info can be tracked
                addCall(conn);
                finishImsCall(id, reasonInfo);
                finishImsCall(id, reasonInfo, conn.getDurationMillis());
            }
        }
    }
@@ -557,12 +575,13 @@ public class VoiceCallSessionStats {
        }
    }

    private void finishImsCall(int id, ImsReasonInfo reasonInfo) {
    private void finishImsCall(int id, ImsReasonInfo reasonInfo, long durationMillis) {
        VoiceCallSession proto = mCallProtos.get(id);
        proto.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
        proto.disconnectReasonCode = reasonInfo.mCode;
        proto.disconnectExtraCode = reasonInfo.mExtraCode;
        proto.disconnectExtraMessage = ImsStats.filterExtraMessage(reasonInfo.mExtraMessage);
        proto.callDuration = classifyCallDuration(durationMillis);
        finishCall(id);
    }

@@ -737,6 +756,19 @@ public class VoiceCallSessionStats {
        return VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_SLOW;
    }

    private static int classifyCallDuration(long durationMillis) {
        if (durationMillis == 0L) {
            return VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
        }
        // keys in CALL_SETUP_DURATION_MAP are upper bounds in ascending order
        for (int i = 0; i < CALL_DURATION_MAP.size(); i++) {
            if (durationMillis < CALL_DURATION_MAP.keyAt(i)) {
                return CALL_DURATION_MAP.valueAt(i);
            }
        }
        return VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_MORE_THAN_ONE_HOUR;
    }

    /**
     * Generates an ID for each connection, which should be the same for IMS and CS connections
     * involved in the same SRVCC.
@@ -836,4 +868,27 @@ public class VoiceCallSessionStats {

        return map;
    }

    private static SparseIntArray buildCallDurationMap() {
        SparseIntArray map = new SparseIntArray();

        map.put(
                CALL_DURATION_ONE_MINUTE,
                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_MINUTE);
        map.put(
                CALL_DURATION_FIVE_MINUTES,
                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_FIVE_MINUTES);
        map.put(
                CALL_DURATION_TEN_MINUTES,
                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_TEN_MINUTES);
        map.put(
                CALL_DURATION_THIRTY_MINUTES,
                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_THIRTY_MINUTES);
        map.put(
                CALL_DURATION_ONE_HOUR,
                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_HOUR);
        // anything above would be MORE_THAN_ONE_HOUR

        return map;
    }
}
+31 −0
Original line number Diff line number Diff line
@@ -18,6 +18,13 @@ package com.android.internal.telephony.metrics;

import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_FIVE_MINUTES;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_HOUR;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_MINUTE;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_TEN_MINUTES;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_THIRTY_MINUTES;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_MORE_THAN_ONE_HOUR;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
@@ -194,6 +201,7 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
        doReturn(false).when(mImsConnection0).isIncoming();
        doReturn(2000L).when(mImsConnection0).getCreateTime();
        doReturn(0L).when(mImsConnection0).getDurationMillis();
        doReturn(mImsCall0).when(mImsConnection0).getCall();
        doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections();
        VoiceCallSession expectedCall =
@@ -211,6 +219,7 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        expectedCall.mainCodecQuality =
                VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_SUPER_WIDEBAND;
        expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN;
        expectedCall.callDuration = VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
        VoiceCallRatUsage expectedRatUsage =
                makeRatUsageProto(
                        CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 12000L, 1L);
@@ -247,6 +256,7 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
        doReturn(false).when(mImsConnection0).isIncoming();
        doReturn(2000L).when(mImsConnection0).getCreateTime();
        doReturn(0L).when(mImsConnection0).getDurationMillis();
        doReturn(mImsCall0).when(mImsConnection0).getCall();
        doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections();
        VoiceCallSession expectedCall =
@@ -257,6 +267,7 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
                        ImsReasonInfo.CODE_SIP_FORBIDDEN);
        expectedCall.setupFailed = true;
        expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN;
        expectedCall.callDuration = VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
        VoiceCallRatUsage expectedRatUsage =
                makeRatUsageProto(
                        CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 2200L, 1L);
@@ -286,6 +297,7 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
        doReturn(false).when(mImsConnection0).isIncoming();
        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 =
@@ -302,6 +314,8 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        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_LTE, 2000L, 100000L, 1L);
@@ -344,6 +358,7 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
        doReturn(true).when(mImsConnection0).isIncoming();
        doReturn(2000L).when(mImsConnection0).getCreateTime();
        doReturn(0L).when(mImsConnection0).getDurationMillis();
        doReturn(mImsCall0).when(mImsConnection0).getCall();
        doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections();
        VoiceCallSession expectedCall =
@@ -357,6 +372,7 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
        expectedCall.mainCodecQuality =
                VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
        expectedCall.callDuration = VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
        VoiceCallRatUsage expectedRatUsage =
                makeRatUsageProto(
                        CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 8000L, 1L);
@@ -390,6 +406,7 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        doReturn(true).when(mImsConnection0).isIncoming();
        doReturn(2000L).when(mImsConnection0).getCreateTime();
        doReturn(mImsCall0).when(mImsConnection0).getCall();
        doReturn(60006L).when(mImsConnection0).getDurationMillis();
        doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections();
        VoiceCallSession expectedCall =
                makeSlot0CallProto(
@@ -404,6 +421,8 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
        expectedCall.mainCodecQuality =
                VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
        expectedCall.callDuration =
                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_FIVE_MINUTES;
        VoiceCallRatUsage expectedRatUsage =
                makeRatUsageProto(
                        CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 12000L, 1L);
@@ -658,6 +677,7 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
        doReturn(true).when(mImsConnection0).isIncoming();
        doReturn(2000L).when(mImsConnection0).getCreateTime();
        doReturn(300000L).when(mImsConnection0).getDurationMillis();
        doReturn(mImsCall0).when(mImsConnection0).getCall();
        doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections();
        VoiceCallSession expectedCall =
@@ -674,6 +694,8 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
                1L << AudioCodec.AUDIO_CODEC_AMR | 1L << AudioCodec.AUDIO_CODEC_EVS_SWB;
        expectedCall.mainCodecQuality =
                VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
        expectedCall.callDuration =
                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_TEN_MINUTES;

        mVoiceCallSessionStats0.setTimeMillis(2000L);
        doReturn(Call.State.INCOMING).when(mImsCall0).getState();
@@ -709,6 +731,7 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
        doReturn(true).when(mImsConnection0).isIncoming();
        doReturn(2000L).when(mImsConnection0).getCreateTime();
        doReturn(600001L).when(mImsConnection0).getDurationMillis();
        doReturn(mImsCall0).when(mImsConnection0).getCall();
        doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections();
        VoiceCallSession expectedCall =
@@ -727,6 +750,8 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        expectedCall.ratSwitchCount = 2L;
        expectedCall.ratAtEnd = TelephonyManager.NETWORK_TYPE_UMTS;
        expectedCall.bandAtEnd = 0;
        expectedCall.callDuration =
                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_THIRTY_MINUTES;
        VoiceCallRatUsage expectedRatUsageLte =
                makeRatUsageProto(
                        CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 4000L, 1L);
@@ -781,6 +806,7 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        doReturn(true).when(mImsConnection0).isIncoming();
        doReturn(2000L).when(mImsConnection0).getCreateTime();
        doReturn(true).when(mImsConnection0).hasRttTextStream();
        doReturn(1800001L).when(mImsConnection0).getDurationMillis();
        doReturn(mImsCall0).when(mImsConnection0).getCall();
        doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections();
        VoiceCallSession expectedCall =
@@ -795,6 +821,8 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        expectedCall.mainCodecQuality =
                VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
        expectedCall.rttEnabled = true;
        expectedCall.callDuration =
                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_HOUR;

        mVoiceCallSessionStats0.setTimeMillis(2000L);
        doReturn(Call.State.INCOMING).when(mImsCall0).getState();
@@ -822,6 +850,7 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        doReturn(true).when(mImsConnection0).isIncoming();
        doReturn(2000L).when(mImsConnection0).getCreateTime();
        doReturn(mImsCall0).when(mImsConnection0).getCall();
        doReturn(3600005L).when(mImsConnection0).getDurationMillis();
        doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections();
        VoiceCallSession expectedCall =
                makeSlot0CallProto(
@@ -837,6 +866,8 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        expectedCall.mainCodecQuality =
                VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
        expectedCall.rttEnabled = true;
        expectedCall.callDuration =
                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_MORE_THAN_ONE_HOUR;

        mVoiceCallSessionStats0.setTimeMillis(2000L);
        doReturn(Call.State.INCOMING).when(mImsCall0).getState();