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

Commit 3af582ba authored by Michele Berionne's avatar Michele Berionne
Browse files

Add metrics for audio codec during voice calls

Expand existing Telephony metrics to include information on the codec
used during voice calls, including also all renegotiation of the audio
codec during a voice call.

Bug: 119871674
Test: Verified dumping metrics after several calls on CS and IMS
Change-Id: I5de7910e1c1eb69cd9f4351ada040f180b1d6d4a
Merged-In: Ia1c87d8890cf00055f09b883daea08ab84cf9c80
parent 099b5d9a
Loading
Loading
Loading
Loading
+53 −0
Original line number Original line Diff line number Diff line
@@ -1070,6 +1070,9 @@ message TelephonyCallSession {


      // System time overwritten by NITZ (Network time)
      // System time overwritten by NITZ (Network time)
      NITZ_TIME = 21;
      NITZ_TIME = 21;

      // Change of audio codec
      AUDIO_CODEC = 22;
    }
    }


    enum RilRequest {
    enum RilRequest {
@@ -1162,6 +1165,53 @@ message TelephonyCallSession {
      CALL_DISCONNECTING = 9;
      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
    // The information about a voice call
    message RilCall {
    message RilCall {


@@ -1269,6 +1319,9 @@ message TelephonyCallSession {


    // NITZ time in milliseconds
    // NITZ time in milliseconds
    optional int64 nitz_timestamp_millis = 21;
    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,
  // Time when call has started, in minutes since epoch,
+12 −0
Original line number Original line Diff line number Diff line
@@ -33,6 +33,7 @@ import android.text.TextUtils;


import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
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.IccCardApplicationStatus.AppState;
import com.android.internal.telephony.uicc.UiccCardApplication;
import com.android.internal.telephony.uicc.UiccCardApplication;


@@ -75,6 +76,11 @@ public class GsmCdmaConnection extends Connection {
    // The cached delay to be used between DTMF tones fetched from carrier config.
    // The cached delay to be used between DTMF tones fetched from carrier config.
    private int mDtmfToneDelay = 0;
    private int mDtmfToneDelay = 0;


    // Store the current audio codec
    private int mAudioCodec = DriverCall.AUDIO_QUALITY_UNSPECIFIED;

    private TelephonyMetrics mMetrics = TelephonyMetrics.getInstance();

    //***** Event Constants
    //***** Event Constants
    static final int EVENT_DTMF_DONE = 1;
    static final int EVENT_DTMF_DONE = 1;
    static final int EVENT_PAUSE_DONE = 2;
    static final int EVENT_PAUSE_DONE = 2;
@@ -654,6 +660,12 @@ public class GsmCdmaConnection extends Connection {
            changed = true;
            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 ""
        // A null cnapName should be the same as ""
        if (TextUtils.isEmpty(dc.name)) {
        if (TextUtils.isEmpty(dc.name)) {
            if (!TextUtils.isEmpty(mCnapName)) {
            if (!TextUtils.isEmpty(mCnapName)) {
+12 −0
Original line number Original line Diff line number Diff line
@@ -46,6 +46,7 @@ import com.android.internal.telephony.Connection;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.UUSInfo;
import com.android.internal.telephony.UUSInfo;
import com.android.internal.telephony.metrics.TelephonyMetrics;


import java.util.Objects;
import java.util.Objects;


@@ -64,6 +65,7 @@ public class ImsPhoneConnection extends Connection implements
    private ImsPhoneCall mParent;
    private ImsPhoneCall mParent;
    private ImsCall mImsCall;
    private ImsCall mImsCall;
    private Bundle mExtras = new Bundle();
    private Bundle mExtras = new Bundle();
    private TelephonyMetrics mMetrics = TelephonyMetrics.getInstance();


    private boolean mDisconnected;
    private boolean mDisconnected;


@@ -123,6 +125,9 @@ public class ImsPhoneConnection extends Connection implements
     */
     */
    private boolean mIsVideoEnabled = true;
    private boolean mIsVideoEnabled = true;


    // Store the current audio codec
    private int mAudioCodec = ImsStreamMediaProfile.AUDIO_QUALITY_NONE;

    //***** Event Constants
    //***** Event Constants
    private static final int EVENT_DTMF_DONE = 1;
    private static final int EVENT_DTMF_DONE = 1;
    private static final int EVENT_PAUSE_DONE = 2;
    private static final int EVENT_PAUSE_DONE = 2;
@@ -955,6 +960,13 @@ public class ImsPhoneConnection extends Connection implements
                changed = true;
                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 =
            int newAudioQuality =
                    getAudioQualityFromCallProfile(localCallProfile, remoteCallProfile);
                    getAudioQualityFromCallProfile(localCallProfile, remoteCallProfile);
            if (getAudioQuality() != newAudioQuality) {
            if (getAudioQuality() != newAudioQuality) {
+6 −0
Original line number Original line Diff line number Diff line
@@ -130,4 +130,10 @@ public class CallSessionEventBuilder {
        mEvent.calls = rilCalls;
        mEvent.calls = rilCalls;
        return this;
        return this;
    }
    }

    /** Set the audio codec. */
    public CallSessionEventBuilder setAudioCodec(int audioCodec) {
        mEvent.audioCodec = audioCodec;
        return this;
    }
}
}
+138 −0
Original line number Original line Diff line number Diff line
@@ -45,14 +45,17 @@ import android.telephony.TelephonyHistogram;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager;
import android.telephony.data.DataCallResponse;
import android.telephony.data.DataCallResponse;
import android.telephony.data.DataService;
import android.telephony.data.DataService;
import android.telephony.ims.ImsCallProfile;
import android.telephony.ims.ImsCallSession;
import android.telephony.ims.ImsCallSession;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.ImsStreamMediaProfile;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Base64;
import android.util.SparseArray;
import android.util.SparseArray;


import com.android.internal.telephony.DriverCall;
import com.android.internal.telephony.GsmCdmaConnection;
import com.android.internal.telephony.GsmCdmaConnection;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.RIL;
import com.android.internal.telephony.RIL;
@@ -297,6 +300,8 @@ public class TelephonyMetrics {
                return "PHONE_STATE_CHANGED";
                return "PHONE_STATE_CHANGED";
            case TelephonyCallSession.Event.Type.NITZ_TIME:
            case TelephonyCallSession.Event.Type.NITZ_TIME:
                return "NITZ_TIME";
                return "NITZ_TIME";
            case TelephonyCallSession.Event.Type.AUDIO_CODEC:
                return "AUDIO_CODEC";
            default:
            default:
                return Integer.toString(event);
                return Integer.toString(event);
        }
        }
@@ -386,6 +391,9 @@ public class TelephonyMetrics {
                                + " isMultiparty = " + call.isMultiparty);
                                + " isMultiparty = " + call.isMultiparty);
                    }
                    }
                    pw.decreaseIndent();
                    pw.decreaseIndent();
                } else if (event.type == TelephonyCallSession.Event.Type.AUDIO_CODEC) {
                    pw.println(callSessionEventToString(event.type)
                            + "(" + event.audioCodec + ")");
                } else {
                } else {
                    pw.println(callSessionEventToString(event.type));
                    pw.println(callSessionEventToString(event.type));
                }
                }
@@ -1867,6 +1875,136 @@ public class TelephonyMetrics {
        addTelephonyEvent(event);
        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
    //TODO: Expand the proto in the future
    public void writeOnImsCallProgressing(int phoneId, ImsCallSession session) {}
    public void writeOnImsCallProgressing(int phoneId, ImsCallSession session) {}
    public void writeOnImsCallStarted(int phoneId, ImsCallSession session) {}
    public void writeOnImsCallStarted(int phoneId, ImsCallSession session) {}