From 4f11976612567e57eefb0b58c7aef1059f52b45c Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Mon, 29 Jan 2018 22:57:09 -0800 Subject: ScanRequestProxy: Add scan throttling This is a port of the existing scan throttling for background apps in WifiServiceImpl. We're now going to throttle all external scan requests, except for requests coming in from apps holding NETWORK_SETTINGS permission. TODO: WifiServiceImpl.startScan() should return the status from ScanRequestProxy.startScan(). Bug: 68987915 Test: Unit tests Test: Scans from settings UI still works. Change-Id: Ib388752df554de85ca5c29e424b344ef07a7d5b2 Merged-In: I78e4113317b9835dec6e816f2c5a0ba309d73061 --- .../android/server/wifi/ScanRequestProxyTest.java | 155 ++++++++++++++++++--- .../android/server/wifi/WifiServiceImplTest.java | 97 +------------ 2 files changed, 137 insertions(+), 115 deletions(-) (limited to 'tests') diff --git a/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java b/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java index 759fbe27b..aa7a821eb 100644 --- a/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java @@ -47,6 +47,8 @@ import java.util.List; @SmallTest public class ScanRequestProxyTest { private static final int TEST_UID = 5; + private static final String TEST_PACKAGE_NAME_1 = "com.test.1"; + private static final String TEST_PACKAGE_NAME_2 = "com.test.2"; private static final List TEST_HIDDEN_NETWORKS_LIST = new ArrayList() {{ add(new WifiScanner.ScanSettings.HiddenNetwork("test_ssid_1")); @@ -59,6 +61,7 @@ public class ScanRequestProxyTest { @Mock private WifiConfigManager mWifiConfigManager; @Mock private WifiScanner mWifiScanner; @Mock private WifiPermissionsUtil mWifiPermissionsUtil; + @Mock private Clock mClock; private ArgumentCaptor mWorkSourceArgumentCaptor = ArgumentCaptor.forClass(WorkSource.class); private ArgumentCaptor mScanSettingsArgumentCaptor = @@ -87,7 +90,8 @@ public class ScanRequestProxyTest { mTestScanDatas2 = ScanTestUtil.createScanDatas(new int[][]{ { 2412, 2422, 5200, 5210 } }); mScanRequestProxy = - new ScanRequestProxy(mContext, mWifiInjector, mWifiConfigManager, mWifiPermissionsUtil); + new ScanRequestProxy(mContext, mWifiInjector, mWifiConfigManager, + mWifiPermissionsUtil, mClock); } @After @@ -101,8 +105,8 @@ public class ScanRequestProxyTest { @Test public void testStartScanFailWithoutScanner() { when(mWifiInjector.getWifiScanner()).thenReturn(null); - assertFalse(mScanRequestProxy.startScan(TEST_UID)); - validateScanResultsAvailableBroadcastSent(false); + assertFalse(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); + validateScanResultsFailureBroadcastSent(TEST_PACKAGE_NAME_1); verifyNoMoreInteractions(mWifiScanner, mWifiConfigManager, mContext); } @@ -112,7 +116,7 @@ public class ScanRequestProxyTest { */ @Test public void testStartScanSuccess() { - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); assertTrue(mWorkSourceArgumentCaptor.getValue().equals(new WorkSource(TEST_UID))); @@ -127,7 +131,7 @@ public class ScanRequestProxyTest { @Test public void testStartScanSuccessFromAppWithNetworkSettings() { when(mWifiPermissionsUtil.checkNetworkSettingsPermission(TEST_UID)).thenReturn(true); - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); assertTrue(mWorkSourceArgumentCaptor.getValue().equals(new WorkSource(TEST_UID))); @@ -143,7 +147,7 @@ public class ScanRequestProxyTest { @Test public void testStartScanWithHiddenNetworkScanningDisabled() { mScanRequestProxy.enableScanningForHiddenNetworks(false); - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); mInOrder.verify(mWifiConfigManager, never()).retrieveHiddenNetworkList(); mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); @@ -159,7 +163,7 @@ public class ScanRequestProxyTest { @Test public void testStartScanWithHiddenNetworkScanningEnabled() { mScanRequestProxy.enableScanningForHiddenNetworks(true); - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); mInOrder.verify(mWifiConfigManager).retrieveHiddenNetworkList(); mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); @@ -213,7 +217,7 @@ public class ScanRequestProxyTest { @Test public void testScanSuccessOverwritesPreviousResults() { // Make scan request 1. - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); // Verify the scan results processing for request 1. mScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1); @@ -224,7 +228,7 @@ public class ScanRequestProxyTest { mScanRequestProxy.getScanResults().stream().toArray(ScanResult[]::new)); // Make scan request 2. - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2)); mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); // Verify the scan results processing for request 2. mScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas2); @@ -243,7 +247,7 @@ public class ScanRequestProxyTest { @Test public void testScanFailureDoesNotOverwritePreviousResults() { // Make scan request 1. - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); // Verify the scan results processing for request 1. mScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1); @@ -254,7 +258,7 @@ public class ScanRequestProxyTest { mScanRequestProxy.getScanResults().stream().toArray(ScanResult[]::new)); // Make scan request 2. - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2)); mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); // Verify the scan failure processing. mScanListenerArgumentCaptor.getValue().onFailure(0, "failed"); @@ -277,12 +281,12 @@ public class ScanRequestProxyTest { WifiScanner.ScanListener listener1; WifiScanner.ScanListener listener2; // Make scan request 1. - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); listener1 = mScanListenerArgumentCaptor.getValue(); // Make scan request 2. - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2)); // Ensure that we did send a second scan request to scanner. mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); listener2 = mScanListenerArgumentCaptor.getValue(); @@ -314,7 +318,7 @@ public class ScanRequestProxyTest { @Test public void testNewScanRequestAfterPreviousScanSucceeds() { // Make scan request 1. - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); // Now send the scan results for request 1. mScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1); @@ -325,7 +329,7 @@ public class ScanRequestProxyTest { mScanRequestProxy.getScanResults().stream().toArray(ScanResult[]::new)); // Make scan request 2. - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2)); // Ensure that we did send a second scan request to scanner. mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); // Now send the scan results for request 2. @@ -347,7 +351,7 @@ public class ScanRequestProxyTest { @Test public void testNewScanRequestAfterPreviousScanSucceedsWithInvalidScanDatas() { // Make scan request 1. - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); // Now send scan success for request 1, but with invalid scan datas. @@ -358,7 +362,7 @@ public class ScanRequestProxyTest { assertTrue(mScanRequestProxy.getScanResults().isEmpty()); // Make scan request 2. - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2)); // Ensure that we did send a second scan request to scanner. mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); // Now send the scan results for request 2. @@ -380,7 +384,7 @@ public class ScanRequestProxyTest { @Test public void testNewScanRequestAfterPreviousScanFailure() { // Make scan request 1. - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); // Now send scan failure for request 1. @@ -390,7 +394,7 @@ public class ScanRequestProxyTest { assertTrue(mScanRequestProxy.getScanResults().isEmpty()); // Make scan request 2. - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2)); // Ensure that we did send a second scan request to scanner. mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); // Now send the scan results for request 2. @@ -410,7 +414,7 @@ public class ScanRequestProxyTest { @Test public void testClearScanResults() { // Make scan request 1. - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); // Verify the scan results processing for request 1. mScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1); @@ -433,12 +437,12 @@ public class ScanRequestProxyTest { WifiScanner.ScanListener listener1; WifiScanner.ScanListener listener2; // Make scan request 1. - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); listener1 = mScanListenerArgumentCaptor.getValue(); // Make scan request 2. - assertTrue(mScanRequestProxy.startScan(TEST_UID)); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2)); // Ensure that we did send a second scan request to scanner. mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); listener2 = mScanListenerArgumentCaptor.getValue(); @@ -448,6 +452,96 @@ public class ScanRequestProxyTest { verifyNoMoreInteractions(mWifiScanner, mWifiConfigManager, mContext); } + /** + * Ensure new scan requests from the same app are rejected if it's before + * {@link ScanRequestProxy#SCAN_REQUEST_THROTTLE_INTERVAL_MS} + */ + @Test + public void testSuccessiveScanRequestFromSameAppThrottled() { + long firstRequestMs = 782; + when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs); + // Make scan request 1. + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); + mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); + + long secondRequestMs = + firstRequestMs + ScanRequestProxy.SCAN_REQUEST_THROTTLE_INTERVAL_MS - 1; + when(mClock.getElapsedSinceBootMillis()).thenReturn(secondRequestMs); + // Make scan request 2 from the same package name & ensure that it is throttled. + assertFalse(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); + validateScanResultsFailureBroadcastSent(TEST_PACKAGE_NAME_1); + + verifyNoMoreInteractions(mWifiScanner, mWifiConfigManager, mContext); + } + + /** + * Ensure new scan requests from the same app are not rejected if it's after + * {@link ScanRequestProxy#SCAN_REQUEST_THROTTLE_INTERVAL_MS} + */ + @Test + public void testSuccessiveScanRequestFromSameAppNotThrottled() { + long firstRequestMs = 782; + when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs); + // Make scan request 1. + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); + mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); + + long secondRequestMs = + firstRequestMs + ScanRequestProxy.SCAN_REQUEST_THROTTLE_INTERVAL_MS + 1; + when(mClock.getElapsedSinceBootMillis()).thenReturn(secondRequestMs); + // Make scan request 2 from the same package name & ensure that it is not throttled. + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); + mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); + + verifyNoMoreInteractions(mWifiScanner, mWifiConfigManager, mContext); + } + + /** + * Ensure new scan requests from the same app with NETWORK_SETTINGS permission are not + * throttled. + */ + @Test + public void testSuccessiveScanRequestFromSameAppWithNetworkSettingsPermissionNotThrottled() { + when(mWifiPermissionsUtil.checkNetworkSettingsPermission(TEST_UID)).thenReturn(true); + + long firstRequestMs = 782; + when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs); + // Make scan request 1. + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); + mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); + + long secondRequestMs = + firstRequestMs + ScanRequestProxy.SCAN_REQUEST_THROTTLE_INTERVAL_MS - 1; + when(mClock.getElapsedSinceBootMillis()).thenReturn(secondRequestMs); + // Make scan request 2 from the same package name & ensure that it is not throttled. + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); + mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); + + verifyNoMoreInteractions(mWifiScanner, mWifiConfigManager, mContext); + } + + /** + * Ensure new scan requests from different apps are not throttled. + */ + @Test + public void testSuccessiveScanRequestFromDifferentAppsNotThrottled() { + long firstRequestMs = 782; + when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs); + // Make scan request 1. + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); + mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); + + // Make scan request 2 from the same package name & ensure that it is throttled. + assertFalse(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); + validateScanResultsFailureBroadcastSent(TEST_PACKAGE_NAME_1); + + // Make scan request 3 from a different package name & ensure that it is not throttled. + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2)); + mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); + + verifyNoMoreInteractions(mWifiScanner, mWifiConfigManager, mContext); + } + private void validateScanSettings(WifiScanner.ScanSettings scanSettings, boolean expectHiddenNetworks) { validateScanSettings(scanSettings, expectHiddenNetworks, false); @@ -502,4 +596,21 @@ public class ScanRequestProxyTest { boolean scanSucceeded = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false); assertEquals(expectScanSuceeded, scanSucceeded); } + + private void validateScanResultsFailureBroadcastSent(String expectedPackageName) { + ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); + ArgumentCaptor userHandleCaptor = ArgumentCaptor.forClass(UserHandle.class); + mInOrder.verify(mContext).sendBroadcastAsUser( + intentCaptor.capture(), userHandleCaptor.capture()); + + assertEquals(userHandleCaptor.getValue(), UserHandle.ALL); + + Intent intent = intentCaptor.getValue(); + assertEquals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION, intent.getAction()); + assertEquals(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT, intent.getFlags()); + boolean scanSucceeded = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false); + assertFalse(scanSucceeded); + String packageName = intent.getPackage(); + assertEquals(expectedPackageName, packageName); + } } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java index 6f99f5521..efd9b9fc0 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java @@ -89,7 +89,6 @@ import android.os.Process; import android.os.RemoteException; import android.os.UserManager; import android.os.test.TestLooper; -import android.provider.Settings; import android.support.test.filters.SmallTest; import com.android.internal.os.PowerProfile; @@ -126,9 +125,7 @@ public class WifiServiceImplTest { private static final String TAG = "WifiServiceImplTest"; private static final String SCAN_PACKAGE_NAME = "scanPackage"; - private static final String WHITE_LIST_SCAN_PACKAGE_NAME = "whiteListScanPackage"; private static final int DEFAULT_VERBOSE_LOGGING = 0; - private static final long WIFI_BACKGROUND_SCAN_INTERVAL = 10000; private static final String ANDROID_SYSTEM_PACKAGE = "android"; private static final String TEST_PACKAGE_NAME = "TestPackage"; private static final String SYSUI_PACKAGE_NAME = "com.android.systemui"; @@ -286,15 +283,6 @@ public class WifiServiceImplTest { anyBoolean(), any()); when(mContext.getSystemService(Context.ACTIVITY_SERVICE)).thenReturn(mActivityManager); when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager); - when(mFrameworkFacade.getLongSetting( - eq(mContext), - eq(Settings.Global.WIFI_SCAN_BACKGROUND_THROTTLE_INTERVAL_MS), - anyLong())) - .thenReturn(WIFI_BACKGROUND_SCAN_INTERVAL); - when(mFrameworkFacade.getStringSetting( - eq(mContext), - eq(Settings.Global.WIFI_SCAN_BACKGROUND_THROTTLE_PACKAGE_WHITELIST))) - .thenReturn(WHITE_LIST_SCAN_PACKAGE_NAME); IPowerManager powerManagerService = mock(IPowerManager.class); mPowerManager = new PowerManager(mContext, powerManagerService, new Handler()); when(mContext.getSystemServiceName(PowerManager.class)).thenReturn(Context.POWER_SERVICE); @@ -1028,80 +1016,6 @@ public class WifiServiceImplTest { mWifiServiceImpl.stopSoftAp(); } - /** - * Ensure foreground apps can always do wifi scans. - */ - @Test - public void testWifiScanStartedForeground() { - setupWifiStateMachineHandlerForRunWithScissors(); - - when(mActivityManager.getPackageImportance(SCAN_PACKAGE_NAME)).thenReturn( - ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE); - mWifiServiceImpl.startScan(null, null, SCAN_PACKAGE_NAME); - verify(mScanRequestProxy).startScan(Process.myUid()); - verifyCheckChangePermission(SCAN_PACKAGE_NAME); - } - - /** - * Ensure background apps get throttled when the previous scan is too close. - */ - @Test - public void testWifiScanBackgroundThrottled() { - setupWifiStateMachineHandlerForRunWithScissors(); - - when(mActivityManager.getPackageImportance(SCAN_PACKAGE_NAME)).thenReturn( - ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED); - long startMs = 1000; - when(mClock.getElapsedSinceBootMillis()).thenReturn(startMs); - mWifiServiceImpl.startScan(null, null, SCAN_PACKAGE_NAME); - verify(mScanRequestProxy).startScan(Process.myUid()); - - when(mClock.getElapsedSinceBootMillis()).thenReturn( - startMs + WIFI_BACKGROUND_SCAN_INTERVAL - 1000); - mWifiServiceImpl.startScan(null, null, SCAN_PACKAGE_NAME); - verify(mScanRequestProxy, times(1)).startScan(Process.myUid()); - } - - /** - * Ensure background apps can do wifi scan when the throttle interval reached. - */ - @Test - public void testWifiScanBackgroundNotThrottled() { - setupWifiStateMachineHandlerForRunWithScissors(); - - when(mActivityManager.getPackageImportance(SCAN_PACKAGE_NAME)).thenReturn( - ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED); - long startMs = 1000; - when(mClock.getElapsedSinceBootMillis()).thenReturn(startMs); - mWifiServiceImpl.startScan(null, null, SCAN_PACKAGE_NAME); - verify(mScanRequestProxy).startScan(Process.myUid()); - - when(mClock.getElapsedSinceBootMillis()).thenReturn( - startMs + WIFI_BACKGROUND_SCAN_INTERVAL + 1000); - mWifiServiceImpl.startScan(null, null, SCAN_PACKAGE_NAME); - verify(mScanRequestProxy, times(2)).startScan(Process.myUid()); - } - - /** - * Ensure background apps can do wifi scan when the throttle interval reached. - */ - @Test - public void testWifiScanBackgroundWhiteListed() { - setupWifiStateMachineHandlerForRunWithScissors(); - - when(mActivityManager.getPackageImportance(WHITE_LIST_SCAN_PACKAGE_NAME)).thenReturn( - ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED); - long startMs = 1000; - when(mClock.getElapsedSinceBootMillis()).thenReturn(startMs); - mWifiServiceImpl.startScan(null, null, WHITE_LIST_SCAN_PACKAGE_NAME); - verify(mScanRequestProxy).startScan(Process.myUid()); - - when(mClock.getElapsedSinceBootMillis()).thenReturn( - startMs + WIFI_BACKGROUND_SCAN_INTERVAL - 1000); - mWifiServiceImpl.startScan(null, null, WHITE_LIST_SCAN_PACKAGE_NAME); - verify(mScanRequestProxy, times(2)).startScan(Process.myUid()); - } - /** * Ensure that we handle scan request failure when posting the runnable to handler fails. */ @@ -1111,11 +1025,8 @@ public class WifiServiceImplTest { setupWifiStateMachineHandlerForRunWithScissors(); doReturn(false).when(mHandlerSpyForWsmRunWithScissors) .runWithScissors(any(), anyLong()); - - when(mActivityManager.getPackageImportance(SCAN_PACKAGE_NAME)).thenReturn( - ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE); mWifiServiceImpl.startScan(null, null, SCAN_PACKAGE_NAME); - verify(mScanRequestProxy, never()).startScan(Process.myUid()); + verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME); } static final String TEST_SSID = "Sid's Place"; @@ -2614,14 +2525,14 @@ public class WifiServiceImplTest { // Send a scan request while the device is idle. mWifiServiceImpl.startScan(null, null, SCAN_PACKAGE_NAME); // No scans must be made yet as the device is idle. - verify(mScanRequestProxy, never()).startScan(Process.myUid()); + verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME); // Tell the wifi service that idle mode ended. when(mPowerManager.isDeviceIdleMode()).thenReturn(false); TestUtil.sendIdleModeChanged(mBroadcastReceiverCaptor.getValue(), mContext); // Must scan now. - verify(mScanRequestProxy, times(1)).startScan(Process.myUid()); + verify(mScanRequestProxy).startScan(Process.myUid(), TEST_PACKAGE_NAME); // The app ops check is executed with this package's identity (not the identity of the // original remote caller who requested the scan while idle). verify(mAppOpsManager).noteOp( @@ -2630,7 +2541,7 @@ public class WifiServiceImplTest { // Send another scan request. The device is not idle anymore, so it must be executed // immediately. mWifiServiceImpl.startScan(null, null, SCAN_PACKAGE_NAME); - verify(mScanRequestProxy, times(2)).startScan(Process.myUid()); + verify(mScanRequestProxy).startScan(Process.myUid(), SCAN_PACKAGE_NAME); } private class IdleModeIntentMatcher implements ArgumentMatcher { -- cgit v1.2.3 From c7a347b9f084606cb1cf78eda4a1eb42539dc1d9 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Fri, 2 Mar 2018 14:15:44 -0800 Subject: ScanRequestProxy: Add a separate bg scan throttle mechanism The current scan throttling mechanism is too lenient for background apps. So, split the throttling logic into two: a) For foreground apps, continue to throttle to a max of 1 scan per app every 30 seconds. b) For background apps, throttle to a max of 1 scan from any background app every 30 minutes. Bug: 68987915 Test: Unit tests Change-Id: I57915226e3be332ad6934e81ad69c218fe17ad30 Merged-In: I7c392429f8abaa00ea29b0a4479d010415d7b0ef --- .../android/server/wifi/ScanRequestProxyTest.java | 71 +++++++++++++++++++--- 1 file changed, 64 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java b/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java index aa7a821eb..7f684bc20 100644 --- a/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java @@ -16,9 +16,13 @@ package com.android.server.wifi; +import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE; + import static org.junit.Assert.*; import static org.mockito.Mockito.*; +import android.app.ActivityManager; +import android.app.AppOpsManager; import android.content.Context; import android.content.Intent; import android.net.wifi.ScanResult; @@ -57,6 +61,8 @@ public class ScanRequestProxyTest { }}; @Mock private Context mContext; + @Mock private AppOpsManager mAppOps; + @Mock private ActivityManager mActivityManager; @Mock private WifiInjector mWifiInjector; @Mock private WifiConfigManager mWifiConfigManager; @Mock private WifiScanner mWifiScanner; @@ -90,8 +96,8 @@ public class ScanRequestProxyTest { mTestScanDatas2 = ScanTestUtil.createScanDatas(new int[][]{ { 2412, 2422, 5200, 5210 } }); mScanRequestProxy = - new ScanRequestProxy(mContext, mWifiInjector, mWifiConfigManager, - mWifiPermissionsUtil, mClock); + new ScanRequestProxy(mContext, mAppOps, mActivityManager, mWifiInjector, + mWifiConfigManager, mWifiPermissionsUtil, mClock); } @After @@ -454,7 +460,7 @@ public class ScanRequestProxyTest { /** * Ensure new scan requests from the same app are rejected if it's before - * {@link ScanRequestProxy#SCAN_REQUEST_THROTTLE_INTERVAL_MS} + * {@link ScanRequestProxy#SCAN_REQUEST_THROTTLE_INTERVAL_FG_APPS_MS} */ @Test public void testSuccessiveScanRequestFromSameAppThrottled() { @@ -465,7 +471,7 @@ public class ScanRequestProxyTest { mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); long secondRequestMs = - firstRequestMs + ScanRequestProxy.SCAN_REQUEST_THROTTLE_INTERVAL_MS - 1; + firstRequestMs + ScanRequestProxy.SCAN_REQUEST_THROTTLE_INTERVAL_FG_APPS_MS - 1; when(mClock.getElapsedSinceBootMillis()).thenReturn(secondRequestMs); // Make scan request 2 from the same package name & ensure that it is throttled. assertFalse(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); @@ -476,7 +482,7 @@ public class ScanRequestProxyTest { /** * Ensure new scan requests from the same app are not rejected if it's after - * {@link ScanRequestProxy#SCAN_REQUEST_THROTTLE_INTERVAL_MS} + * {@link ScanRequestProxy#SCAN_REQUEST_THROTTLE_INTERVAL_FG_APPS_MS} */ @Test public void testSuccessiveScanRequestFromSameAppNotThrottled() { @@ -487,7 +493,7 @@ public class ScanRequestProxyTest { mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); long secondRequestMs = - firstRequestMs + ScanRequestProxy.SCAN_REQUEST_THROTTLE_INTERVAL_MS + 1; + firstRequestMs + ScanRequestProxy.SCAN_REQUEST_THROTTLE_INTERVAL_FG_APPS_MS + 1; when(mClock.getElapsedSinceBootMillis()).thenReturn(secondRequestMs); // Make scan request 2 from the same package name & ensure that it is not throttled. assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); @@ -511,7 +517,7 @@ public class ScanRequestProxyTest { mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); long secondRequestMs = - firstRequestMs + ScanRequestProxy.SCAN_REQUEST_THROTTLE_INTERVAL_MS - 1; + firstRequestMs + ScanRequestProxy.SCAN_REQUEST_THROTTLE_INTERVAL_FG_APPS_MS - 1; when(mClock.getElapsedSinceBootMillis()).thenReturn(secondRequestMs); // Make scan request 2 from the same package name & ensure that it is not throttled. assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); @@ -542,6 +548,57 @@ public class ScanRequestProxyTest { verifyNoMoreInteractions(mWifiScanner, mWifiConfigManager, mContext); } + /** + * Ensure scan requests from different background apps are throttled if it's before + * {@link ScanRequestProxy#SCAN_REQUEST_THROTTLE_INTERVAL_BG_APPS_MS}. + */ + @Test + public void testSuccessiveScanRequestFromBgAppsThrottled() { + when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1)) + .thenReturn(IMPORTANCE_FOREGROUND_SERVICE + 1); + when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_2)) + .thenReturn(IMPORTANCE_FOREGROUND_SERVICE + 1); + + long firstRequestMs = 782; + when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs); + // Make scan request 1. + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); + mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); + + // Make scan request 2 from the different package name & ensure that it is throttled. + assertFalse(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2)); + validateScanResultsFailureBroadcastSent(TEST_PACKAGE_NAME_2); + + verifyNoMoreInteractions(mWifiScanner, mWifiConfigManager, mContext); + } + + /** + * Ensure scan requests from different background apps are not throttled if it's after + * {@link ScanRequestProxy#SCAN_REQUEST_THROTTLE_INTERVAL_BG_APPS_MS}. + */ + @Test + public void testSuccessiveScanRequestFromBgAppsNotThrottled() { + when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1)) + .thenReturn(ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND + 1); + when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_2)) + .thenReturn(ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND + 1); + + long firstRequestMs = 782; + when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs); + // Make scan request 1. + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); + mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); + + long secondRequestMs = + firstRequestMs + ScanRequestProxy.SCAN_REQUEST_THROTTLE_INTERVAL_BG_APPS_MS + 1; + when(mClock.getElapsedSinceBootMillis()).thenReturn(secondRequestMs); + // Make scan request 2 from the different package name & ensure that it is throttled. + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2)); + mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); + + verifyNoMoreInteractions(mWifiScanner, mWifiConfigManager, mContext); + } + private void validateScanSettings(WifiScanner.ScanSettings scanSettings, boolean expectHiddenNetworks) { validateScanSettings(scanSettings, expectHiddenNetworks, false); -- cgit v1.2.3