Loading src/java/com/android/internal/telephony/data/AutoDataSwitchController.java +32 −18 Original line number Diff line number Diff line Loading @@ -674,7 +674,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); } Loading @@ -694,7 +694,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); Loading @@ -706,31 +706,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; } Loading tests/telephonytests/src/com/android/internal/telephony/data/AutoDataSwitchControllerTest.java +28 −1 Original line number Diff line number Diff line Loading @@ -420,6 +420,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); Loading @@ -433,6 +434,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); Loading @@ -445,6 +447,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); Loading Loading @@ -906,7 +909,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(); Loading @@ -915,6 +918,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 Loading Loading
src/java/com/android/internal/telephony/data/AutoDataSwitchController.java +32 −18 Original line number Diff line number Diff line Loading @@ -674,7 +674,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); } Loading @@ -694,7 +694,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); Loading @@ -706,31 +706,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; } Loading
tests/telephonytests/src/com/android/internal/telephony/data/AutoDataSwitchControllerTest.java +28 −1 Original line number Diff line number Diff line Loading @@ -420,6 +420,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); Loading @@ -433,6 +434,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); Loading @@ -445,6 +447,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); Loading Loading @@ -906,7 +909,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(); Loading @@ -915,6 +918,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 Loading