Android O WiFi对应用前后台扫描的限制

流程梳理

  • ScanRequestProxy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
    // 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);
return false;
}
}

/**
* Checks if the scan request from the app (specified by callingUid & packageName) needs
* to be throttled.
*/
private boolean shouldScanRequestBeThrottledForApp(int callingUid, String packageName) {
boolean isThrottled;
if (isRequestFromBackground(callingUid, packageName)) {
isThrottled = shouldScanRequestBeThrottledForBackgroundApp();
if (isThrottled) {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Background scan app request [" + callingUid + ", "
+ packageName + "]");
}
mWifiMetrics.incrementExternalBackgroundAppOneshotScanRequestsThrottledCount();
}
} else {
isThrottled = shouldScanRequestBeThrottledForForegroundApp(callingUid, packageName);
if (isThrottled) {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Foreground scan app request [" + callingUid + ", "
+ packageName + "]");
}
mWifiMetrics.incrementExternalForegroundAppOneshotScanRequestsThrottledCount();
}
}
mWifiMetrics.incrementExternalAppOneshotScanRequestsCount();
return isThrottled;
}

后台扫描限制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* Checks if the scan request from a background app needs to be throttled.
*/
private boolean shouldScanRequestBeThrottledForBackgroundApp() {
long lastScanMs = mLastScanTimestampForBgApps;
long elapsedRealtime = mClock.getElapsedSinceBootMillis();
if (lastScanMs != 0
&& (elapsedRealtime - lastScanMs) < SCAN_REQUEST_THROTTLE_INTERVAL_BG_APPS_MS) {
return true;
}
// Proceed with the scan request and record the time.
mLastScanTimestampForBgApps = elapsedRealtime;
return false;
}

public static final int SCAN_REQUEST_THROTTLE_INTERVAL_BG_APPS_MS = 30 * 60 * 1000;

也就是说所有后台应用30min内只能发起一次扫描

前台扫描限制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/**
* Checks if the scan request from the app (specified by packageName) needs
* to be throttled.
* The throttle limit allows a max of {@link #SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS}
* in {@link #SCAN_REQUEST_THROTTLE_TIME_WINDOW_FG_APPS_MS} window.
*/
private boolean shouldScanRequestBeThrottledForForegroundApp(
int callingUid, String packageName) {
LinkedList<Long> scanRequestTimestamps =
getOrCreateScanRequestTimestampsForForegroundApp(callingUid, packageName);
long currentTimeMillis = mClock.getElapsedSinceBootMillis();
// First evict old entries from the list.
trimPastScanRequestTimesForForegroundApp(scanRequestTimestamps, currentTimeMillis);
if (scanRequestTimestamps.size() >= SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS) {
return true;
}
// Proceed with the scan request and record the time.
scanRequestTimestamps.addLast(currentTimeMillis);
return false;
}


@VisibleForTesting
public static final int SCAN_REQUEST_THROTTLE_TIME_WINDOW_FG_APPS_MS = 120 * 1000;
@VisibleForTesting
public static final int SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS = 4;

private void trimPastScanRequestTimesForForegroundApp(
List<Long> scanRequestTimestamps, long currentTimeMillis) {
Iterator<Long> timestampsIter = scanRequestTimestamps.iterator();
while (timestampsIter.hasNext()) {
Long scanRequestTimeMillis = timestampsIter.next();
if ((currentTimeMillis - scanRequestTimeMillis)
> SCAN_REQUEST_THROTTLE_TIME_WINDOW_FG_APPS_MS) {
timestampsIter.remove();
} else {
// This list is sorted by timestamps, so we can skip any more checks
break;
}
}
}

也就是说每个应用2分钟内只能发起四次扫描

总结

1
2
3
4
5
6
* d) Throttle scan requests from non-setting apps:
* a) Each foreground app can request a max of
* {@link #SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS} scan every
* {@link #SCAN_REQUEST_THROTTLE_TIME_WINDOW_FG_APPS_MS}.
* b) Background apps combined can request 1 scan every
* {@link #SCAN_REQUEST_THROTTLE_INTERVAL_BG_APPS_MS}.

ScanRequestProxy的注释讲的很清楚

  • 每个前台应用2分钟内只能发起四次扫描
  • 所有的后台应用加起来30分钟内只能发起一次扫描

Powered by AppBlog.CN     浙ICP备14037229号

Copyright © 2012 - 2021 APP开发技术博客 All Rights Reserved.

访客数 : | 访问量 :