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

Commit 66d0a3d8 authored by qingqi's avatar qingqi
Browse files

Collect B2C data in voice call metric

Bug:326616369
Test: m, basic telephony tests, inspect voice call atom on device

Change-Id: I09657dbd3e81a606b9fbcfc94f2982664be562b4
parent f3dd2901
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -288,6 +288,8 @@ message VoiceCallSession {
    optional bool is_iwlan_cross_sim_at_connected = 39;
    optional bool vonr_enabled = 40;
    optional bool is_ntn = 41;
    optional bool supports_business_call_composer = 42;
    optional int32 call_composer_status = 43;

    // Internal use only
    optional int64 setup_begin_millis = 10001;
+3 −1
Original line number Diff line number Diff line
@@ -1053,7 +1053,9 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback {
                session.isIwlanCrossSimAtEnd,
                session.isIwlanCrossSimAtConnected,
                session.vonrEnabled,
                session.isNtn);
                session.isNtn,
                session.supportsBusinessCallComposer,
                session.callComposerStatus);

    }

+37 −2
Original line number Diff line number Diff line
@@ -41,16 +41,19 @@ import android.annotation.Nullable;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.PersistableBundle;
import android.os.SystemClock;
import android.telecom.VideoProfile;
import android.telecom.VideoProfile.VideoState;
import android.telephony.Annotation.NetworkType;
import android.telephony.AnomalyReporter;
import android.telephony.CarrierConfigManager;
import android.telephony.DisconnectCause;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PreciseDataConnectionState;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager.CallComposerStatus;
import android.telephony.data.ApnSetting;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.ImsStreamMediaProfile;
@@ -168,10 +171,8 @@ public class VoiceCallSessionStats {
    private final UiccController mUiccController = UiccController.getInstance();
    private final DeviceStateHelper mDeviceStateHelper =
            PhoneFactory.getMetricsCollector().getDeviceStateHelper();

    private final VonrHelper mVonrHelper =
            PhoneFactory.getMetricsCollector().getVonrHelper();

    private final SatelliteController mSatelliteController;

    public VoiceCallSessionStats(int phoneId, Phone phone, @NonNull FeatureFlags featureFlags) {
@@ -574,6 +575,10 @@ public class VoiceCallSessionStats {
            proto.vonrEnabled = mVonrHelper.getVonrEnabled(mPhone.getSubId());
        }

        proto.supportsBusinessCallComposer = isBusinessCallSupported();
        // 0 is defined as UNKNOWN in Enum
        proto.callComposerStatus = getCallComposerStatusForPhone() + 1;

        proto.isNtn = mSatelliteController != null
                ? mSatelliteController.isInSatelliteModeForCarrierRoaming(mPhone) : false;

@@ -947,6 +952,36 @@ public class VoiceCallSessionStats {
        return false;
    }

    private @CallComposerStatus int getCallComposerStatusForPhone() {
        TelephonyManager telephonyManager = mPhone.getContext()
                .getSystemService(TelephonyManager.class);
        if (telephonyManager == null) {
            return TelephonyManager.CALL_COMPOSER_STATUS_OFF;
        }
        telephonyManager = telephonyManager.createForSubscriptionId(mPhone.getSubId());
        return telephonyManager.getCallComposerStatus();
    }

    private boolean isBusinessCallSupported() {
        CarrierConfigManager carrierConfigManager = (CarrierConfigManager)
                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
        if (carrierConfigManager == null) {
            return false;
        }
        int subId = mPhone.getSubId();
        PersistableBundle b = null;
        try {
            b = carrierConfigManager.getConfigForSubId(subId,
                    CarrierConfigManager.KEY_SUPPORTS_BUSINESS_CALL_COMPOSER_BOOL);
        } catch (RuntimeException e) {
            loge("CarrierConfigLoader is not available.");
        }
        if (b == null || b.isEmpty()) {
            return false;
        }
        return b.getBoolean(CarrierConfigManager.KEY_SUPPORTS_BUSINESS_CALL_COMPOSER_BOOL);
    }

    @VisibleForTesting
    protected long getTimeMillis() {
        return SystemClock.elapsedRealtime();
+72 −1
Original line number Diff line number Diff line
@@ -50,8 +50,10 @@ import static org.mockito.Mockito.when;

import android.annotation.NonNull;
import android.os.Looper;
import android.os.PersistableBundle;
import android.telephony.AccessNetworkConstants;
import android.telephony.Annotation.NetworkType;
import android.telephony.CarrierConfigManager;
import android.telephony.DisconnectCause;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PreciseDataConnectionState;
@@ -226,7 +228,8 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {

        mVoiceCallSessionStats0 = new TestableVoiceCallSessionStats(0, mPhone, mFeatureFlags);
        mVoiceCallSessionStats0.onServiceStateChanged(mServiceState);
        mVoiceCallSessionStats1 = new TestableVoiceCallSessionStats(1, mSecondPhone, mFeatureFlags);
        mVoiceCallSessionStats1 = new TestableVoiceCallSessionStats(
                1, mSecondPhone, mFeatureFlags);
        mVoiceCallSessionStats1.onServiceStateChanged(mSecondServiceState);

        doReturn(true).when(mFeatureFlags).vonrEnabledMetric();
@@ -2787,6 +2790,72 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        assertFalse(session.isNtn);
    }


    @Test
    @SmallTest
    public void singleCall_supportBusinessCall() {
        PersistableBundle mCarrierConfig = new PersistableBundle();
        mCarrierConfig.putBoolean(
                CarrierConfigManager.KEY_SUPPORTS_BUSINESS_CALL_COMPOSER_BOOL, true);
        when(mCarrierConfigManager.getConfigForSubId(eq(mPhone.getSubId()),
                eq(CarrierConfigManager.KEY_SUPPORTS_BUSINESS_CALL_COMPOSER_BOOL)))
                        .thenReturn(mCarrierConfig);
        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mImsStats).getImsVoiceRadioTech();
        doReturn(mImsPhone).when(mPhone).getImsPhone();
        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();
        doReturn(2).when(mTelephonyManager).getCallComposerStatus();
        VoiceCallSession expectedCall =
                makeSlot0CallProto(
                        VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS,
                        VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO,
                        TelephonyManager.NETWORK_TYPE_LTE,
                        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;
        expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN;
        expectedCall.callDuration = VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
        expectedCall.supportsBusinessCallComposer = true;
        // 0 is defined as UNKNOWN, adding 1 to original value.
        expectedCall.callComposerStatus = 3;
        VoiceCallRatUsage expectedRatUsage =
                makeRatUsageProto(
                        CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 12000L, 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);
        mVoiceCallSessionStats0.onImsCallTerminated(
                mImsConnection0, new ImsReasonInfo(ImsReasonInfo.CODE_REMOTE_CALL_DECLINE, 0));

        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]);
    }

    private AtomicReference<VoiceCallRatUsage[]> setupRatUsageCapture() {
        final AtomicReference<VoiceCallRatUsage[]> ratUsage = new AtomicReference<>(null);
        doAnswer(
@@ -2875,6 +2944,7 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        call.setupBeginMillis = 0L;
        call.signalStrengthAtEnd = 2;
        call.vonrEnabled = false;
        call.callComposerStatus = 1;
        return call;
    }

@@ -2910,6 +2980,7 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        call.isRoaming = false;
        call.setupBeginMillis = 0L;
        call.signalStrengthAtEnd = 2;
        call.callComposerStatus = 1;
        return call;
    }