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

Commit 42fbe339 authored by Meng Wang's avatar Meng Wang
Browse files

Consider isRadioPowerOn before updating roaming state

Context:
ImsPhone keeps track of the last known roaming state i.e. mRoaming
state in order to decide which WFC mode to apply (home vs roaming).
The state is also used to decide if WFC prompt should be shown: it
should not be if WFC roaming is disallowed and is currently roaming.

Issue:
It's found that ServiceState can report IN_SERVICE when device in
airplane mode i.e. isRadioPowerOn=false and Wi-Fi connected. Hence
mRoaming is udpated to true, which may not be correct.

Fix:
Consider isRadioPowerOn=false as not IN_SERVICE, so do not update the
last known roaming state i.e. mRoaming.

Risk of regression:
Minimal. The WFC mode doesn't matter in airplane mode since voice over
cellular is not possible anyway.

Bug: 172975077
Test: fake roaming, turn on airplane mode + Wi-Fi: mRoaming not updated.
Change-Id: I26242d1904869265fcd5ea273ea49fb6fc6882d0
parent 60c3c11b
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -273,7 +273,7 @@ public class ImsPhone extends ImsPhoneBase {
    private ImsRegistrationCallbackHelper mImsMmTelRegistrationHelper;

    // The roaming state if currently in service, or the last roaming state when was in service.
    private boolean mRoaming = false;
    private boolean mLastKnownRoamingState = false;

    private boolean mIsInImsEcm = false;

@@ -2312,15 +2312,15 @@ public class ImsPhone extends ImsPhoneBase {
        }
        boolean newRoamingState = ss.getRoaming();
        // Do not recalculate if there is no change to state.
        if (mRoaming == newRoamingState) {
        if (mLastKnownRoamingState == newRoamingState) {
            return;
        }
        boolean isInService = (ss.getState() == ServiceState.STATE_IN_SERVICE
                || ss.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE);
        // If we are not IN_SERVICE for voice or data, ignore change roaming state, as we always
        // move to home in this case.
        if (!isInService) {
            logi("updateRoamingState: we are OUT_OF_SERVICE, ignoring roaming change.");
        if (!isInService || !mDefaultPhone.isRadioOn()) {
            logi("updateRoamingState: we are not IN_SERVICE, ignoring roaming change.");
            return;
        }
        // We ignore roaming changes when moving to IWLAN because it always sets the roaming
@@ -2334,7 +2334,7 @@ public class ImsPhone extends ImsPhoneBase {
        }
        if (mCT.getState() == PhoneConstants.State.IDLE) {
            if (DBG) logd("updateRoamingState now: " + newRoamingState);
            mRoaming = newRoamingState;
            mLastKnownRoamingState = newRoamingState;
            CarrierConfigManager configManager = (CarrierConfigManager)
                    getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
            // Don't set wfc mode if carrierconfig has not loaded. It will be set by GsmCdmaPhone
@@ -2484,8 +2484,8 @@ public class ImsPhone extends ImsPhoneBase {
                getBackgroundCall().getState() != Call.State.IDLE);
    }

    public boolean getRoamingState() {
        return mRoaming;
    public boolean getLastKnownRoamingState() {
        return mLastKnownRoamingState;
    }

    @Override
@@ -2506,7 +2506,7 @@ public class ImsPhone extends ImsPhoneBase {
        pw.println("  mSilentRedialRegistrants = " + mSilentRedialRegistrants);
        pw.println("  mImsMmTelRegistrationState = "
                + mImsMmTelRegistrationHelper.getImsRegistrationState());
        pw.println("  mRoaming = " + mRoaming);
        pw.println("  mLastKnownRoamingState = " + mLastKnownRoamingState);
        pw.println("  mSsnRegistrants = " + mSsnRegistrants);
        pw.println(" Registration Log:");
        pw.increaseIndent();
+32 −0
Original line number Diff line number Diff line
@@ -712,6 +712,7 @@ public class ImsPhoneTest extends TelephonyTest {
    @SmallTest
    public void testRoamingDuplicateMessages() throws Exception {
        doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
        doReturn(true).when(mPhone).isRadioOn();

        //roaming - data registration only on LTE
        Message m = getServiceStateChangedMessage(getServiceStateDataOnly(
@@ -729,12 +730,40 @@ public class ImsPhoneTest extends TelephonyTest {
        verify(mImsManager, times(1)).setWfcMode(anyInt(), anyBoolean());
    }

    @Test
    @SmallTest
    public void testRoamingToAirplanModeIwlanInService() throws Exception {
        doReturn(true).when(mTransportManager).isInLegacyMode();
        doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
        doReturn(true).when(mPhone).isRadioOn();

        //roaming - data registration only on LTE
        Message m = getServiceStateChangedMessage(getServiceStateDataOnly(
                ServiceState.RIL_RADIO_TECHNOLOGY_LTE, ServiceState.STATE_IN_SERVICE, true));
        // Inject the message synchronously instead of waiting for the thread to do it.
        mImsPhoneUT.handleMessage(m);
        m.recycle();

        verify(mImsManager, times(1)).setWfcMode(anyInt(), eq(true));

        // move to airplane mode + IWLAN in service
        doReturn(false).when(mPhone).isRadioOn();
        m = getServiceStateChangedMessage(getServiceStateDataOnly(
            ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN, ServiceState.STATE_IN_SERVICE, false));
        mImsPhoneUT.handleMessage(m);
        m.recycle();

        // setWfcMode should not be called again, airplane mode should not trigger move out of
        // roaming.
        verify(mImsManager, times(1)).setWfcMode(anyInt(), anyBoolean());
    }

    @Test
    @SmallTest
    public void testRoamingToOutOfService() throws Exception {
        doReturn(true).when(mTransportManager).isInLegacyMode();
        doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
        doReturn(true).when(mPhone).isRadioOn();

        //roaming - data registration only on LTE
        Message m = getServiceStateChangedMessage(getServiceStateDataOnly(
@@ -760,6 +789,7 @@ public class ImsPhoneTest extends TelephonyTest {
    public void testRoamingChangeForLteInLegacyMode() throws Exception {
        doReturn(true).when(mTransportManager).isInLegacyMode();
        doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
        doReturn(true).when(mPhone).isRadioOn();

        //roaming - data registration only on LTE
        Message m = getServiceStateChangedMessage(getServiceStateDataOnly(
@@ -784,6 +814,7 @@ public class ImsPhoneTest extends TelephonyTest {
    public void testDataOnlyRoamingCellToIWlanInLegacyMode() throws Exception {
        doReturn(true).when(mTransportManager).isInLegacyMode();
        doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
        doReturn(true).when(mPhone).isRadioOn();

        //roaming - data registration only on LTE
        Message m = getServiceStateChangedMessage(getServiceStateDataOnly(
@@ -809,6 +840,7 @@ public class ImsPhoneTest extends TelephonyTest {
    public void testCellVoiceDataChangeToWlanInLegacyMode() throws Exception {
        doReturn(true).when(mTransportManager).isInLegacyMode();
        doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
        doReturn(true).when(mPhone).isRadioOn();

        //roaming - voice/data registration on LTE
        ServiceState ss = getServiceStateDataAndVoice(