diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2018-08-01 16:42:29 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2018-08-01 16:42:29 +0000 |
commit | c630bd543106df72cc22eca1fe3e58fea4107090 (patch) | |
tree | 7b16b45a42b98dd1f27ebd9a5b926104ebe67ace | |
parent | 6b0af0a4dfa297b7cf7c72a544f0f5120f8bc789 (diff) | |
parent | 73cf4e7594368d0bb2688867a7c055a58bf078db (diff) |
Merge "ScanRequestProxy: Add a setting to toggle wifi scan throttling"
3 files changed, 107 insertions, 6 deletions
diff --git a/service/java/com/android/server/wifi/ScanRequestProxy.java b/service/java/com/android/server/wifi/ScanRequestProxy.java index 900d85095..d9bbe15ee 100644 --- a/service/java/com/android/server/wifi/ScanRequestProxy.java +++ b/service/java/com/android/server/wifi/ScanRequestProxy.java @@ -21,12 +21,15 @@ import android.app.ActivityManager; import android.app.AppOpsManager; import android.content.Context; import android.content.Intent; +import android.database.ContentObserver; import android.net.wifi.ScanResult; import android.net.wifi.WifiManager; import android.net.wifi.WifiScanner; import android.os.Binder; +import android.os.Handler; import android.os.UserHandle; import android.os.WorkSource; +import android.provider.Settings; import android.util.ArrayMap; import android.util.Log; import android.util.Pair; @@ -82,6 +85,8 @@ public class ScanRequestProxy { private final WifiPermissionsUtil mWifiPermissionsUtil; private final WifiMetrics mWifiMetrics; private final Clock mClock; + private final FrameworkFacade mFrameworkFacade; + private final ThrottleEnabledSettingObserver mThrottleEnabledSettingObserver; private WifiScanner mWifiScanner; // Verbose logging flag. @@ -150,9 +155,57 @@ public class ScanRequestProxy { } }; + /** + * Observer for scan throttle enable settings changes. + * This is enabled by default. Will be toggled off via adb command or a developer settings + * toggle by the user to disable all scan throttling. + */ + private class ThrottleEnabledSettingObserver extends ContentObserver { + private boolean mThrottleEnabled = true; + + ThrottleEnabledSettingObserver(Handler handler) { + super(handler); + } + + /** + * Register for any changes to the scan throttle setting. + */ + public void initialize() { + mFrameworkFacade.registerContentObserver(mContext, + Settings.Global.getUriFor(Settings.Global.WIFI_SCAN_THROTTLE_ENABLED), + true, this); + mThrottleEnabled = getValue(); + if (mVerboseLoggingEnabled) { + Log.v(TAG, "Scan throttle enabled " + mThrottleEnabled); + } + } + + /** + * Check if throttling is enabled or not. + * + * @return true if throttling is enabled, false otherwise. + */ + public boolean isEnabled() { + return mThrottleEnabled; + } + + @Override + public void onChange(boolean selfChange) { + super.onChange(selfChange); + mThrottleEnabled = getValue(); + Log.i(TAG, "Scan throttle enabled " + mThrottleEnabled); + } + + private boolean getValue() { + return mFrameworkFacade.getIntegerSetting(mContext, + Settings.Global.WIFI_SCAN_THROTTLE_ENABLED, 1) == 1; + } + } + ScanRequestProxy(Context context, AppOpsManager appOpsManager, ActivityManager activityManager, WifiInjector wifiInjector, WifiConfigManager configManager, - WifiPermissionsUtil wifiPermissionUtil, WifiMetrics wifiMetrics, Clock clock) { + WifiPermissionsUtil wifiPermissionUtil, WifiMetrics wifiMetrics, Clock clock, + FrameworkFacade frameworkFacade, Handler handler) { mContext = context; mAppOps = appOpsManager; mActivityManager = activityManager; @@ -161,6 +214,8 @@ public class ScanRequestProxy { mWifiPermissionsUtil = wifiPermissionUtil; mWifiMetrics = wifiMetrics; mClock = clock; + mFrameworkFacade = frameworkFacade; + mThrottleEnabledSettingObserver = new ThrottleEnabledSettingObserver(handler); } /** @@ -177,6 +232,8 @@ public class ScanRequestProxy { private boolean retrieveWifiScannerIfNecessary() { if (mWifiScanner == null) { mWifiScanner = mWifiInjector.getWifiScanner(); + // Start listening for throttle settings change after we retrieve scanner instance. + mThrottleEnabledSettingObserver.initialize(); } return mWifiScanner != null; } @@ -402,8 +459,10 @@ public class ScanRequestProxy { boolean fromSettingsOrSetupWizard = mWifiPermissionsUtil.checkNetworkSettingsPermission(callingUid) || mWifiPermissionsUtil.checkNetworkSetupWizardPermission(callingUid); - // Check and throttle scan request from apps without NETWORK_SETTINGS permission. - if (!fromSettingsOrSetupWizard + // Check and throttle scan request unless, + // a) App has either NETWORK_SETTINGS or NETWORK_SETUP_WIZARD permission. + // b) Throttling has been disabled by user. + if (!fromSettingsOrSetupWizard && mThrottleEnabledSettingObserver.isEnabled() && shouldScanRequestBeThrottledForApp(callingUid, packageName)) { Log.i(TAG, "Scan request from " + packageName + " throttled"); sendScanResultFailureBroadcastToPackage(packageName); diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java index 5412a5204..ba288505e 100644 --- a/service/java/com/android/server/wifi/WifiInjector.java +++ b/service/java/com/android/server/wifi/WifiInjector.java @@ -253,7 +253,8 @@ public class WifiInjector { (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE), (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE), this, mWifiConfigManager, - mWifiPermissionsUtil, mWifiMetrics, mClock); + mWifiPermissionsUtil, mWifiMetrics, mClock, mFrameworkFacade, + new Handler(clientModeImplLooper)); mSarManager = new SarManager(mContext, makeTelephonyManager(), clientModeImplLooper, mWifiNative, new SystemSensorManager(mContext, clientModeImplLooper), mWifiMetrics); diff --git a/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java b/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java index 4b262b07f..865501685 100644 --- a/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java @@ -28,11 +28,14 @@ import android.app.ActivityManager; import android.app.AppOpsManager; import android.content.Context; import android.content.Intent; +import android.database.ContentObserver; import android.net.wifi.ScanResult; import android.net.wifi.WifiManager; import android.net.wifi.WifiScanner; +import android.os.Handler; import android.os.UserHandle; import android.os.WorkSource; +import android.provider.Settings; import android.support.test.filters.SmallTest; import com.android.server.wifi.util.WifiPermissionsUtil; @@ -72,12 +75,15 @@ public class ScanRequestProxyTest { @Mock private WifiPermissionsUtil mWifiPermissionsUtil; @Mock private WifiMetrics mWifiMetrics; @Mock private Clock mClock; + @Mock private FrameworkFacade mFrameworkFacade; private ArgumentCaptor<WorkSource> mWorkSourceArgumentCaptor = ArgumentCaptor.forClass(WorkSource.class); private ArgumentCaptor<WifiScanner.ScanSettings> mScanSettingsArgumentCaptor = ArgumentCaptor.forClass(WifiScanner.ScanSettings.class); private ArgumentCaptor<WifiScanner.ScanListener> mScanListenerArgumentCaptor = ArgumentCaptor.forClass(WifiScanner.ScanListener.class); + private ArgumentCaptor<ContentObserver> mThrottleEnabledSettingObservorCaptor = + ArgumentCaptor.forClass(ContentObserver.class); private WifiScanner.ScanData[] mTestScanDatas1; private WifiScanner.ScanData[] mTestScanDatas2; private InOrder mInOrder; @@ -99,9 +105,14 @@ public class ScanRequestProxyTest { mTestScanDatas1 = ScanTestUtil.createScanDatas(new int[][]{ { 2417, 2427, 5180, 5170 } }); mTestScanDatas2 = ScanTestUtil.createScanDatas(new int[][]{ { 2412, 2422, 5200, 5210 } }); + // Scan throttling is enabled by default. + when(mFrameworkFacade.getIntegerSetting( + eq(mContext), eq(Settings.Global.WIFI_SCAN_THROTTLE_ENABLED), anyInt())) + .thenReturn(1); mScanRequestProxy = new ScanRequestProxy(mContext, mAppOps, mActivityManager, mWifiInjector, - mWifiConfigManager, mWifiPermissionsUtil, mWifiMetrics, mClock); + mWifiConfigManager, mWifiPermissionsUtil, mWifiMetrics, mClock, + mFrameworkFacade, mock(Handler.class)); } @After @@ -115,7 +126,7 @@ public class ScanRequestProxyTest { */ @Test public void testEnableScanning() { - mScanRequestProxy.enableScanning(true, true); + mScanRequestProxy.enableScanning(true, false); verify(mWifiScanner).setScanningEnabled(true); validateScanAvailableBroadcastSent(true); } @@ -596,6 +607,36 @@ public class ScanRequestProxyTest { } /** + * Ensure new scan requests from the same app are not throttled when the user turns + * off scan throttling. + */ + @Test + public void testSuccessiveScanRequestFromSameAppWhenThrottlingIsDisabledNotThrottled() { + // Triggers the scan throttle setting registration. + testEnableScanning(); + verify(mFrameworkFacade).registerContentObserver(any(), + eq(Settings.Global.getUriFor(Settings.Global.WIFI_SCAN_THROTTLE_ENABLED)), + anyBoolean(), mThrottleEnabledSettingObservorCaptor.capture()); + assertNotNull(mThrottleEnabledSettingObservorCaptor); + // Disable scan throttling & invoke the content observer callback. + when(mFrameworkFacade.getIntegerSetting( + eq(mContext), eq(Settings.Global.WIFI_SCAN_THROTTLE_ENABLED), anyInt())) + .thenReturn(0); + mThrottleEnabledSettingObservorCaptor.getValue().onChange(false); + + long firstRequestMs = 782; + when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs); + for (int i = 0; i < SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS; i++) { + when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs + i); + assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); + mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); + } + // Make next scan request 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()); + } + + /** * Ensure new scan requests from different apps are not throttled. */ @Test |