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

Commit c4e40f06 authored by Chi Zhang's avatar Chi Zhang Committed by Gerrit Code Review
Browse files

Merge "Use IMS registration for voice RAT stats."

parents ec7d6a54 69e548b0
Loading
Loading
Loading
Loading
+31 −12
Original line number Diff line number Diff line
@@ -35,8 +35,6 @@ import android.os.SystemClock;
import android.telephony.AccessNetworkConstants;
import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.Annotation.NetworkType;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.ProvisioningManager;
@@ -265,10 +263,24 @@ public class ImsStats {
            @ImsRegistrationTech int radioTech, MmTelCapabilities capabilities) {
        conclude();

        if (mLastRegistrationStats != null) {
            mLastRegistrationStats.rat = convertRegistrationTechToNetworkType(radioTech);
        boolean ratChanged = false;
        @NetworkType int newRat = convertRegistrationTechToNetworkType(radioTech);
        if (mLastRegistrationStats != null && mLastRegistrationStats.rat != newRat) {
            mLastRegistrationStats.rat = newRat;
            ratChanged = true;
        }

        boolean voiceAvailableNow = capabilities.isCapable(CAPABILITY_TYPE_VOICE);
        boolean voiceAvailabilityChanged =
                (mLastAvailableFeatures.isCapable(CAPABILITY_TYPE_VOICE) != voiceAvailableNow);
        mLastAvailableFeatures = capabilities;

        // Notify voice RAT change if 1. RAT changed while voice over IMS is available, or 2. voice
        // over IMS availability changed
        if ((ratChanged && voiceAvailableNow) || voiceAvailabilityChanged) {
            mPhone.getDefaultPhone().getServiceStateTracker().getServiceStateStats()
                    .onImsVoiceRegistrationChanged();
        }
    }

    /** Updates the stats when capable features changed. */
@@ -335,6 +347,20 @@ public class ImsStats {
        mLastAvailableFeatures = new MmTelCapabilities();
    }

    /**
     * Returns the current RAT used for IMS voice registration, or {@link
     * TelephonyManager#NETWORK_TYPE_UNKNOWN} if there isn't any.
     */
    @NetworkType
    @VisibleForTesting
    public synchronized int getImsVoiceRadioTech() {
        if (mLastRegistrationStats == null
                || !mLastAvailableFeatures.isCapable(CAPABILITY_TYPE_VOICE)) {
            return TelephonyManager.NETWORK_TYPE_UNKNOWN;
        }
        return mLastRegistrationStats.rat;
    }

    @NetworkType
    private int getRatAtEnd(@NetworkType int lastStateRat) {
        return lastStateRat == TelephonyManager.NETWORK_TYPE_IWLAN ? lastStateRat : getWwanPsRat();
@@ -354,14 +380,7 @@ public class ImsStats {

    @NetworkType
    private int getWwanPsRat() {
        ServiceState state = mPhone.getServiceStateTracker().getServiceState();
        final NetworkRegistrationInfo wwanRegInfo =
                state.getNetworkRegistrationInfo(
                        NetworkRegistrationInfo.DOMAIN_PS,
                        AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
        return wwanRegInfo != null
                ? wwanRegInfo.getAccessNetworkTechnology()
                : TelephonyManager.NETWORK_TYPE_UNKNOWN;
        return ServiceStateStats.getDataRat(mPhone.getServiceStateTracker().getServiceState());
    }

    private ImsRegistrationStats getDefaultImsRegistrationStats() {
+30 −9
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.nano.PersistAtomsProto.CellularDataServiceSwitch;
import com.android.internal.telephony.nano.PersistAtomsProto.CellularServiceState;
import com.android.telephony.Rlog;
@@ -58,6 +59,23 @@ public class ServiceStateStats {
        addServiceState(lastState, now);
    }

    /** Updates service state when IMS voice registration changes. */
    public void onImsVoiceRegistrationChanged() {
        final long now = getTimeMillis();
        TimestampedServiceState lastState =
                mLastState.getAndUpdate(
                        state -> {
                            if (state.mServiceState == null) {
                                return new TimestampedServiceState(null, now);
                            }
                            CellularServiceState newServiceState = copyOf(state.mServiceState);
                            newServiceState.voiceRat =
                                    getVoiceRat(mPhone, getServiceStateForPhone(mPhone));
                            return new TimestampedServiceState(newServiceState, now);
                        });
        addServiceState(lastState, now);
    }

    /** Updates the current service state. */
    public void onServiceStateChanged(ServiceState serviceState) {
        final long now = getTimeMillis();
@@ -209,18 +227,21 @@ public class ServiceStateStats {
    }

    /**
     * Returns the current voice RAT from the service state, or {@link
     * TelephonyManager#NETWORK_TYPE_IWLAN} if the phone has Wifi calling in use.
     * Returns the current voice RAT from IMS registration if present, otherwise from the service
     * state.
     */
    public static @NetworkType int getVoiceRat(Phone phone, @Nullable ServiceState state) {
    static @NetworkType int getVoiceRat(Phone phone, @Nullable ServiceState state) {
        if (state == null) {
            return TelephonyManager.NETWORK_TYPE_UNKNOWN;
        }
        boolean isWifiCall =
                phone.getImsPhone() != null
                        && phone.getImsPhone().isWifiCallingEnabled()
                        && state.getDataNetworkType() == TelephonyManager.NETWORK_TYPE_IWLAN;
        return isWifiCall ? TelephonyManager.NETWORK_TYPE_IWLAN : state.getVoiceNetworkType();
        ImsPhone imsPhone = (ImsPhone) phone.getImsPhone();
        if (imsPhone != null) {
            @NetworkType int imsVoiceRat = imsPhone.getImsStats().getImsVoiceRadioTech();
            if (imsVoiceRat != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
                return imsVoiceRat;
            }
        }
        return state.getVoiceNetworkType();
    }

    /**
@@ -237,7 +258,7 @@ public class ServiceStateStats {
    }

    /** Returns PS (data) RAT used by WWAN. */
    private static @NetworkType int getDataRat(ServiceState state) {
    static @NetworkType int getDataRat(ServiceState state) {
        final NetworkRegistrationInfo wwanRegInfo =
                state.getNetworkRegistrationInfo(
                        NetworkRegistrationInfo.DOMAIN_PS,
+141 −0
Original line number Diff line number Diff line
@@ -25,11 +25,13 @@ import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPAB
import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE;
import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN;
import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_LTE;
import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_NR;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -76,6 +78,7 @@ public class ImsStatsTest extends TelephonyTest {
    @Mock private UiccSlot mPhysicalSlot1;
    @Mock private Phone mSecondPhone;
    @Mock private ImsPhone mSecondImsPhone;
    @Mock private ServiceStateStats mServiceStateStats;

    private TestableImsStats mImsStats;

@@ -109,6 +112,7 @@ public class ImsStatsTest extends TelephonyTest {
        doReturn(CARRIER1_ID).when(mPhone).getCarrierId();
        doReturn(mImsPhone).when(mPhone).getImsPhone();
        doReturn(mSST).when(mImsPhone).getServiceStateTracker();
        doReturn(mServiceStateStats).when(mSST).getServiceStateStats();

        // WWAN PS RAT is LTE
        doReturn(
@@ -338,6 +342,86 @@ public class ImsStatsTest extends TelephonyTest {
        assertEquals(0L, stats.smsCapableMillis);
        assertEquals(0L, stats.smsAvailableMillis);
        verifyNoMoreInteractions(mPersistAtomsStorage);
        // ServiceStateStats should be notified
        verify(mServiceStateStats).onImsVoiceRegistrationChanged();
    }

    @Test
    @SmallTest
    public void onImsCapabilitiesChanged_differentTech() throws Exception {
        mImsStats.onSetFeatureResponse(
                CAPABILITY_TYPE_VOICE,
                REGISTRATION_TECH_LTE,
                ProvisioningManager.PROVISIONING_VALUE_ENABLED);
        mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
        mImsStats.onImsCapabilitiesChanged(
                REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));

        verify(mServiceStateStats).onImsVoiceRegistrationChanged();

        mImsStats.incTimeMillis(2000L);
        mImsStats.onImsCapabilitiesChanged(
                REGISTRATION_TECH_NR, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));

        // Atom with previous feature availability should be generated
        ArgumentCaptor<ImsRegistrationStats> captor =
                ArgumentCaptor.forClass(ImsRegistrationStats.class);
        verify(mPersistAtomsStorage).addImsRegistrationStats(captor.capture());
        ImsRegistrationStats stats = captor.getValue();
        assertEquals(CARRIER1_ID, stats.carrierId);
        assertEquals(0, stats.simSlotIndex);
        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, stats.rat);
        assertEquals(2000L, stats.registeredMillis);
        assertEquals(2000L, stats.voiceCapableMillis);
        assertEquals(2000L, stats.voiceAvailableMillis);
        assertEquals(0L, stats.videoCapableMillis);
        assertEquals(0L, stats.videoAvailableMillis);
        assertEquals(0L, stats.utCapableMillis);
        assertEquals(0L, stats.utAvailableMillis);
        assertEquals(0L, stats.smsCapableMillis);
        assertEquals(0L, stats.smsAvailableMillis);
        verifyNoMoreInteractions(mPersistAtomsStorage);
        // ServiceStateStats should be notified
        verify(mServiceStateStats, times(2)).onImsVoiceRegistrationChanged();
    }

    @Test
    @SmallTest
    public void onImsCapabilitiesChanged_differentTechNoVoice() throws Exception {
        mImsStats.onSetFeatureResponse(
                CAPABILITY_TYPE_SMS,
                REGISTRATION_TECH_LTE,
                ProvisioningManager.PROVISIONING_VALUE_ENABLED);
        mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
        mImsStats.onImsCapabilitiesChanged(
                REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_SMS));

        verify(mServiceStateStats, never()).onImsVoiceRegistrationChanged();

        mImsStats.incTimeMillis(2000L);
        mImsStats.onImsCapabilitiesChanged(
                REGISTRATION_TECH_NR, new MmTelCapabilities(CAPABILITY_TYPE_SMS));

        // Atom with previous feature availability should be generated
        ArgumentCaptor<ImsRegistrationStats> captor =
                ArgumentCaptor.forClass(ImsRegistrationStats.class);
        verify(mPersistAtomsStorage).addImsRegistrationStats(captor.capture());
        ImsRegistrationStats stats = captor.getValue();
        assertEquals(CARRIER1_ID, stats.carrierId);
        assertEquals(0, stats.simSlotIndex);
        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, stats.rat);
        assertEquals(2000L, stats.registeredMillis);
        assertEquals(0L, stats.voiceCapableMillis);
        assertEquals(0L, stats.voiceAvailableMillis);
        assertEquals(0L, stats.videoCapableMillis);
        assertEquals(0L, stats.videoAvailableMillis);
        assertEquals(0L, stats.utCapableMillis);
        assertEquals(0L, stats.utAvailableMillis);
        assertEquals(2000L, stats.smsCapableMillis);
        assertEquals(2000L, stats.smsAvailableMillis);
        verifyNoMoreInteractions(mPersistAtomsStorage);
        // ServiceStateStats should not be notified
        verify(mServiceStateStats, never()).onImsVoiceRegistrationChanged();
    }

    @Test
@@ -722,4 +806,61 @@ public class ImsStatsTest extends TelephonyTest {
        assertEquals("Timeout", termination.extraMessage);
        verifyNoMoreInteractions(mPersistAtomsStorage);
    }

    @Test
    @SmallTest
    public void getImsVoiceRadioTech_noRegistration() throws Exception {
        // Do nothing

        assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, mImsStats.getImsVoiceRadioTech());
    }

    @Test
    @SmallTest
    public void getImsVoiceRadioTech_noVoiceRegistration() throws Exception {
        mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
        mImsStats.onImsCapabilitiesChanged(
                REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_SMS));

        assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, mImsStats.getImsVoiceRadioTech());
    }

    @Test
    @SmallTest
    public void getImsVoiceRadioTech_cellularRegistration() throws Exception {
        mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
        mImsStats.onImsCapabilitiesChanged(
                REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));

        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, mImsStats.getImsVoiceRadioTech());
    }

    @Test
    @SmallTest
    public void getImsVoiceRadioTech_wifiRegistration() throws Exception {
        mImsStats.onImsRegistered(TRANSPORT_TYPE_WLAN);
        mImsStats.onImsCapabilitiesChanged(
                REGISTRATION_TECH_IWLAN, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));

        assertEquals(TelephonyManager.NETWORK_TYPE_IWLAN, mImsStats.getImsVoiceRadioTech());
    }

    @Test
    @SmallTest
    public void getImsVoiceRadioTech_unregistered() throws Exception {
        mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
        mImsStats.onImsCapabilitiesChanged(
                REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));
        mImsStats.onImsUnregistered(
                new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR, 999, "Timeout"));
        doReturn(
                        new NetworkRegistrationInfo.Builder()
                                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_UMTS)
                                .build())
                .when(mServiceState)
                .getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN);


        assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, mImsStats.getImsVoiceRadioTech());
    }
}
+2 −3
Original line number Diff line number Diff line
@@ -192,7 +192,7 @@ public class ServiceStateStatsTest extends TelephonyTest {
        doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mServiceState).getVoiceNetworkType();
        doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mServiceState).getDataNetworkType();
        mockWwanPsRat(TelephonyManager.NETWORK_TYPE_UNKNOWN);
        doReturn(true).when(mImsPhone).isWifiCallingEnabled();
        doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech();
        mServiceStateStats.onServiceStateChanged(mServiceState);

        mServiceStateStats.incTimeMillis(100L);
