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

Commit 266a8263 authored by Sarah Chin's avatar Sarah Chin
Browse files

NR connected idle state handles both NR/NR advanced

1. In order to support the NR idle timer properly, the device needs to
   transition to NR idle state when the PCC list is empty regardless of
   if it's NR advanced or not.
2. Since NR idle state icon can be either 5G/5G+, update primary timer
   reset logic to be based on the state instead of the icon.
3. If there is already a primary timer running, ignore subsequent
   primary timers until the first one expires.
4. Remove the timer check in idle state PCI change condition, since this
   was added for an obsolete idle <-> connected idle timer.
5. Fix minor bug initialization and timer reset for idle mode.

Test: atest NetworkTypeControllerTest
Bug: 314349757
Change-Id: Idcd0c77fae1b113c89b9e928ab4e13d1d6400058
parent d7deae04
Loading
Loading
Loading
Loading
+48 −51
Original line number Diff line number Diff line
@@ -378,6 +378,9 @@ public class NetworkTypeController extends StateMachine {
        createTimerRules(nrIconConfiguration, overrideTimerRule, overrideSecondaryTimerRule);
        updatePhysicalChannelConfigs(
                mPhone.getServiceStateTracker().getPhysicalChannelConfigList());
        if (isUsingPhysicalChannelConfigForRrcDetection()) {
            mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
        }
    }

    private void createTimerRules(String icons, String timers, String secondaryTimers) {
@@ -1035,12 +1038,16 @@ public class NetworkTypeController extends StateMachine {
                    if (isUsingPhysicalChannelConfigForRrcDetection()) {
                        mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
                    }
                    // Check NR advanced in case NR advanced bands were added
                    if (isPhysicalLinkActive()) {
                        if (isNrAdvanced()) {
                            transitionTo(mNrConnectedAdvancedState);
                    } else if (isPhysicalLinkActive()) {
                        } else {
                            transitionWithTimerTo(mNrConnectedState);
                        }
                    } else {
                        // Update in case the override network type changed
                        updateOverrideNetworkType();
                    }
                    break;
                case EVENT_PHYSICAL_LINK_STATUS_CHANGED:
                    mPhysicalLinkStatus = msg.arg1;
@@ -1113,11 +1120,10 @@ public class NetworkTypeController extends StateMachine {
                    if (isUsingPhysicalChannelConfigForRrcDetection()) {
                        mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
                    }
                    // Check NR advanced in case NR advanced bands were added
                    if (isNrAdvanced()) {
                        transitionTo(mNrConnectedAdvancedState);
                    } else if (!isPhysicalLinkActive() && mFeatureFlags.supportNrSaRrcIdle()) {
                    if (!isPhysicalLinkActive() && mFeatureFlags.supportNrSaRrcIdle()) {
                        transitionWithTimerTo(mNrIdleState);
                    } else if (isNrAdvanced()) {
                        transitionTo(mNrConnectedAdvancedState);
                    }
                    break;
                case EVENT_PHYSICAL_LINK_STATUS_CHANGED:
@@ -1203,11 +1209,10 @@ public class NetworkTypeController extends StateMachine {
                    if (isUsingPhysicalChannelConfigForRrcDetection()) {
                        mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
                    }
                    // Check NR advanced in case NR advanced bands were removed
                    if (!isNrAdvanced()) {
                        transitionWithTimerTo(isPhysicalLinkActive()
                                || !mFeatureFlags.supportNrSaRrcIdle()
                                ? mNrConnectedState : mNrIdleState);
                    if (!isPhysicalLinkActive() && mFeatureFlags.supportNrSaRrcIdle()) {
                        transitionWithTimerTo(mNrIdleState);
                    } else if (!isNrAdvanced()) {
                        transitionWithTimerTo(mNrConnectedState);
                    }
                    break;
                case EVENT_PHYSICAL_LINK_STATUS_CHANGED:
@@ -1299,9 +1304,9 @@ public class NetworkTypeController extends StateMachine {
        } else {
            if (mFeatureFlags.supportNrSaRrcIdle() && mDoesPccListIndicateIdle
                    && isUsingPhysicalChannelConfigForRrcDetection()
                    && !mPrimaryCellChangedWhileIdle && isTimerActiveForRrcIdle()
                    && !mPrimaryCellChangedWhileIdle
                    && !isNrAdvancedForPccFields(nrBandwidths, nrBands)) {
                log("Allow primary cell change during RRC idle timer without changing state: "
                log("Allow primary cell change once during RRC idle without changing state: "
                        + mLastAnchorNrCellId + " -> " + anchorNrCellId);
                mPrimaryCellChangedWhileIdle = true;
                mLastAnchorNrCellId = anchorNrCellId;
@@ -1327,7 +1332,13 @@ public class NetworkTypeController extends StateMachine {

    private void transitionWithTimerTo(IState destState) {
        String destName = destState.getName();
        if (DBG) log("Transition with primary timer from " + mPreviousState + " to " + destName);
        if (mIsPrimaryTimerActive) {
            log("Transition without timer from " + getCurrentState().getName() + " to " + destName
                    + " due to existing " + mPrimaryTimerState + " primary timer.");
        } else {
            if (DBG) {
                log("Transition with primary timer from " + mPreviousState + " to " + destName);
            }
            OverrideTimerRule rule = mOverrideTimerRules.get(mPreviousState);
            if (!mIsDeviceIdleMode && rule != null && rule.getTimer(destName) > 0) {
                int duration = rule.getTimer(destName);
@@ -1337,6 +1348,7 @@ public class NetworkTypeController extends StateMachine {
                mIsPrimaryTimerActive = true;
                sendMessageDelayed(EVENT_PRIMARY_TIMER_EXPIRED, destState, duration * 1000L);
            }
        }
        transitionTo(destState);
    }

@@ -1367,14 +1379,12 @@ public class NetworkTypeController extends StateMachine {
        int dataRat = getDataNetworkType();
        IState transitionState;
        if (dataRat == TelephonyManager.NETWORK_TYPE_NR || (isLte(dataRat) && isNrConnected())) {
            if (isNrAdvanced()) {
            if (!isPhysicalLinkActive() && mFeatureFlags.supportNrSaRrcIdle()) {
                transitionState = mNrIdleState;
            } else if (isNrAdvanced()) {
                transitionState = mNrConnectedAdvancedState;
            } else {
                if (isPhysicalLinkActive() || !mFeatureFlags.supportNrSaRrcIdle()) {
                transitionState = mNrConnectedState;
                } else {
                    transitionState = mNrIdleState;
                }
            }
        } else if (isLte(dataRat) && isNrNotRestricted()) {
            if (isPhysicalLinkActive()) {
@@ -1403,13 +1413,11 @@ public class NetworkTypeController extends StateMachine {

        String currentState = getCurrentState().getName();

        if (mIsPrimaryTimerActive && getOverrideNetworkType() == getCurrentOverrideNetworkType()
                && getDataNetworkType()
                == mDisplayInfoController.getTelephonyDisplayInfo().getNetworkType()) {
            // remove primary timer if device goes back to the original icon
        if (mIsPrimaryTimerActive && mPrimaryTimerState.equals(currentState)) {
            // remove primary timer if device goes back to the original state
            if (DBG) {
                log("Remove primary timer since icon of primary state and current icon equal: "
                        + mPrimaryTimerState);
                log("Remove primary timer since primary timer state ("
                        + mPrimaryTimerState + ") was reestablished.");
            }
            removeMessages(EVENT_PRIMARY_TIMER_EXPIRED);
            mIsPrimaryTimerActive = false;
@@ -1435,10 +1443,11 @@ public class NetworkTypeController extends StateMachine {
            if (currentState.equals(STATE_CONNECTED_NR_ADVANCED)) {
                if (DBG) log("Reset timers since state is NR_ADVANCED.");
                resetAllTimers();
            } else if (currentState.equals(STATE_CONNECTED)
            } else if ((currentState.equals(STATE_CONNECTED)
                    || currentState.equals(STATE_CONNECTED_RRC_IDLE))
                    && !mPrimaryTimerState.equals(STATE_CONNECTED_NR_ADVANCED)
                    && !mSecondaryTimerState.equals(STATE_CONNECTED_NR_ADVANCED)) {
                if (DBG) log("Reset non-NR_ADVANCED timers since state is NR_CONNECTED");
                if (DBG) log("Reset non-NR advanced timers since state is NR connected/idle");
                resetAllTimers();
            } else {
                int rat = getDataNetworkType();
@@ -1461,18 +1470,6 @@ public class NetworkTypeController extends StateMachine {
        mLastShownNrDueToAdvancedBand = false;
    }

    private boolean isTimerActiveForRrcIdle() {
        if (mIsPrimaryTimerActive) {
            return mPrimaryTimerState.equals(STATE_CONNECTED_RRC_IDLE)
                    || mPrimaryTimerState.equals(STATE_NOT_RESTRICTED_RRC_IDLE);
        } else if (mIsSecondaryTimerActive) {
            return mSecondaryTimerState.equals(STATE_CONNECTED_RRC_IDLE)
                    || mSecondaryTimerState.equals(STATE_NOT_RESTRICTED_RRC_IDLE);
        } else {
            return false;
        }
    }

    /**
     * Private class defining timer rules between states to prevent flickering. These rules are
     * created in {@link #parseCarrierConfigs()} based on various carrier configs.
+89 −16
Original line number Diff line number Diff line
@@ -1249,6 +1249,79 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertFalse(mNetworkTypeController.areAnyTimersActive());
    }

    @Test
    public void testPrimaryTimerPrimaryCellChangeNrIdle() throws Exception {
        doReturn(true).when(mFeatureFlags).supportNrSaRrcIdle();
        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
        ArrayList<PhysicalChannelConfig> physicalChannelConfigs = new ArrayList<>();
        physicalChannelConfigs.add(new PhysicalChannelConfig.Builder()
                .setPhysicalCellId(1)
                .setNetworkType(TelephonyManager.NETWORK_TYPE_NR)
                .setCellConnectionStatus(CellInfo.CONNECTION_PRIMARY_SERVING)
                .setBand(41)
                .build());
        doReturn(physicalChannelConfigs).when(mSST).getPhysicalChannelConfigList();
        mBundle.putIntArray(CarrierConfigManager.KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY,
                new int[]{41});
        mBundle.putString(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING,
                "connected_mmwave,any,10");
        sendCarrierConfigChanged();

        assertEquals("connected_mmwave", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
                mNetworkTypeController.getOverrideNetworkType());

        // should trigger 10 second primary timer
        physicalChannelConfigs.clear();
        mNetworkTypeController.sendMessage(11 /* EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED */,
                new AsyncResult(null, physicalChannelConfigs, null));
        processAllMessages();

        assertEquals("connected_rrc_idle", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
                mNetworkTypeController.getOverrideNetworkType());
        assertTrue(mNetworkTypeController.areAnyTimersActive());

        // change PCI during connected_rrc_idle
        physicalChannelConfigs.add(new PhysicalChannelConfig.Builder()
                .setPhysicalCellId(2)
                .setNetworkType(TelephonyManager.NETWORK_TYPE_NR)
                .setCellConnectionStatus(CellInfo.CONNECTION_PRIMARY_SERVING)
                .build());
        mNetworkTypeController.sendMessage(11 /* EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED */,
                new AsyncResult(null, physicalChannelConfigs, null));
        processAllMessages();

        assertEquals("connected_rrc_idle", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
                mNetworkTypeController.getOverrideNetworkType());
        assertTrue(mNetworkTypeController.areAnyTimersActive());

        // change PCI for the second time during connected_rrc_idle
        physicalChannelConfigs.add(new PhysicalChannelConfig.Builder()
                .setPhysicalCellId(3)
                .setNetworkType(TelephonyManager.NETWORK_TYPE_NR)
                .setCellConnectionStatus(CellInfo.CONNECTION_PRIMARY_SERVING)
                .build());
        mNetworkTypeController.sendMessage(11 /* EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED */,
                new AsyncResult(null, physicalChannelConfigs, null));
        processAllMessages();

        assertEquals("connected", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
                mNetworkTypeController.getOverrideNetworkType());
        assertTrue(mNetworkTypeController.areAnyTimersActive());

        // primary timer expires
        moveTimeForward(10 * 1000);
        processAllMessages();

        assertEquals("connected", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                mNetworkTypeController.getOverrideNetworkType());
        assertFalse(mNetworkTypeController.areAnyTimersActive());
    }

    @Test
    public void testSecondaryTimerExpire() throws Exception {
        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
@@ -1695,22 +1768,6 @@ public class NetworkTypeControllerTest extends TelephonyTest {

        // should trigger 10 second primary timer
        physicalChannelConfigs.clear();
        physicalChannelConfigs.add(new PhysicalChannelConfig.Builder()
                .setPhysicalCellId(1)
                .setNetworkType(TelephonyManager.NETWORK_TYPE_NR)
                .setCellConnectionStatus(CellInfo.CONNECTION_PRIMARY_SERVING)
                .build());
        mNetworkTypeController.sendMessage(11 /* EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED */,
                new AsyncResult(null, physicalChannelConfigs, null));
        processAllMessages();

        assertEquals("connected", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
                mNetworkTypeController.getOverrideNetworkType());
        assertTrue(mNetworkTypeController.areAnyTimersActive());

        // switch to connected_rrc_idle
        physicalChannelConfigs.clear();
        mNetworkTypeController.sendMessage(11 /* EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED */,
                new AsyncResult(null, physicalChannelConfigs, null));
        processAllMessages();
@@ -1745,6 +1802,22 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
                mNetworkTypeController.getOverrideNetworkType());
        assertTrue(mNetworkTypeController.areAnyTimersActive());

        // primary cell changes again
        physicalChannelConfigs.clear();
        physicalChannelConfigs.add(new PhysicalChannelConfig.Builder()
                .setPhysicalCellId(3)
                .setNetworkType(TelephonyManager.NETWORK_TYPE_NR)
                .setCellConnectionStatus(CellInfo.CONNECTION_PRIMARY_SERVING)
                .build());
        mNetworkTypeController.sendMessage(11 /* EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED */,
                new AsyncResult(null, physicalChannelConfigs, null));
        processAllMessages();

        assertEquals("connected", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                mNetworkTypeController.getOverrideNetworkType());
        assertFalse(mNetworkTypeController.areAnyTimersActive());
    }

    @Test