diff options
author | 2025-02-04 22:50:29 +0000 | |
---|---|---|
committer | 2025-02-07 13:11:04 -0800 | |
commit | ea553ee622c3181b2f85c77c74e09d6c6ea5a91b (patch) | |
tree | 9ebc4d6c3b570d5eeff1cc3eff3b0b627389a8bb | |
parent | 32a8b6b9dddc0411681e0aa6d38f096789a04b94 (diff) |
wifi: Using registerReceiverForAllUsers
To ensure correct Wi-Fi functionality after a user switch, system status settings are now retrieved using registerReceiverForAllUsers. Previously, registering the intent before the switch resulted in incorrect settings.
Fix for intents:
ACTION_AIRPLANE_MODE_CHANGED
ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
ACTION_EMERGENCY_CALL_STATE_CHANGED
Flag: com.android.wifi.flags.monitor_intent_for_all_users
Bug: 390257834
Test: atest -c FrameworksWifiTests
Test: Manuel test
Change-Id: I6e877dae2aa7e2dc90316ab7fdfb4ec849a1dd63
-rw-r--r-- | flags/wifi_flags.aconfig | 9 | ||||
-rw-r--r-- | service/java/com/android/server/wifi/ActiveModeWarden.java | 59 | ||||
-rw-r--r-- | service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java | 103 |
3 files changed, 153 insertions, 18 deletions
diff --git a/flags/wifi_flags.aconfig b/flags/wifi_flags.aconfig index c7ee13a665..edaf96cd37 100644 --- a/flags/wifi_flags.aconfig +++ b/flags/wifi_flags.aconfig @@ -273,3 +273,12 @@ flag { bug: "382023801" is_fixed_read_only: true } + +flag { + name: "monitor_intent_for_all_users" + is_exported: false + namespace: "wifi" + description: "IntentReceiver should monitor intent from all users" + bug: "390257834" + is_fixed_read_only: true +} diff --git a/service/java/com/android/server/wifi/ActiveModeWarden.java b/service/java/com/android/server/wifi/ActiveModeWarden.java index 9e6845f47b..0505504aa2 100644 --- a/service/java/com/android/server/wifi/ActiveModeWarden.java +++ b/service/java/com/android/server/wifi/ActiveModeWarden.java @@ -95,6 +95,7 @@ import com.android.server.wifi.util.ApConfigUtil; import com.android.server.wifi.util.LastCallerInfoManager; import com.android.server.wifi.util.NativeUtil; import com.android.server.wifi.util.WifiPermissionsUtil; +import com.android.wifi.flags.FeatureFlags; import com.android.wifi.resources.R; import java.io.FileDescriptor; @@ -148,6 +149,7 @@ public class ActiveModeWarden { private final UserManager mUserManager; private final LastCallerInfoManager mLastCallerInfoManager; private final WifiGlobals mWifiGlobals; + private final FeatureFlags mFeatureFlags; private WifiServiceImpl.SoftApCallbackInternal mSoftApCallback; private WifiServiceImpl.SoftApCallbackInternal mLohsCallback; @@ -447,6 +449,7 @@ public class ActiveModeWarden { mUserManager = mWifiInjector.getUserManager(); mLastCallerInfoManager = mWifiInjector.getLastCallerInfoManager(); mWifiGlobals = wifiGlobals; + mFeatureFlags = mWifiInjector.getDeviceConfigFacade().getFeatureFlags(); wifiNative.registerStatusListener(isReady -> { if (!isReady && !mIsShuttingdown) { @@ -715,15 +718,16 @@ public class ActiveModeWarden { /** Begin listening to broadcasts and start the internal state machine. */ public void start() { - mContext.registerReceiverForAllUsers(new BroadcastReceiver() { + BroadcastReceiver locationChangeReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // Location mode has been toggled... trigger with the scan change // update to make sure we are in the correct mode scanAlwaysModeChanged(); } - }, new IntentFilter(LocationManager.MODE_CHANGED_ACTION), null, mHandler); - mContext.registerReceiver(new BroadcastReceiver() { + }; + + BroadcastReceiver airplaneChangedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { boolean airplaneModeUpdated = mSettingsStore.updateAirplaneModeTracker(); @@ -736,26 +740,51 @@ public class ActiveModeWarden { airplaneModeToggled(); } } - }, new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED)); - mContext.registerReceiver(new BroadcastReceiver() { + }; + + BroadcastReceiver emergencyCallbackModeChangedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { boolean emergencyMode = intent.getBooleanExtra(TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, false); emergencyCallbackModeChanged(emergencyMode); } - }, new IntentFilter(TelephonyManager.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)); + }; + + BroadcastReceiver emergencyCallStateChangedReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + boolean inCall = intent.getBooleanExtra( + TelephonyManager.EXTRA_PHONE_IN_EMERGENCY_CALL, false); + emergencyCallStateChanged(inCall); + } + }; + + + mContext.registerReceiverForAllUsers(locationChangeReceiver, + new IntentFilter(LocationManager.MODE_CHANGED_ACTION), null, mHandler); boolean trackEmergencyCallState = mResourceCache.getBoolean( R.bool.config_wifi_turn_off_during_emergency_call); - if (trackEmergencyCallState) { - mContext.registerReceiver(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - boolean inCall = intent.getBooleanExtra( - TelephonyManager.EXTRA_PHONE_IN_EMERGENCY_CALL, false); - emergencyCallStateChanged(inCall); - } - }, new IntentFilter(TelephonyManager.ACTION_EMERGENCY_CALL_STATE_CHANGED)); + if (mFeatureFlags.monitorIntentForAllUsers()) { + mContext.registerReceiverForAllUsers(airplaneChangedReceiver, + new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED), null, mHandler); + mContext.registerReceiverForAllUsers(emergencyCallbackModeChangedReceiver, + new IntentFilter(TelephonyManager.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED), + null, mHandler); + if (trackEmergencyCallState) { + mContext.registerReceiverForAllUsers(emergencyCallStateChangedReceiver, + new IntentFilter(TelephonyManager.ACTION_EMERGENCY_CALL_STATE_CHANGED), + null, mHandler); + } + } else { + mContext.registerReceiver(airplaneChangedReceiver, + new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED)); + mContext.registerReceiver(emergencyCallbackModeChangedReceiver, + new IntentFilter(TelephonyManager.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)); + if (trackEmergencyCallState) { + mContext.registerReceiver(emergencyCallStateChangedReceiver, + new IntentFilter(TelephonyManager.ACTION_EMERGENCY_CALL_STATE_CHANGED)); + } } mWifiGlobals.setD2dStaConcurrencySupported( mWifiNative.isP2pStaConcurrencySupported() diff --git a/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java b/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java index 424ceb69ed..92c8bc8206 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java @@ -113,6 +113,7 @@ import com.android.server.wifi.ActiveModeWarden.ExternalClientModeManagerRequest import com.android.server.wifi.util.GeneralUtil.Mutable; import com.android.server.wifi.util.LastCallerInfoManager; import com.android.server.wifi.util.WifiPermissionsUtil; +import com.android.wifi.flags.FeatureFlags; import com.android.wifi.resources.R; import org.junit.After; @@ -204,6 +205,8 @@ public class ActiveModeWardenTest extends WifiBaseTest { @Mock WifiConnectivityManager mWifiConnectivityManager; @Mock WifiConfigManager mWifiConfigManager; @Mock WakeupController mWakeupController; + @Mock DeviceConfigFacade mDeviceConfigFacade; + @Mock FeatureFlags mFeatureFlags; Listener<ConcreteClientModeManager> mClientListener; Listener<SoftApManager> mSoftApListener; @@ -248,6 +251,8 @@ public class ActiveModeWardenTest extends WifiBaseTest { when(mClientModeManager.getInterfaceName()).thenReturn(WIFI_IFACE_NAME); when(mContext.getResourceCache()).thenReturn(mWifiResourceCache); when(mSoftApManager.getRole()).thenReturn(ROLE_SOFTAP_TETHERED); + when(mWifiInjector.getDeviceConfigFacade()).thenReturn(mDeviceConfigFacade); + when(mDeviceConfigFacade.getFeatureFlags()).thenReturn(mFeatureFlags); when(mWifiResourceCache.getString(R.string.wifi_localhotspot_configure_ssid_default)) .thenReturn("AndroidShare"); @@ -1599,6 +1604,21 @@ public class ActiveModeWardenTest extends WifiBaseTest { */ @Test public void testWifiStateUnaffectedByAirplaneMode() throws Exception { + when(mFeatureFlags.monitorIntentForAllUsers()).thenReturn(false); + verifyWifiStateUnaffectedByAirplaneMode(false); + } + + /** + * Same as #testWifiStateUnaffectedByAirplaneMode but monitoring intent by RegisterForAllUsers. + */ + @Test + public void testWifiStateUnaffectedByAirplaneModeWithRegisterForAllUsers() throws Exception { + when(mFeatureFlags.monitorIntentForAllUsers()).thenReturn(true); + verifyWifiStateUnaffectedByAirplaneMode(true); + } + + private void verifyWifiStateUnaffectedByAirplaneMode(boolean isMonitorIntentForAllUsersEnabled) + throws Exception { assumeTrue(SdkLevel.isAtLeastT()); when(mUserManager.hasUserRestrictionForUser(eq(UserManager.DISALLOW_CHANGE_WIFI_STATE), any())).thenReturn(true); @@ -1612,9 +1632,16 @@ public class ActiveModeWardenTest extends WifiBaseTest { ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = ArgumentCaptor.forClass(BroadcastReceiver.class); - verify(mContext).registerReceiver( - bcastRxCaptor.capture(), - argThat(filter -> filter.hasAction(Intent.ACTION_AIRPLANE_MODE_CHANGED))); + if (isMonitorIntentForAllUsersEnabled) { + verify(mContext).registerReceiverForAllUsers( + bcastRxCaptor.capture(), + argThat(filter -> filter.hasAction(Intent.ACTION_AIRPLANE_MODE_CHANGED)), + eq(null), any(Handler.class)); + } else { + verify(mContext).registerReceiver( + bcastRxCaptor.capture(), + argThat(filter -> filter.hasAction(Intent.ACTION_AIRPLANE_MODE_CHANGED))); + } BroadcastReceiver broadcastReceiver = bcastRxCaptor.getValue(); Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); @@ -1752,6 +1779,37 @@ public class ActiveModeWardenTest extends WifiBaseTest { * When in Client mode, make sure ECM triggers wifi shutdown. */ @Test + public void testEcmReceiverFromClientModeWithRegisterForAllUsers() + throws Exception { + when(mFeatureFlags.monitorIntentForAllUsers()).thenReturn(true); + ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = + ArgumentCaptor.forClass(BroadcastReceiver.class); + mActiveModeWarden = createActiveModeWarden(); + mActiveModeWarden.start(); + mLooper.dispatchAll(); + verify(mContext).registerReceiverForAllUsers( + bcastRxCaptor.capture(), + argThat(filter -> + filter.hasAction(TelephonyManager.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)), + eq(null), any(Handler.class)); + mEmergencyCallbackModeChangedBr = bcastRxCaptor.getValue(); + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); + enableWifi(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + + assertWifiShutDown(() -> { + // test ecm changed + emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + } + + /** + * When in Client mode, make sure ECM triggers wifi shutdown. + */ + @Test public void testEcmOnFromClientMode() throws Exception { when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); enableWifi(); @@ -1977,6 +2035,45 @@ public class ActiveModeWardenTest extends WifiBaseTest { }); } + /** + * Updates about call state change also trigger entry of ECM mode. + */ + @Test + public void testEnterEcmOnEmergencyCallStateChangeWithRegisterForAllUsers() + throws Exception { + when(mFeatureFlags.monitorIntentForAllUsers()).thenReturn(true); + ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = + ArgumentCaptor.forClass(BroadcastReceiver.class); + mActiveModeWarden = createActiveModeWarden(); + mActiveModeWarden.start(); + mLooper.dispatchAll(); + verify(mContext).registerReceiverForAllUsers( + bcastRxCaptor.capture(), + argThat(filter -> + filter.hasAction(TelephonyManager.ACTION_EMERGENCY_CALL_STATE_CHANGED)), + eq(null), any(Handler.class)); + mEmergencyCallStateChangedBr = bcastRxCaptor.getValue(); + assertInDisabledState(); + + enableWifi(); + assertInEnabledState(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + + assertEnteredEcmMode(() -> { + // test call state changed + emergencyCallStateChanged(true); + mLooper.dispatchAll(); + mClientListener.onStopped(mClientModeManager); + mLooper.dispatchAll(); + }); + + emergencyCallStateChanged(false); + mLooper.dispatchAll(); + + assertInEnabledState(); + } /** * Updates about call state change also trigger entry of ECM mode. |