@@ -395,7 +395,7 @@ public class ServiceStateStatsTest extends TelephonyTest {
        mServiceStateStats.incTimeMillis(100L);
        // Voice RAT changes to IWLAN and data RAT stays in LTE according to WWAN PS RAT
        doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mServiceState).getDataNetworkType();
        doReturn(true).when(mImsPhone).isWifiCallingEnabled();
        doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech();
        mServiceStateStats.onServiceStateChanged(mServiceState);
        mServiceStateStats.incTimeMillis(100L);

@@ -433,7 +433,6 @@ public class ServiceStateStatsTest extends TelephonyTest {
    public void update_iwlanButNotWifiCalling() throws Exception {
        // Using default service state for LTE as WWAN PS RAT
        doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mServiceState).getDataNetworkType();
        doReturn(false).when(mImsPhone).isWifiCallingEnabled();

        mServiceStateStats.onServiceStateChanged(mServiceState);

+2 −2
Original line number Diff line number Diff line
@@ -1907,7 +1907,7 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
    public void singleWifiCall_preferred() {
        setServiceStateWithWifiCalling(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
        doReturn(mImsPhone).when(mPhone).getImsPhone();
        doReturn(true).when(mImsPhone).isWifiCallingEnabled();
        doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech();
        doReturn(true).when(mImsConnection0).isIncoming();
        doReturn(2000L).when(mImsConnection0).getCreateTime();
        doReturn(mImsCall0).when(mImsConnection0).getCall();
@@ -1955,7 +1955,7 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
    public void singleWifiCall_airPlaneMode() {
        setServiceStateWithWifiCalling(mServiceState, TelephonyManager.NETWORK_TYPE_UNKNOWN);
        doReturn(mImsPhone).when(mPhone).getImsPhone();
        doReturn(true).when(mImsPhone).isWifiCallingEnabled();
        doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech();
        doReturn(true).when(mImsConnection0).isIncoming();
        doReturn(2000L).when(mImsConnection0).getCreateTime();
        doReturn(mImsCall0).when(mImsConnection0).getCall();