Loading flags/data.aconfig +11 −0 Original line number Diff line number Diff line package: "com.android.internal.telephony.flags" container: "system" # OWNER=linggm TARGET=25Q3 flag { name: "auto_data_prune_listener" namespace: "telephony" description: "Unregister listeners when user disable settings or connect to wifi." bug:"389591869" metadata { purpose: PURPOSE_BUGFIX } } # OWNER=sarahchin TARGET=24Q3 flag { name: "slicing_additional_error_codes" Loading flags/satellite.aconfig +12 −0 Original line number Diff line number Diff line Loading @@ -103,3 +103,15 @@ flag { purpose: PURPOSE_BUGFIX } } # OWNER=amallampati TARGET=25Q3 flag { name: "satellite_improve_multi_thread_design" is_exported: false namespace: "telephony" description: "Improve multi-thread design in satellite module" bug:"398227332" metadata { purpose: PURPOSE_BUGFIX } } No newline at end of file src/java/com/android/internal/telephony/data/AutoDataSwitchController.java +103 −17 Original line number Diff line number Diff line Loading @@ -422,6 +422,10 @@ public class AutoDataSwitchController extends Handler { * sub to reduce unnecessary tracking. */ private void onSubscriptionsChanged() { if (sFeatureFlags.autoDataPruneListener()) { boolean changed = updateListenerRegistrations(); if (changed) logl("onSubscriptionChanged: " + Arrays.toString(mPhonesSignalStatus)); } else { Set<Integer> activePhoneIds = Arrays.stream(mSubscriptionManagerService .getActiveSubIdList(true /*visibleOnly*/)) .map(mSubscriptionManagerService::getPhoneId) Loading @@ -443,6 +447,80 @@ public class AutoDataSwitchController extends Handler { } if (changed) logl("onSubscriptionChanged: " + Arrays.toString(mPhonesSignalStatus)); } } /** * Updates network event listener registrations based on conditions. * * Unregisters listeners for *all* phones if: * 1. <2 active subscriptions (auto-switching requires 2+). * 2. Non-cellular default network (auto-switching not relevant). * 3. Default data disabled (no need to monitor for switching). * 4. No eligible auto-switch candidates (all other phones' data * disabled, preventing switching). * * Registers listeners if none of the above apply and a phone's * listeners are currently unregistered. * * @return `true` if any registration changed; `false` otherwise. */ private boolean updateListenerRegistrations() { if (!sFeatureFlags.autoDataPruneListener()) { return false; } boolean shouldUnregister = false; String reason = ""; if (mSubscriptionManagerService.getActiveSubIdList(true).length < 2) { shouldUnregister = true; reason = "only have one active subscription"; } else if (mDefaultNetworkIsOnNonCellular) { shouldUnregister = true; reason = "default network is on non-cellular network"; } else { int defaultDataPhoneId = mSubscriptionManagerService.getPhoneId( mSubscriptionManagerService.getDefaultDataSubId()); Phone defaultDataPhone = PhoneFactory.getPhone(defaultDataPhoneId); if (defaultDataPhone != null && !defaultDataPhone.isUserDataEnabled()) { shouldUnregister = true; reason = "default data is disabled"; } else { boolean anyCandidateEnabled = false; for (int phoneId = 0; phoneId < mPhonesSignalStatus.length; phoneId++) { if (phoneId != defaultDataPhoneId) { Phone phone = PhoneFactory.getPhone(phoneId); if (phone != null && phone.getDataSettingsManager().isDataEnabled()) { anyCandidateEnabled = true; break; } } } if (!anyCandidateEnabled) { shouldUnregister = true; reason = "no candidate enabled auto data switch feature"; } } } if (shouldUnregister) { log("updateListenerRegistrations: " + reason); } // Register or unregister as needed boolean changed = false; for (int phoneId = 0; phoneId < mPhonesSignalStatus.length; phoneId++) { if (shouldUnregister && mPhonesSignalStatus[phoneId].mListeningForEvents) { unregisterAllEventsForPhone(phoneId); changed = true; } else if (!shouldUnregister && !mPhonesSignalStatus[phoneId].mListeningForEvents) { registerAllEventsForPhone(phoneId); changed = true; } } return changed; } /** * Register all tracking events for a phone. Loading @@ -459,6 +537,7 @@ public class AutoDataSwitchController extends Handler { phone.getServiceStateTracker().registerForServiceStateChanged(this, EVENT_SERVICE_STATE_CHANGED, phoneId); mPhonesSignalStatus[phoneId].mListeningForEvents = true; log("registerAllEventsForPhone: registered listeners for phone " + phoneId); } else { loge("Unexpected null phone " + phoneId + " when register all events"); } Loading @@ -475,6 +554,7 @@ public class AutoDataSwitchController extends Handler { phone.getSignalStrengthController().unregisterForSignalStrengthChanged(this); phone.getServiceStateTracker().unregisterForServiceStateChanged(this); mPhonesSignalStatus[phoneId].mListeningForEvents = false; log("unregisterAllEventsForPhone: unregistered listeners for phone " + phoneId); } else { loge("Unexpected out of bound phone " + phoneId + " when unregister all events"); } Loading @@ -497,8 +577,7 @@ public class AutoDataSwitchController extends Handler { dataConfig.getAutoDataSwitchAvailabilitySwitchbackStabilityTimeThreshold() >= 0 ? dataConfig.getAutoDataSwitchAvailabilitySwitchbackStabilityTimeThreshold() : dataConfig.getAutoDataSwitchAvailabilityStabilityTimeThreshold()); mAutoDataSwitchValidationMaxRetry = dataConfig.getAutoDataSwitchValidationMaxRetry(); mAutoDataSwitchValidationMaxRetry = dataConfig.getAutoDataSwitchValidationMaxRetry(); } @Override Loading Loading @@ -664,7 +743,14 @@ public class AutoDataSwitchController extends Handler { ? STABILITY_CHECK_TIMER_MAP.get(STABILITY_CHECK_AVAILABILITY_SWITCH) << mAutoSwitchValidationFailedCount : 0; if (!mScheduledEventsToExtras.containsKey(EVENT_EVALUATE_AUTO_SWITCH)) { if (reason == EVALUATION_REASON_DATA_SETTINGS_CHANGED || reason == EVALUATION_REASON_DEFAULT_NETWORK_CHANGED) { // In some conditions, listeners are paused to reduce unnecessary tracking. updateListenerRegistrations(); // Always reevaluate with those critical condition change. scheduleEventWithTimer(EVENT_EVALUATE_AUTO_SWITCH, new EvaluateEventExtra(reason), delayMs); } else if (!mScheduledEventsToExtras.containsKey(EVENT_EVALUATE_AUTO_SWITCH)) { scheduleEventWithTimer(EVENT_EVALUATE_AUTO_SWITCH, new EvaluateEventExtra(reason), delayMs); } Loading tests/telephonytests/src/com/android/internal/telephony/data/AutoDataSwitchControllerTest.java +184 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,7 @@ public class AutoDataSwitchControllerTest extends TelephonyTest { doReturn(mSignalStrength).when(phone).getSignalStrength(); doReturn(mDataNetworkController).when(phone).getDataNetworkController(); doReturn(mDataConfigManager).when(mDataNetworkController).getDataConfigManager(); doReturn(mDataSettingsManager).when(phone).getDataSettingsManager(); doAnswer(invocation -> phone.getSubId() == mDefaultDataSub) .when(phone).isUserDataEnabled(); } Loading Loading @@ -195,6 +196,10 @@ public class AutoDataSwitchControllerTest extends TelephonyTest { "mEventsToAlarmListener", Map.class); mScheduledEventsToExtras = getPrivateField(mAutoDataSwitchControllerUT, "mScheduledEventsToExtras", Map.class); clearInvocations(mDisplayInfoController, mSignalStrengthController, mSST); doReturn(true).when(mFeatureFlags).autoDataPruneListener(); } @After Loading Loading @@ -721,6 +726,184 @@ public class AutoDataSwitchControllerTest extends TelephonyTest { } } @Test public void testDataSettingsChangedUpdateListener() { setDefaultDataSubId(SUB_1); // Phone 1 is default int modemCount = mPhones.length; // Should be 2 // Pre-condition: Assume listeners are registered initially (cleared invocations in setUp) // --- Scenario 1: Disable Default Phone User Data --- logd("Scenario 1: Disable Default Phone User Data"); doReturn(false).when(mPhone).isUserDataEnabled(); mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(EVALUATION_REASON_DATA_SETTINGS_CHANGED); processAllMessages(); // Verify unregister calls for *both* phones verify(mDisplayInfoController, times(modemCount)) .unregisterForTelephonyDisplayInfoChanged(any()); verify(mSignalStrengthController, times(modemCount)).unregisterForSignalStrengthChanged( any()); verify(mSST, times(modemCount)).unregisterForServiceStateChanged(any()); // Verify register calls were NOT made verify(mDisplayInfoController, never()).registerForTelephonyDisplayInfoChanged( any(), anyInt(), any()); verify(mSignalStrengthController, never()).registerForSignalStrengthChanged( any(), anyInt(), any()); verify(mSST, never()).registerForServiceStateChanged(any(), anyInt(), any()); clearInvocations(mDisplayInfoController, mSignalStrengthController, mSST); // --- Scenario 2: Re-enable Default Phone User Data --- logd("Scenario 2: Re-enable Default Phone User Data"); doReturn(true).when(mPhone).isUserDataEnabled(); mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(EVALUATION_REASON_DATA_SETTINGS_CHANGED); processAllMessages(); // Verify register calls for *both* phones verify(mDisplayInfoController, times(modemCount)).registerForTelephonyDisplayInfoChanged( any(), eq(EVENT_DISPLAY_INFO_CHANGED), any()); verify(mSignalStrengthController, times(modemCount)).registerForSignalStrengthChanged( any(), eq(EVENT_SIGNAL_STRENGTH_CHANGED), any()); verify(mSST, times(modemCount)).registerForServiceStateChanged( any(), eq(EVENT_SERVICE_STATE_CHANGED), any()); // Verify unregister calls were NOT made verify(mDisplayInfoController, never()).unregisterForTelephonyDisplayInfoChanged(any()); verify(mSignalStrengthController, never()).unregisterForSignalStrengthChanged(any()); verify(mSST, never()).unregisterForServiceStateChanged(any()); clearInvocations(mDisplayInfoController, mSignalStrengthController, mSST); // Reset // --- Scenario 3: Disable *Only* Candidate Phone Data Setting --- logd("Scenario 3: Disable *Only* Candidate Phone Data Setting"); doReturn(true).when(mPhone).isUserDataEnabled(); // Ensure default is enabled doReturn(false).when(mDataSettingsManager).isDataEnabled(); // Disable candidate mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(EVALUATION_REASON_DATA_SETTINGS_CHANGED); processAllMessages(); // Verify unregister calls for *both* phones (as no candidates left) verify(mDisplayInfoController, times(modemCount)) .unregisterForTelephonyDisplayInfoChanged(any()); verify(mSignalStrengthController, times(modemCount)) .unregisterForSignalStrengthChanged(any()); verify(mSST, times(modemCount)).unregisterForServiceStateChanged(any()); // Verify register calls were NOT made verify(mDisplayInfoController, never()) .registerForTelephonyDisplayInfoChanged(any(), anyInt(), any()); verify(mSignalStrengthController, never()) .registerForSignalStrengthChanged(any(), anyInt(), any()); verify(mSST, never()).registerForServiceStateChanged(any(), anyInt(), any()); clearInvocations(mDisplayInfoController, mSignalStrengthController, mSST); // Reset // --- Scenario 4: Re-enable Candidate Phone Data Setting --- logd("Scenario 4: Re-enable Candidate Phone Data Setting"); doReturn(true).when(mDataSettingsManager).isDataEnabled(); mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(EVALUATION_REASON_DATA_SETTINGS_CHANGED); processAllMessages(); // Verify register calls for *both* phones verify(mDisplayInfoController, times(modemCount)).registerForTelephonyDisplayInfoChanged( any(), eq(EVENT_DISPLAY_INFO_CHANGED), any()); verify(mSignalStrengthController, times(modemCount)).registerForSignalStrengthChanged( any(), eq(EVENT_SIGNAL_STRENGTH_CHANGED), any()); verify(mSST, times(modemCount)).registerForServiceStateChanged( any(), eq(EVENT_SERVICE_STATE_CHANGED), any()); // Verify unregister calls were NOT made verify(mDisplayInfoController, never()).unregisterForTelephonyDisplayInfoChanged(any()); verify(mSignalStrengthController, never()).unregisterForSignalStrengthChanged(any()); verify(mSST, never()).unregisterForServiceStateChanged(any()); } @Test public void testDefaultNetworkChangedUpdateListener() { setDefaultDataSubId(SUB_1); // Phone 1 is default int modemCount = mPhones.length; // Should be 2 // Pre-condition: Assume listeners are registered initially (cleared invocations in setUp) // --- Scenario 1: Default network becomes non-cellular (WIFI) --- logd("Scenario 1: Default network becomes WIFI"); NetworkCapabilities wifiCapabilities = new NetworkCapabilities(); wifiCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); mAutoDataSwitchControllerUT.updateDefaultNetworkCapabilities(wifiCapabilities); mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(AutoDataSwitchController .EVALUATION_REASON_DEFAULT_NETWORK_CHANGED); processAllMessages(); // Verify unregister calls for *both* phones verify(mDisplayInfoController, times(modemCount)) .unregisterForTelephonyDisplayInfoChanged(any()); verify(mSignalStrengthController, times(modemCount)) .unregisterForSignalStrengthChanged(any()); verify(mSST, times(modemCount)).unregisterForServiceStateChanged(any()); // Verify register calls were NOT made verify(mDisplayInfoController, never()).registerForTelephonyDisplayInfoChanged( any(), anyInt(), any()); verify(mSignalStrengthController, never()).registerForSignalStrengthChanged( any(), anyInt(), any()); verify(mSST, never()).registerForServiceStateChanged(any(), anyInt(), any()); clearInvocations(mDisplayInfoController, mSignalStrengthController, mSST); // Reset // --- Scenario 2: Default network becomes cellular --- logd("Scenario 2: Default network becomes CELLULAR"); NetworkCapabilities cellularCapabilities = new NetworkCapabilities(); cellularCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); mAutoDataSwitchControllerUT.updateDefaultNetworkCapabilities(cellularCapabilities); mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(AutoDataSwitchController .EVALUATION_REASON_DEFAULT_NETWORK_CHANGED); processAllMessages(); // Verify register calls for *both* phones verify(mDisplayInfoController, times(modemCount)).registerForTelephonyDisplayInfoChanged( any(), eq(EVENT_DISPLAY_INFO_CHANGED), any()); verify(mSignalStrengthController, times(modemCount)).registerForSignalStrengthChanged(any(), eq(EVENT_SIGNAL_STRENGTH_CHANGED), any()); verify(mSST, times(modemCount)).registerForServiceStateChanged(any(), eq(EVENT_SERVICE_STATE_CHANGED), any()); // Verify unregister calls were NOT made verify(mDisplayInfoController, never()).unregisterForTelephonyDisplayInfoChanged(any()); verify(mSignalStrengthController, never()).unregisterForSignalStrengthChanged(any()); verify(mSST, never()).unregisterForServiceStateChanged(any()); clearInvocations(mDisplayInfoController, mSignalStrengthController, mSST); // Reset // --- Scenario 3: Default network lost (null) --- logd("Scenario 3: Default network lost (null)"); // First switch to non-cellular to ensure listeners are off mAutoDataSwitchControllerUT.updateDefaultNetworkCapabilities(wifiCapabilities); mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(AutoDataSwitchController .EVALUATION_REASON_DEFAULT_NETWORK_CHANGED); processAllMessages(); verify(mDisplayInfoController, times(modemCount)) .unregisterForTelephonyDisplayInfoChanged(any()); verify(mSignalStrengthController, times(modemCount)) .unregisterForSignalStrengthChanged(any()); verify(mSST, times(modemCount)) .unregisterForServiceStateChanged(any()); clearInvocations(mDisplayInfoController, mSignalStrengthController, mSST); // Now lose the network mAutoDataSwitchControllerUT.updateDefaultNetworkCapabilities(null); mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(AutoDataSwitchController .EVALUATION_REASON_DEFAULT_NETWORK_CHANGED); processAllMessages(); // Verify register calls for *both* phones (null network means cellular is possible) verify(mDisplayInfoController, times(modemCount)).registerForTelephonyDisplayInfoChanged( any(), eq(EVENT_DISPLAY_INFO_CHANGED), any()); verify(mSignalStrengthController, times(modemCount)).registerForSignalStrengthChanged(any(), eq(EVENT_SIGNAL_STRENGTH_CHANGED), any()); verify(mSST, times(modemCount)).registerForServiceStateChanged(any(), eq(EVENT_SERVICE_STATE_CHANGED), any()); verify(mDisplayInfoController, never()) .unregisterForTelephonyDisplayInfoChanged(any()); verify(mSignalStrengthController, never()).unregisterForSignalStrengthChanged(any()); verify(mSST, never()).unregisterForServiceStateChanged(any()); } @Test public void testRatSignalStrengthSkipEvaluation() { // Verify the secondary phone is OOS and its score(0) is too low to justify the evaluation Loading Loading @@ -764,6 +947,7 @@ public class AutoDataSwitchControllerTest extends TelephonyTest { // 4.2 Auto switch feature is enabled doReturn(true).when(mPhone2).getDataRoamingEnabled(); doReturn(true).when(mDataSettingsManager).isDataEnabled(); mDataEvaluation.addDataAllowedReason(DataEvaluation.DataAllowedReason.NORMAL); // 5. No default network Loading Loading
flags/data.aconfig +11 −0 Original line number Diff line number Diff line package: "com.android.internal.telephony.flags" container: "system" # OWNER=linggm TARGET=25Q3 flag { name: "auto_data_prune_listener" namespace: "telephony" description: "Unregister listeners when user disable settings or connect to wifi." bug:"389591869" metadata { purpose: PURPOSE_BUGFIX } } # OWNER=sarahchin TARGET=24Q3 flag { name: "slicing_additional_error_codes" Loading
flags/satellite.aconfig +12 −0 Original line number Diff line number Diff line Loading @@ -103,3 +103,15 @@ flag { purpose: PURPOSE_BUGFIX } } # OWNER=amallampati TARGET=25Q3 flag { name: "satellite_improve_multi_thread_design" is_exported: false namespace: "telephony" description: "Improve multi-thread design in satellite module" bug:"398227332" metadata { purpose: PURPOSE_BUGFIX } } No newline at end of file
src/java/com/android/internal/telephony/data/AutoDataSwitchController.java +103 −17 Original line number Diff line number Diff line Loading @@ -422,6 +422,10 @@ public class AutoDataSwitchController extends Handler { * sub to reduce unnecessary tracking. */ private void onSubscriptionsChanged() { if (sFeatureFlags.autoDataPruneListener()) { boolean changed = updateListenerRegistrations(); if (changed) logl("onSubscriptionChanged: " + Arrays.toString(mPhonesSignalStatus)); } else { Set<Integer> activePhoneIds = Arrays.stream(mSubscriptionManagerService .getActiveSubIdList(true /*visibleOnly*/)) .map(mSubscriptionManagerService::getPhoneId) Loading @@ -443,6 +447,80 @@ public class AutoDataSwitchController extends Handler { } if (changed) logl("onSubscriptionChanged: " + Arrays.toString(mPhonesSignalStatus)); } } /** * Updates network event listener registrations based on conditions. * * Unregisters listeners for *all* phones if: * 1. <2 active subscriptions (auto-switching requires 2+). * 2. Non-cellular default network (auto-switching not relevant). * 3. Default data disabled (no need to monitor for switching). * 4. No eligible auto-switch candidates (all other phones' data * disabled, preventing switching). * * Registers listeners if none of the above apply and a phone's * listeners are currently unregistered. * * @return `true` if any registration changed; `false` otherwise. */ private boolean updateListenerRegistrations() { if (!sFeatureFlags.autoDataPruneListener()) { return false; } boolean shouldUnregister = false; String reason = ""; if (mSubscriptionManagerService.getActiveSubIdList(true).length < 2) { shouldUnregister = true; reason = "only have one active subscription"; } else if (mDefaultNetworkIsOnNonCellular) { shouldUnregister = true; reason = "default network is on non-cellular network"; } else { int defaultDataPhoneId = mSubscriptionManagerService.getPhoneId( mSubscriptionManagerService.getDefaultDataSubId()); Phone defaultDataPhone = PhoneFactory.getPhone(defaultDataPhoneId); if (defaultDataPhone != null && !defaultDataPhone.isUserDataEnabled()) { shouldUnregister = true; reason = "default data is disabled"; } else { boolean anyCandidateEnabled = false; for (int phoneId = 0; phoneId < mPhonesSignalStatus.length; phoneId++) { if (phoneId != defaultDataPhoneId) { Phone phone = PhoneFactory.getPhone(phoneId); if (phone != null && phone.getDataSettingsManager().isDataEnabled()) { anyCandidateEnabled = true; break; } } } if (!anyCandidateEnabled) { shouldUnregister = true; reason = "no candidate enabled auto data switch feature"; } } } if (shouldUnregister) { log("updateListenerRegistrations: " + reason); } // Register or unregister as needed boolean changed = false; for (int phoneId = 0; phoneId < mPhonesSignalStatus.length; phoneId++) { if (shouldUnregister && mPhonesSignalStatus[phoneId].mListeningForEvents) { unregisterAllEventsForPhone(phoneId); changed = true; } else if (!shouldUnregister && !mPhonesSignalStatus[phoneId].mListeningForEvents) { registerAllEventsForPhone(phoneId); changed = true; } } return changed; } /** * Register all tracking events for a phone. Loading @@ -459,6 +537,7 @@ public class AutoDataSwitchController extends Handler { phone.getServiceStateTracker().registerForServiceStateChanged(this, EVENT_SERVICE_STATE_CHANGED, phoneId); mPhonesSignalStatus[phoneId].mListeningForEvents = true; log("registerAllEventsForPhone: registered listeners for phone " + phoneId); } else { loge("Unexpected null phone " + phoneId + " when register all events"); } Loading @@ -475,6 +554,7 @@ public class AutoDataSwitchController extends Handler { phone.getSignalStrengthController().unregisterForSignalStrengthChanged(this); phone.getServiceStateTracker().unregisterForServiceStateChanged(this); mPhonesSignalStatus[phoneId].mListeningForEvents = false; log("unregisterAllEventsForPhone: unregistered listeners for phone " + phoneId); } else { loge("Unexpected out of bound phone " + phoneId + " when unregister all events"); } Loading @@ -497,8 +577,7 @@ public class AutoDataSwitchController extends Handler { dataConfig.getAutoDataSwitchAvailabilitySwitchbackStabilityTimeThreshold() >= 0 ? dataConfig.getAutoDataSwitchAvailabilitySwitchbackStabilityTimeThreshold() : dataConfig.getAutoDataSwitchAvailabilityStabilityTimeThreshold()); mAutoDataSwitchValidationMaxRetry = dataConfig.getAutoDataSwitchValidationMaxRetry(); mAutoDataSwitchValidationMaxRetry = dataConfig.getAutoDataSwitchValidationMaxRetry(); } @Override Loading Loading @@ -664,7 +743,14 @@ public class AutoDataSwitchController extends Handler { ? STABILITY_CHECK_TIMER_MAP.get(STABILITY_CHECK_AVAILABILITY_SWITCH) << mAutoSwitchValidationFailedCount : 0; if (!mScheduledEventsToExtras.containsKey(EVENT_EVALUATE_AUTO_SWITCH)) { if (reason == EVALUATION_REASON_DATA_SETTINGS_CHANGED || reason == EVALUATION_REASON_DEFAULT_NETWORK_CHANGED) { // In some conditions, listeners are paused to reduce unnecessary tracking. updateListenerRegistrations(); // Always reevaluate with those critical condition change. scheduleEventWithTimer(EVENT_EVALUATE_AUTO_SWITCH, new EvaluateEventExtra(reason), delayMs); } else if (!mScheduledEventsToExtras.containsKey(EVENT_EVALUATE_AUTO_SWITCH)) { scheduleEventWithTimer(EVENT_EVALUATE_AUTO_SWITCH, new EvaluateEventExtra(reason), delayMs); } Loading
tests/telephonytests/src/com/android/internal/telephony/data/AutoDataSwitchControllerTest.java +184 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,7 @@ public class AutoDataSwitchControllerTest extends TelephonyTest { doReturn(mSignalStrength).when(phone).getSignalStrength(); doReturn(mDataNetworkController).when(phone).getDataNetworkController(); doReturn(mDataConfigManager).when(mDataNetworkController).getDataConfigManager(); doReturn(mDataSettingsManager).when(phone).getDataSettingsManager(); doAnswer(invocation -> phone.getSubId() == mDefaultDataSub) .when(phone).isUserDataEnabled(); } Loading Loading @@ -195,6 +196,10 @@ public class AutoDataSwitchControllerTest extends TelephonyTest { "mEventsToAlarmListener", Map.class); mScheduledEventsToExtras = getPrivateField(mAutoDataSwitchControllerUT, "mScheduledEventsToExtras", Map.class); clearInvocations(mDisplayInfoController, mSignalStrengthController, mSST); doReturn(true).when(mFeatureFlags).autoDataPruneListener(); } @After Loading Loading @@ -721,6 +726,184 @@ public class AutoDataSwitchControllerTest extends TelephonyTest { } } @Test public void testDataSettingsChangedUpdateListener() { setDefaultDataSubId(SUB_1); // Phone 1 is default int modemCount = mPhones.length; // Should be 2 // Pre-condition: Assume listeners are registered initially (cleared invocations in setUp) // --- Scenario 1: Disable Default Phone User Data --- logd("Scenario 1: Disable Default Phone User Data"); doReturn(false).when(mPhone).isUserDataEnabled(); mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(EVALUATION_REASON_DATA_SETTINGS_CHANGED); processAllMessages(); // Verify unregister calls for *both* phones verify(mDisplayInfoController, times(modemCount)) .unregisterForTelephonyDisplayInfoChanged(any()); verify(mSignalStrengthController, times(modemCount)).unregisterForSignalStrengthChanged( any()); verify(mSST, times(modemCount)).unregisterForServiceStateChanged(any()); // Verify register calls were NOT made verify(mDisplayInfoController, never()).registerForTelephonyDisplayInfoChanged( any(), anyInt(), any()); verify(mSignalStrengthController, never()).registerForSignalStrengthChanged( any(), anyInt(), any()); verify(mSST, never()).registerForServiceStateChanged(any(), anyInt(), any()); clearInvocations(mDisplayInfoController, mSignalStrengthController, mSST); // --- Scenario 2: Re-enable Default Phone User Data --- logd("Scenario 2: Re-enable Default Phone User Data"); doReturn(true).when(mPhone).isUserDataEnabled(); mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(EVALUATION_REASON_DATA_SETTINGS_CHANGED); processAllMessages(); // Verify register calls for *both* phones verify(mDisplayInfoController, times(modemCount)).registerForTelephonyDisplayInfoChanged( any(), eq(EVENT_DISPLAY_INFO_CHANGED), any()); verify(mSignalStrengthController, times(modemCount)).registerForSignalStrengthChanged( any(), eq(EVENT_SIGNAL_STRENGTH_CHANGED), any()); verify(mSST, times(modemCount)).registerForServiceStateChanged( any(), eq(EVENT_SERVICE_STATE_CHANGED), any()); // Verify unregister calls were NOT made verify(mDisplayInfoController, never()).unregisterForTelephonyDisplayInfoChanged(any()); verify(mSignalStrengthController, never()).unregisterForSignalStrengthChanged(any()); verify(mSST, never()).unregisterForServiceStateChanged(any()); clearInvocations(mDisplayInfoController, mSignalStrengthController, mSST); // Reset // --- Scenario 3: Disable *Only* Candidate Phone Data Setting --- logd("Scenario 3: Disable *Only* Candidate Phone Data Setting"); doReturn(true).when(mPhone).isUserDataEnabled(); // Ensure default is enabled doReturn(false).when(mDataSettingsManager).isDataEnabled(); // Disable candidate mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(EVALUATION_REASON_DATA_SETTINGS_CHANGED); processAllMessages(); // Verify unregister calls for *both* phones (as no candidates left) verify(mDisplayInfoController, times(modemCount)) .unregisterForTelephonyDisplayInfoChanged(any()); verify(mSignalStrengthController, times(modemCount)) .unregisterForSignalStrengthChanged(any()); verify(mSST, times(modemCount)).unregisterForServiceStateChanged(any()); // Verify register calls were NOT made verify(mDisplayInfoController, never()) .registerForTelephonyDisplayInfoChanged(any(), anyInt(), any()); verify(mSignalStrengthController, never()) .registerForSignalStrengthChanged(any(), anyInt(), any()); verify(mSST, never()).registerForServiceStateChanged(any(), anyInt(), any()); clearInvocations(mDisplayInfoController, mSignalStrengthController, mSST); // Reset // --- Scenario 4: Re-enable Candidate Phone Data Setting --- logd("Scenario 4: Re-enable Candidate Phone Data Setting"); doReturn(true).when(mDataSettingsManager).isDataEnabled(); mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(EVALUATION_REASON_DATA_SETTINGS_CHANGED); processAllMessages(); // Verify register calls for *both* phones verify(mDisplayInfoController, times(modemCount)).registerForTelephonyDisplayInfoChanged( any(), eq(EVENT_DISPLAY_INFO_CHANGED), any()); verify(mSignalStrengthController, times(modemCount)).registerForSignalStrengthChanged( any(), eq(EVENT_SIGNAL_STRENGTH_CHANGED), any()); verify(mSST, times(modemCount)).registerForServiceStateChanged( any(), eq(EVENT_SERVICE_STATE_CHANGED), any()); // Verify unregister calls were NOT made verify(mDisplayInfoController, never()).unregisterForTelephonyDisplayInfoChanged(any()); verify(mSignalStrengthController, never()).unregisterForSignalStrengthChanged(any()); verify(mSST, never()).unregisterForServiceStateChanged(any()); } @Test public void testDefaultNetworkChangedUpdateListener() { setDefaultDataSubId(SUB_1); // Phone 1 is default int modemCount = mPhones.length; // Should be 2 // Pre-condition: Assume listeners are registered initially (cleared invocations in setUp) // --- Scenario 1: Default network becomes non-cellular (WIFI) --- logd("Scenario 1: Default network becomes WIFI"); NetworkCapabilities wifiCapabilities = new NetworkCapabilities(); wifiCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); mAutoDataSwitchControllerUT.updateDefaultNetworkCapabilities(wifiCapabilities); mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(AutoDataSwitchController .EVALUATION_REASON_DEFAULT_NETWORK_CHANGED); processAllMessages(); // Verify unregister calls for *both* phones verify(mDisplayInfoController, times(modemCount)) .unregisterForTelephonyDisplayInfoChanged(any()); verify(mSignalStrengthController, times(modemCount)) .unregisterForSignalStrengthChanged(any()); verify(mSST, times(modemCount)).unregisterForServiceStateChanged(any()); // Verify register calls were NOT made verify(mDisplayInfoController, never()).registerForTelephonyDisplayInfoChanged( any(), anyInt(), any()); verify(mSignalStrengthController, never()).registerForSignalStrengthChanged( any(), anyInt(), any()); verify(mSST, never()).registerForServiceStateChanged(any(), anyInt(), any()); clearInvocations(mDisplayInfoController, mSignalStrengthController, mSST); // Reset // --- Scenario 2: Default network becomes cellular --- logd("Scenario 2: Default network becomes CELLULAR"); NetworkCapabilities cellularCapabilities = new NetworkCapabilities(); cellularCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); mAutoDataSwitchControllerUT.updateDefaultNetworkCapabilities(cellularCapabilities); mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(AutoDataSwitchController .EVALUATION_REASON_DEFAULT_NETWORK_CHANGED); processAllMessages(); // Verify register calls for *both* phones verify(mDisplayInfoController, times(modemCount)).registerForTelephonyDisplayInfoChanged( any(), eq(EVENT_DISPLAY_INFO_CHANGED), any()); verify(mSignalStrengthController, times(modemCount)).registerForSignalStrengthChanged(any(), eq(EVENT_SIGNAL_STRENGTH_CHANGED), any()); verify(mSST, times(modemCount)).registerForServiceStateChanged(any(), eq(EVENT_SERVICE_STATE_CHANGED), any()); // Verify unregister calls were NOT made verify(mDisplayInfoController, never()).unregisterForTelephonyDisplayInfoChanged(any()); verify(mSignalStrengthController, never()).unregisterForSignalStrengthChanged(any()); verify(mSST, never()).unregisterForServiceStateChanged(any()); clearInvocations(mDisplayInfoController, mSignalStrengthController, mSST); // Reset // --- Scenario 3: Default network lost (null) --- logd("Scenario 3: Default network lost (null)"); // First switch to non-cellular to ensure listeners are off mAutoDataSwitchControllerUT.updateDefaultNetworkCapabilities(wifiCapabilities); mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(AutoDataSwitchController .EVALUATION_REASON_DEFAULT_NETWORK_CHANGED); processAllMessages(); verify(mDisplayInfoController, times(modemCount)) .unregisterForTelephonyDisplayInfoChanged(any()); verify(mSignalStrengthController, times(modemCount)) .unregisterForSignalStrengthChanged(any()); verify(mSST, times(modemCount)) .unregisterForServiceStateChanged(any()); clearInvocations(mDisplayInfoController, mSignalStrengthController, mSST); // Now lose the network mAutoDataSwitchControllerUT.updateDefaultNetworkCapabilities(null); mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(AutoDataSwitchController .EVALUATION_REASON_DEFAULT_NETWORK_CHANGED); processAllMessages(); // Verify register calls for *both* phones (null network means cellular is possible) verify(mDisplayInfoController, times(modemCount)).registerForTelephonyDisplayInfoChanged( any(), eq(EVENT_DISPLAY_INFO_CHANGED), any()); verify(mSignalStrengthController, times(modemCount)).registerForSignalStrengthChanged(any(), eq(EVENT_SIGNAL_STRENGTH_CHANGED), any()); verify(mSST, times(modemCount)).registerForServiceStateChanged(any(), eq(EVENT_SERVICE_STATE_CHANGED), any()); verify(mDisplayInfoController, never()) .unregisterForTelephonyDisplayInfoChanged(any()); verify(mSignalStrengthController, never()).unregisterForSignalStrengthChanged(any()); verify(mSST, never()).unregisterForServiceStateChanged(any()); } @Test public void testRatSignalStrengthSkipEvaluation() { // Verify the secondary phone is OOS and its score(0) is too low to justify the evaluation Loading Loading @@ -764,6 +947,7 @@ public class AutoDataSwitchControllerTest extends TelephonyTest { // 4.2 Auto switch feature is enabled doReturn(true).when(mPhone2).getDataRoamingEnabled(); doReturn(true).when(mDataSettingsManager).isDataEnabled(); mDataEvaluation.addDataAllowedReason(DataEvaluation.DataAllowedReason.NORMAL); // 5. No default network Loading