diff options
3 files changed, 100 insertions, 6 deletions
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java index 20db7fdfd..29c14d272 100644 --- a/service/java/com/android/server/wifi/ClientModeImpl.java +++ b/service/java/com/android/server/wifi/ClientModeImpl.java @@ -2480,6 +2480,7 @@ public class ClientModeImpl extends StateMachine { mWifiMetrics.setScreenState(screenOn); mWifiConnectivityManager.handleScreenStateChanged(screenOn); + mNetworkFactory.handleScreenStateChanged(screenOn); if (mVerboseLoggingEnabled) log("handleScreenStateChanged Exit: " + screenOn); } diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java index 369e36cb5..46a640aeb 100644 --- a/service/java/com/android/server/wifi/WifiNetworkFactory.java +++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java @@ -98,6 +98,7 @@ public class WifiNetworkFactory extends NetworkFactory { private boolean mPeriodicScanTimerSet = false; private boolean mConnectionTimeoutSet = false; private boolean mIsConnectedToUserSelectedNetwork = false; + private boolean mIsPeriodicScanPaused = false; // Scan listener for scan requests. private class NetworkFactoryScanListener implements WifiScanner.ScanListener { @@ -564,6 +565,26 @@ public class WifiNetworkFactory extends NetworkFactory { resetStateForActiveRequestEnd(); } + /** + * Invoked by {@link ClientModeImpl} to indicate screen state changes. + */ + public void handleScreenStateChanged(boolean screenOn) { + // If there is no active request or if the user has already selected a network, + // ignore screen state changes. + if (mActiveSpecificNetworkRequest == null || mUserSelectedNetwork != null) return; + + // Pause periodic scans when the screen is off & resume when the screen is on. + if (screenOn) { + if (mVerboseLoggingEnabled) Log.v(TAG, "Resuming scans on screen on"); + startScan(); + mIsPeriodicScanPaused = false; + } else { + if (mVerboseLoggingEnabled) Log.v(TAG, "Pausing scans on screen off"); + cancelPeriodicScans(); + mIsPeriodicScanPaused = true; + } + } + private void resetState() { if (mIsConnectedToUserSelectedNetwork) { Log.i(TAG, "Disconnecting from network on reset"); @@ -583,6 +604,7 @@ public class WifiNetworkFactory extends NetworkFactory { mUserSelectedNetwork = null; mUserSelectedNetworkConnectRetryCount = 0; mIsConnectedToUserSelectedNetwork = false; + mIsPeriodicScanPaused = false; cancelPeriodicScans(); cancelConnectionTimeout(); // Remove any callbacks registered for the request. @@ -668,6 +690,10 @@ public class WifiNetworkFactory extends NetworkFactory { } private void scheduleNextPeriodicScan() { + if (mIsPeriodicScanPaused) { + Log.e(TAG, "Scan triggered when periodic scanning paused. Ignoring..."); + return; + } mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mClock.getElapsedSinceBootMillis() + PERIODIC_SCAN_INTERVAL_MS, TAG, mPeriodicScanTimerListener, mHandler); diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java index ee9526017..d96247300 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java @@ -114,6 +114,8 @@ public class WifiNetworkFactoryTest { ArgumentCaptor.forClass(OnAlarmListener.class); ArgumentCaptor<OnAlarmListener> mConnectionTimeoutAlarmListenerArgumentCaptor = ArgumentCaptor.forClass(OnAlarmListener.class); + ArgumentCaptor<ScanListener> mScanListenerArgumentCaptor = + ArgumentCaptor.forClass(ScanListener.class); InOrder mInOrder; private WifiNetworkFactory mWifiNetworkFactory; @@ -1236,6 +1238,73 @@ public class WifiNetworkFactoryTest { verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false); } + /** + * Verify handling of screen state changes while triggering periodic scans to find matching + * networks. + */ + @Test + public void testNetworkSpecifierHandleScreenStateChangedWhileScanning() throws Exception { + sendNetworkRequestAndSetupForUserSelection(); + + // Turn off screen. + mWifiNetworkFactory.handleScreenStateChanged(false); + + // 1. Cancel the scan timer. + mInOrder.verify(mAlarmManager).cancel( + mPeriodicScanListenerArgumentCaptor.getValue()); + // 2. Simulate the scan results from an ongoing scan, ensure no more scans are scheduled. + mScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas); + + // Ensure no more interactions. + mInOrder.verifyNoMoreInteractions(); + + // Now, turn the screen on. + mWifiNetworkFactory.handleScreenStateChanged(true); + + // Verify that we resumed periodic scanning. + mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); + } + + /** + * Verify handling of screen state changes after the active network request was released. + */ + @Test + public void testNetworkSpecifierHandleScreenStateChangedWithoutActiveRequest() + throws Exception { + sendNetworkRequestAndSetupForUserSelection(); + // Now release the active network request. + mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest); + // Cancel the scan timer on release. + mInOrder.verify(mAlarmManager).cancel( + mPeriodicScanListenerArgumentCaptor.getValue()); + + // Turn off screen. + mWifiNetworkFactory.handleScreenStateChanged(false); + + // Now, turn the screen on. + mWifiNetworkFactory.handleScreenStateChanged(true); + + // Ensure that we did not pause or resume scanning. + mInOrder.verifyNoMoreInteractions(); + } + + /** + * Verify handling of screen state changes after user selected a network to connect to. + */ + @Test + public void testNetworkSpecifierHandleScreenStateChangedAfterUserSelection() throws Exception { + sendNetworkRequestAndSetupForConnectionStatus(); + + // Turn off screen. + mWifiNetworkFactory.handleScreenStateChanged(false); + + // Now, turn the screen on. + mWifiNetworkFactory.handleScreenStateChanged(true); + + // Ensure that we did not pause or resume scanning. + mInOrder.verifyNoMoreInteractions(); + } + // Helper method to setup the necessary pre-requisite steps for tracking connection status. private Messenger sendNetworkRequestAndSetupForConnectionStatus() throws RemoteException { when(mClock.getElapsedSinceBootMillis()).thenReturn(0L); @@ -1252,7 +1321,7 @@ public class WifiNetworkFactoryTest { mLooper.dispatchAll(); // Cancel the periodic scan timer. - verify(mAlarmManager).cancel(mPeriodicScanListenerArgumentCaptor.getValue()); + mInOrder.verify(mAlarmManager).cancel(mPeriodicScanListenerArgumentCaptor.getValue()); // Disable connectivity manager verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(true); @@ -1263,7 +1332,7 @@ public class WifiNetworkFactoryTest { assertNotNull(message); // Start the connection timeout alarm. - verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), + mInOrder.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), eq((long) WifiNetworkFactory.NETWORK_CONNECTION_TIMEOUT_MS), any(), mConnectionTimeoutAlarmListenerArgumentCaptor.capture(), any()); assertNotNull(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue()); @@ -1309,8 +1378,6 @@ public class WifiNetworkFactoryTest { when(mClock.getElapsedSinceBootMillis()).thenReturn(0L); OnAlarmListener alarmListener = null; - ArgumentCaptor<ScanListener> scanListenerArgumentCaptor = - ArgumentCaptor.forClass(ScanListener.class); ScanListener scanListener = null; mInOrder = inOrder(mWifiScanner, mAlarmManager); @@ -1324,8 +1391,8 @@ public class WifiNetworkFactoryTest { alarmListener.onAlarm(); } mInOrder.verify(mWifiScanner).startScan( - any(), scanListenerArgumentCaptor.capture(), any()); - scanListener = scanListenerArgumentCaptor.getValue(); + any(), mScanListenerArgumentCaptor.capture(), any()); + scanListener = mScanListenerArgumentCaptor.getValue(); assertNotNull(scanListener); // Now trigger the scan results callback and verify the alarm set for the next scan. |