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

Commit 8d8f7ee8 authored by Kiwon Park's avatar Kiwon Park Committed by Gerrit Code Review
Browse files

Merge "Add durations to voice call metrics"

parents 9df7f40a 2ab58bbd
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();