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

Commit a959ae11 authored by Ling Ma's avatar Ling Ma
Browse files

Correctly trigger re-evaluation

Without the change, if the back up phone's score is the same or higher than the default phone's score, but the score is not significantly better than the default, it won't trigger re-evaluation.

Bug: 406432368
Test: basic voice call + data browsing
Flag: EXEMPT bugfix
Change-Id: I57544264f200a2080eacaedf79fe003253a89a1f
parent 8e14097a
Loading
Loading
Loading
Loading
+32 −18
Original line number Diff line number Diff line
@@ -595,7 +595,7 @@ public class AutoDataSwitchController extends Handler {
            TelephonyDisplayInfo displayInfo = phone.getDisplayInfoController()
                    .getTelephonyDisplayInfo();
            mPhonesSignalStatus[phoneId].mDisplayInfo = displayInfo;
            if (getHigherScoreCandidatePhoneId() != mSelectedTargetPhoneId) {
            if (getBetterCandidatePhoneIdBasedOnScore() != mSelectedTargetPhoneId) {
                log("onDisplayInfoChanged: phone " + phoneId + " " + displayInfo);
                evaluateAutoDataSwitch(EVALUATION_REASON_DISPLAY_INFO_CHANGED);
            }
@@ -615,7 +615,7 @@ public class AutoDataSwitchController extends Handler {
            SignalStrength oldSignalStrength = mPhonesSignalStatus[phoneId].mSignalStrength;
            if (oldSignalStrength.getLevel() != newSignalStrength.getLevel()) {
                mPhonesSignalStatus[phoneId].mSignalStrength = newSignalStrength;
                if (getHigherScoreCandidatePhoneId() != mSelectedTargetPhoneId) {
                if (getBetterCandidatePhoneIdBasedOnScore() != mSelectedTargetPhoneId) {
                    log("onSignalStrengthChanged: phone " + phoneId + " "
                            + oldSignalStrength.getLevel() + "->" + newSignalStrength.getLevel());
                    evaluateAutoDataSwitch(EVALUATION_REASON_SIGNAL_STRENGTH_CHANGED);
@@ -627,31 +627,45 @@ public class AutoDataSwitchController extends Handler {
    }

    /**
     * Called as a preliminary check for the frequent signal/display info change.
     * @return The phone Id if found a candidate phone with higher signal score, or the DDS has
     * an equal score.
     * Checks for a better data phone candidate based on signal strength.Compares the preferred data
     * phone and DDS, potentially switching to another active phone with a significantly better
     * signal or reverting to DDS if the preferred phone isn't significantly better.
     *
     * @return A better candidate phone ID, the DDS phone ID,
     * or {@link android.telephony.SubscriptionManager#INVALID_PHONE_INDEX}.
     */
    private int getHigherScoreCandidatePhoneId() {
    private int getBetterCandidatePhoneIdBasedOnScore() {
        int preferredPhoneId = mPhoneSwitcher.getPreferredDataPhoneId();
        int ddsPhoneId = mSubscriptionManagerService.getPhoneId(
                mSubscriptionManagerService.getDefaultDataSubId());
        if (isActiveModemPhone(preferredPhoneId) && isActiveModemPhone(ddsPhoneId)) {
            int currentScore = mPhonesSignalStatus[preferredPhoneId].getRatSignalScore();
            for (int phoneId = 0; phoneId < mPhonesSignalStatus.length; phoneId++) {
                if (phoneId == preferredPhoneId) continue;
                PhoneSignalStatus candidateStatus = mPhonesSignalStatus[phoneId];
                // Ignore non-home phone.
                if (candidateStatus.getUsableState() != PhoneSignalStatus.UsableState.HOME) {

        if (!isActiveModemPhone(preferredPhoneId) || !isActiveModemPhone(ddsPhoneId)) {
            return INVALID_PHONE_INDEX;
        }

        int defaultScore = mPhonesSignalStatus[ddsPhoneId].getRatSignalScore();
        int preferredScore = mPhonesSignalStatus[preferredPhoneId].getRatSignalScore();

        // Currently on default data subscription
        if (ddsPhoneId == preferredPhoneId) {
            // Find any candidate with significantly better score
            for (int backupId = 0; backupId < mPhonesSignalStatus.length; backupId++) {
                // Skip current phone and non-home phones
                if (backupId == preferredPhoneId
                        || !isHomeService(mPhonesSignalStatus[backupId].mDataRegState)) {
                    continue;
                }
                int candidateScore = candidateStatus.getRatSignalScore();
                if ((candidateScore - currentScore) > mScoreTolerance
                        // Also reevaluate if DDS has the same score as the current phone.
                        || (candidateScore >= currentScore && phoneId == ddsPhoneId)) {
                    return phoneId;

                int candidateScore = mPhonesSignalStatus[backupId].getRatSignalScore();
                if (candidateScore - defaultScore > mScoreTolerance) {
                    return backupId;
                }
            }
        } else if (preferredScore - defaultScore <= mScoreTolerance) { // Currently on backup
            // Switch back to dds if preferred isn't significantly better
            return ddsPhoneId;
        }

        return INVALID_PHONE_INDEX;
    }

+28 −1
Original line number Diff line number Diff line
@@ -415,6 +415,7 @@ public class AutoDataSwitchControllerTest extends TelephonyTest {

        // 4.1.2 Display info and signal strength on secondary phone became bad,
        // but primary become service, then don't switch.
        logd("4.1.2 Display info and signal strength on secondary became bad, don't switch.");
        prepareIdealUsesNonDdsCondition();
        processAllFutureMessages();
        clearInvocations(mMockedPhoneSwitcherCallback, mMockedAlarmManager);
@@ -428,6 +429,7 @@ public class AutoDataSwitchControllerTest extends TelephonyTest {
                EVENT_STABILITY_CHECK_PASSED));

        // 4.2 Display info on default phone became good just as the secondary
        logd("4.2 Display info on default phone became good just as the secondary.");
        prepareIdealUsesNonDdsCondition();
        processAllFutureMessages();
        clearInvocations(mMockedPhoneSwitcherCallback, mMockedAlarmManager);
@@ -440,6 +442,7 @@ public class AutoDataSwitchControllerTest extends TelephonyTest {
                EVENT_STABILITY_CHECK_PASSED));

        // 4.3 Signal strength on default phone became just as good as the secondary
        logd("4.3 Signal strength on default phone became just as good as the secondary.");
        prepareIdealUsesNonDdsCondition();
        processAllFutureMessages();
        clearInvocations(mMockedPhoneSwitcherCallback, mMockedAlarmManager);
@@ -723,7 +726,7 @@ public class AutoDataSwitchControllerTest extends TelephonyTest {

    @Test
    public void testRatSignalStrengthSkipEvaluation() {
        // Verify the secondary phone is OOS and its score(0) is too low to justify the evaluation
        // Score NOT significantly better to justify the evaluation
        clearInvocations(mMockedPhoneSwitcherCallback);
        displayInfoChanged(PHONE_2, mBadTelephonyDisplayInfo);
        processAllFutureMessages();
@@ -732,6 +735,30 @@ public class AutoDataSwitchControllerTest extends TelephonyTest {
        verify(mMockedPhoneSwitcherCallback, never()).onRequireValidation(anyInt(), anyBoolean());
    }

    /**
     * Scenario 2: On Default, Candidate score IS better, BUT Candidate is NOT HOME.
     */
    @Test
    public void testBetterCandidate_onDefault_nonHome_scoreHigh_noEval() {
        doReturn(PHONE_1).when(mPhoneSwitcher).getPreferredDataPhoneId();

        // Setup state: Low score for default, high score for backup
        displayInfoChanged(PHONE_1, mBadTelephonyDisplayInfo);
        signalStrengthChanged(PHONE_1, SignalStrength.SIGNAL_STRENGTH_POOR);
        displayInfoChanged(PHONE_2, mGoodTelephonyDisplayInfo); // High score inputs
        signalStrengthChanged(PHONE_2, SignalStrength.SIGNAL_STRENGTH_GREAT);
        serviceStateChanged(PHONE_2, NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
        processAllMessages();

        // Trigger internal call via another display info change
        displayInfoChanged(PHONE_2, mGoodTelephonyDisplayInfo);
        processAllMessages();

        // Verify no evaluation scheduled (skipped because not HOME)
        assertThat(mAutoDataSwitchControllerUT.hasMessages(EVENT_EVALUATE_AUTO_SWITCH)).isFalse();
        mAutoDataSwitchControllerUT.removeMessages(EVENT_EVALUATE_AUTO_SWITCH);
    }

    /**
     * Trigger conditions
     * 1. service state changes