Merge "Decouple the thresholds of the background restrictions" into tm-dev
This commit is contained in:
@@ -20,6 +20,7 @@ import static android.Manifest.permission.ACCESS_BACKGROUND_LOCATION;
|
||||
import static android.app.ActivityManager.RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
|
||||
import static android.app.ActivityManager.RESTRICTION_LEVEL_BACKGROUND_RESTRICTED;
|
||||
import static android.app.ActivityManager.RESTRICTION_LEVEL_RESTRICTED_BUCKET;
|
||||
import static android.app.ActivityManager.RESTRICTION_LEVEL_UNKNOWN;
|
||||
import static android.app.ActivityManager.isLowRamDeviceStatic;
|
||||
import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED_BY_SYSTEM;
|
||||
import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE;
|
||||
@@ -1118,6 +1119,13 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
|
||||
static final String KEY_BG_CURRENT_DRAIN_HIGH_THRESHOLD_BY_BG_LOCATION =
|
||||
DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "current_drain_high_threshold_by_bg_location";
|
||||
|
||||
/**
|
||||
* Whether or not the battery usage of the offending app should fulfill the 1st threshold
|
||||
* before taking actions for the 2nd threshold.
|
||||
*/
|
||||
static final String KEY_BG_CURRENT_DRAIN_DECOUPLE_THRESHOLDS =
|
||||
DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "current_drain_decouple_thresholds";
|
||||
|
||||
/**
|
||||
* Default value to the {@link #INDEX_REGULAR_CURRENT_DRAIN_THRESHOLD} of
|
||||
* the {@link #mBgCurrentDrainRestrictedBucketThreshold}.
|
||||
@@ -1190,6 +1198,11 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
|
||||
*/
|
||||
final boolean mDefaultBgCurrentDrainHighThresholdByBgLocation;
|
||||
|
||||
/**
|
||||
* Default value to {@link #mBgCurrentDrainDecoupleThresholds}.
|
||||
*/
|
||||
static final boolean DEFAULT_BG_CURRENT_DRAIN_DECOUPLE_THRESHOLD = true;
|
||||
|
||||
/**
|
||||
* The index to {@link #mBgCurrentDrainRestrictedBucketThreshold}
|
||||
* and {@link #mBgCurrentDrainBgRestrictedThreshold}.
|
||||
@@ -1257,6 +1270,11 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
|
||||
*/
|
||||
volatile boolean mBgCurrentDrainHighThresholdByBgLocation;
|
||||
|
||||
/**
|
||||
* @see #KEY_BG_CURRENT_DRAIN_DECOUPLE_THRESHOLDS.
|
||||
*/
|
||||
volatile boolean mBgCurrentDrainDecoupleThresholds;
|
||||
|
||||
/**
|
||||
* The capacity of the battery when fully charged in mAh.
|
||||
*/
|
||||
@@ -1369,6 +1387,9 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
|
||||
case KEY_BG_CURRENT_DRAIN_EXEMPTED_TYPES:
|
||||
updateCurrentDrainExemptedTypes();
|
||||
break;
|
||||
case KEY_BG_CURRENT_DRAIN_DECOUPLE_THRESHOLDS:
|
||||
updateCurrentDrainDecoupleThresholds();
|
||||
break;
|
||||
default:
|
||||
super.onPropertiesChanged(name);
|
||||
break;
|
||||
@@ -1466,6 +1487,13 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
|
||||
mDefaultBgCurrentDrainExemptedTypes);
|
||||
}
|
||||
|
||||
private void updateCurrentDrainDecoupleThresholds() {
|
||||
mBgCurrentDrainDecoupleThresholds = DeviceConfig.getBoolean(
|
||||
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
|
||||
KEY_BG_CURRENT_DRAIN_DECOUPLE_THRESHOLDS,
|
||||
DEFAULT_BG_CURRENT_DRAIN_DECOUPLE_THRESHOLD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSystemReady() {
|
||||
mBatteryFullChargeMah =
|
||||
@@ -1477,20 +1505,30 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
|
||||
updateCurrentDrainLocationMinDuration();
|
||||
updateCurrentDrainEventDurationBasedThresholdEnabled();
|
||||
updateCurrentDrainExemptedTypes();
|
||||
updateCurrentDrainDecoupleThresholds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @RestrictionLevel int getProposedRestrictionLevel(String packageName, int uid) {
|
||||
@RestrictionLevel
|
||||
public int getProposedRestrictionLevel(String packageName, int uid,
|
||||
@RestrictionLevel int maxLevel) {
|
||||
if (maxLevel <= RESTRICTION_LEVEL_ADAPTIVE_BUCKET) {
|
||||
return RESTRICTION_LEVEL_UNKNOWN;
|
||||
}
|
||||
synchronized (mLock) {
|
||||
final int index = mHighBgBatteryPackages.indexOfKey(uid);
|
||||
if (index < 0) {
|
||||
// Not found, return adaptive as the default one.
|
||||
return RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
|
||||
final long[] ts = mHighBgBatteryPackages.get(uid);
|
||||
if (ts != null) {
|
||||
final int restrictedLevel = ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] > 0
|
||||
? RESTRICTION_LEVEL_RESTRICTED_BUCKET
|
||||
: RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
|
||||
if (maxLevel > RESTRICTION_LEVEL_BACKGROUND_RESTRICTED) {
|
||||
return ts[TIME_STAMP_INDEX_BG_RESTRICTED] > 0
|
||||
? RESTRICTION_LEVEL_BACKGROUND_RESTRICTED : restrictedLevel;
|
||||
} else if (maxLevel == RESTRICTION_LEVEL_BACKGROUND_RESTRICTED) {
|
||||
return restrictedLevel;
|
||||
}
|
||||
}
|
||||
final long[] ts = mHighBgBatteryPackages.valueAt(index);
|
||||
return ts[TIME_STAMP_INDEX_BG_RESTRICTED] > 0
|
||||
? RESTRICTION_LEVEL_BACKGROUND_RESTRICTED
|
||||
: RESTRICTION_LEVEL_RESTRICTED_BUCKET;
|
||||
return RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1573,36 +1611,58 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
|
||||
final int thresholdIndex = getCurrentDrainThresholdIndex(uid, now,
|
||||
mBgCurrentDrainWindowMs);
|
||||
final int index = mHighBgBatteryPackages.indexOfKey(uid);
|
||||
final boolean decoupleThresholds = mBgCurrentDrainDecoupleThresholds;
|
||||
final double rbThreshold = mBgCurrentDrainRestrictedBucketThreshold[thresholdIndex];
|
||||
final double brThreshold = mBgCurrentDrainBgRestrictedThreshold[thresholdIndex];
|
||||
if (index < 0) {
|
||||
if (rbPercentage >= mBgCurrentDrainRestrictedBucketThreshold[thresholdIndex]) {
|
||||
long[] ts = null;
|
||||
if (rbPercentage >= rbThreshold) {
|
||||
// New findings to us, track it and let the controller know.
|
||||
final long[] ts = new long[TIME_STAMP_INDEX_LAST];
|
||||
ts = new long[TIME_STAMP_INDEX_LAST];
|
||||
ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = now;
|
||||
mHighBgBatteryPackages.put(uid, ts);
|
||||
notifyController = excessive = true;
|
||||
}
|
||||
if (decoupleThresholds && brPercentage >= brThreshold) {
|
||||
if (ts == null) {
|
||||
ts = new long[TIME_STAMP_INDEX_LAST];
|
||||
mHighBgBatteryPackages.put(uid, ts);
|
||||
}
|
||||
ts[TIME_STAMP_INDEX_BG_RESTRICTED] = now;
|
||||
notifyController = excessive = true;
|
||||
}
|
||||
} else {
|
||||
final long[] ts = mHighBgBatteryPackages.valueAt(index);
|
||||
if (rbPercentage < mBgCurrentDrainRestrictedBucketThreshold[thresholdIndex]) {
|
||||
// it's actually back to normal, but we don't untrack it until
|
||||
// explicit user interactions.
|
||||
notifyController = true;
|
||||
} else {
|
||||
excessive = true;
|
||||
if (brPercentage >= mBgCurrentDrainBgRestrictedThreshold[thresholdIndex]
|
||||
&& curLevel == RESTRICTION_LEVEL_RESTRICTED_BUCKET) {
|
||||
// If we're in the restricted standby bucket but still seeing high
|
||||
// current drains, tell the controller again.
|
||||
final long lastResbucket = ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET];
|
||||
final long lastBgRes = ts[TIME_STAMP_INDEX_BG_RESTRICTED];
|
||||
// If it has been a while since restricting the app and since the last
|
||||
// time we notify the controller, notify it again.
|
||||
if ((now >= lastResbucket + mBgCurrentDrainWindowMs) && (lastBgRes == 0
|
||||
|| (now >= lastBgRes + mBgCurrentDrainWindowMs))) {
|
||||
ts[TIME_STAMP_INDEX_BG_RESTRICTED] = now;
|
||||
notifyController = true;
|
||||
}
|
||||
final long lastRestrictBucketTs = ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET];
|
||||
if (rbPercentage >= rbThreshold) {
|
||||
if (lastRestrictBucketTs == 0) {
|
||||
ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = now;
|
||||
}
|
||||
notifyController = excessive = true;
|
||||
} else {
|
||||
// It's actually back to normal, but we don't untrack it until
|
||||
// explicit user interactions, because the restriction could be the cause
|
||||
// of going back to normal.
|
||||
}
|
||||
if (brPercentage >= brThreshold) {
|
||||
// If either
|
||||
// a) It's configured to goto threshold 2 directly without threshold 1;
|
||||
// b) It's already in the restricted standby bucket, but still seeing
|
||||
// high current drains, and it's been a while since it's restricted;
|
||||
// tell the controller.
|
||||
notifyController = decoupleThresholds
|
||||
|| (curLevel == RESTRICTION_LEVEL_RESTRICTED_BUCKET
|
||||
&& (now > lastRestrictBucketTs + mBgCurrentDrainWindowMs));
|
||||
if (notifyController) {
|
||||
ts[TIME_STAMP_INDEX_BG_RESTRICTED] = now;
|
||||
}
|
||||
excessive = true;
|
||||
} else {
|
||||
// Reset the track now - if it's already background restricted, it requires
|
||||
// user consent to unrestrict it; or if it's in restricted bucket level,
|
||||
// resetting this won't lift it from that level.
|
||||
ts[TIME_STAMP_INDEX_BG_RESTRICTED] = 0;
|
||||
// Now need to notify the controller.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import static android.app.ActivityManager.RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
|
||||
import static android.app.ActivityManager.RESTRICTION_LEVEL_BACKGROUND_RESTRICTED;
|
||||
import static android.app.ActivityManager.RESTRICTION_LEVEL_EXEMPTED;
|
||||
import static android.app.ActivityManager.RESTRICTION_LEVEL_HIBERNATION;
|
||||
import static android.app.ActivityManager.RESTRICTION_LEVEL_MAX;
|
||||
import static android.app.ActivityManager.RESTRICTION_LEVEL_RESTRICTED_BUCKET;
|
||||
import static android.app.ActivityManager.RESTRICTION_LEVEL_UNKNOWN;
|
||||
import static android.app.ActivityManager.UID_OBSERVER_ACTIVE;
|
||||
@@ -1152,7 +1153,8 @@ public final class AppRestrictionController {
|
||||
? RESTRICTION_LEVEL_RESTRICTED_BUCKET
|
||||
: RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
|
||||
if (calcTrackers) {
|
||||
@RestrictionLevel int l = calcAppRestrictionLevelFromTackers(uid, packageName);
|
||||
@RestrictionLevel int l = calcAppRestrictionLevelFromTackers(uid, packageName,
|
||||
RESTRICTION_LEVEL_MAX);
|
||||
if (l == RESTRICTION_LEVEL_EXEMPTED) {
|
||||
return RESTRICTION_LEVEL_EXEMPTED;
|
||||
}
|
||||
@@ -1164,7 +1166,8 @@ public final class AppRestrictionController {
|
||||
uid, 0, packageName).sendToTarget();
|
||||
}
|
||||
// Lower the level.
|
||||
level = RESTRICTION_LEVEL_RESTRICTED_BUCKET;
|
||||
level = calcAppRestrictionLevelFromTackers(uid, packageName,
|
||||
RESTRICTION_LEVEL_BACKGROUND_RESTRICTED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1181,12 +1184,13 @@ public final class AppRestrictionController {
|
||||
* monitors certain dimensions of the app, the abusive behaviors could be detected in one or
|
||||
* more of these dimensions, but not necessarily all of them. </p>
|
||||
*/
|
||||
private @RestrictionLevel int calcAppRestrictionLevelFromTackers(int uid, String packageName) {
|
||||
private @RestrictionLevel int calcAppRestrictionLevelFromTackers(int uid, String packageName,
|
||||
@RestrictionLevel int maxLevel) {
|
||||
@RestrictionLevel int level = RESTRICTION_LEVEL_UNKNOWN;
|
||||
final boolean isRestrictedBucketEnabled = mConstantsObserver.mRestrictedBucketEnabled;
|
||||
for (int i = mAppStateTrackers.size() - 1; i >= 0; i--) {
|
||||
@RestrictionLevel int l = mAppStateTrackers.get(i).getPolicy()
|
||||
.getProposedRestrictionLevel(packageName, uid);
|
||||
.getProposedRestrictionLevel(packageName, uid, maxLevel);
|
||||
if (!isRestrictedBucketEnabled && l == RESTRICTION_LEVEL_RESTRICTED_BUCKET) {
|
||||
l = RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
|
||||
}
|
||||
@@ -1475,17 +1479,15 @@ public final class AppRestrictionController {
|
||||
} else if (curLevel >= RESTRICTION_LEVEL_RESTRICTED_BUCKET
|
||||
&& level < RESTRICTION_LEVEL_RESTRICTED_BUCKET) {
|
||||
// Moved out of the background-restricted state.
|
||||
if (curBucket != STANDBY_BUCKET_RARE) {
|
||||
synchronized (mSettingsLock) {
|
||||
final int index = mActiveUids.indexOfKey(uid, pkgName);
|
||||
if (index >= 0) {
|
||||
mActiveUids.add(uid, pkgName, null);
|
||||
}
|
||||
synchronized (mSettingsLock) {
|
||||
final int index = mActiveUids.indexOfKey(uid, pkgName);
|
||||
if (index >= 0) {
|
||||
mActiveUids.add(uid, pkgName, null);
|
||||
}
|
||||
appStandbyInternal.maybeUnrestrictApp(pkgName, UserHandle.getUserId(uid),
|
||||
prevReason & REASON_MAIN_MASK, prevReason & REASON_SUB_MASK,
|
||||
reason, subReason);
|
||||
}
|
||||
appStandbyInternal.maybeUnrestrictApp(pkgName, UserHandle.getUserId(uid),
|
||||
prevReason & REASON_MAIN_MASK, prevReason & REASON_SUB_MASK,
|
||||
reason, subReason);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,9 +87,11 @@ public abstract class BaseAppStatePolicy<T extends BaseAppStateTracker> {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The proposed background restriction policy for the given package/uid.
|
||||
* @return The proposed background restriction policy for the given package/uid,
|
||||
* the returned level should be capped at {@code maxLevel} (exclusive).
|
||||
*/
|
||||
public @RestrictionLevel int getProposedRestrictionLevel(String packageName, int uid) {
|
||||
public @RestrictionLevel int getProposedRestrictionLevel(String packageName, int uid,
|
||||
@RestrictionLevel int maxLevel) {
|
||||
return RESTRICTION_LEVEL_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.server.am;
|
||||
|
||||
import static android.app.ActivityManager.RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
|
||||
import static android.app.ActivityManager.RESTRICTION_LEVEL_RESTRICTED_BUCKET;
|
||||
import static android.app.ActivityManager.RESTRICTION_LEVEL_UNKNOWN;
|
||||
import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED_BY_SYSTEM;
|
||||
import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE;
|
||||
import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE;
|
||||
@@ -295,11 +296,19 @@ abstract class BaseAppStateTimeSlotEventsTracker
|
||||
}
|
||||
|
||||
@Override
|
||||
public @RestrictionLevel int getProposedRestrictionLevel(String packageName, int uid) {
|
||||
@RestrictionLevel
|
||||
public int getProposedRestrictionLevel(String packageName, int uid,
|
||||
@RestrictionLevel int maxLevel) {
|
||||
synchronized (mLock) {
|
||||
return mExcessiveEventPkgs.get(packageName, uid) == null
|
||||
final int level = mExcessiveEventPkgs.get(packageName, uid) == null
|
||||
? RESTRICTION_LEVEL_ADAPTIVE_BUCKET
|
||||
: RESTRICTION_LEVEL_RESTRICTED_BUCKET;
|
||||
if (maxLevel > RESTRICTION_LEVEL_RESTRICTED_BUCKET) {
|
||||
return level;
|
||||
} else if (maxLevel == RESTRICTION_LEVEL_RESTRICTED_BUCKET) {
|
||||
return RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
|
||||
}
|
||||
return RESTRICTION_LEVEL_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -579,6 +579,7 @@ public final class BackgroundRestrictionTest {
|
||||
DeviceConfigSession<Boolean> bgPromptFgsWithNotiToBgRestricted = null;
|
||||
DeviceConfigSession<Long> bgNotificationMinInterval = null;
|
||||
DeviceConfigSession<Integer> bgBatteryExemptionTypes = null;
|
||||
DeviceConfigSession<Boolean> bgCurrentDrainDecoupleThresholds = null;
|
||||
|
||||
mBgRestrictionController.addAppBackgroundRestrictionListener(listener);
|
||||
|
||||
@@ -648,6 +649,13 @@ public final class BackgroundRestrictionTest {
|
||||
R.integer.config_bg_current_drain_exempted_types));
|
||||
bgBatteryExemptionTypes.set(0);
|
||||
|
||||
bgCurrentDrainDecoupleThresholds = new DeviceConfigSession<>(
|
||||
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
|
||||
AppBatteryPolicy.KEY_BG_CURRENT_DRAIN_DECOUPLE_THRESHOLDS,
|
||||
DeviceConfig::getBoolean,
|
||||
AppBatteryPolicy.DEFAULT_BG_CURRENT_DRAIN_DECOUPLE_THRESHOLD);
|
||||
bgCurrentDrainDecoupleThresholds.set(true);
|
||||
|
||||
mCurrentTimeMillis = 10_000L;
|
||||
doReturn(mCurrentTimeMillis - windowMs).when(stats).getStatsStartTimestamp();
|
||||
doReturn(mCurrentTimeMillis).when(stats).getStatsEndTimestamp();
|
||||
@@ -785,6 +793,11 @@ public final class BackgroundRestrictionTest {
|
||||
anyInt(), anyInt());
|
||||
});
|
||||
|
||||
// Pretend we have the standby buckets set above.
|
||||
doReturn(STANDBY_BUCKET_RESTRICTED)
|
||||
.when(mAppStandbyInternal)
|
||||
.getAppStandbyBucket(eq(testPkgName), eq(testUser), anyLong(), anyBoolean());
|
||||
|
||||
// Sleep a while and set a higher drain
|
||||
Thread.sleep(windowMs);
|
||||
clearInvocations(mInjector.getAppStandbyInternal());
|
||||
@@ -921,6 +934,11 @@ public final class BackgroundRestrictionTest {
|
||||
// Expected.
|
||||
}
|
||||
|
||||
// Reset the standby bucket.
|
||||
doReturn(STANDBY_BUCKET_RARE)
|
||||
.when(mAppStandbyInternal)
|
||||
.getAppStandbyBucket(eq(testPkgName), eq(testUser), anyLong(), anyBoolean());
|
||||
|
||||
// Turn OFF the FAS.
|
||||
listener.mLatchHolder[0] = new CountDownLatch(1);
|
||||
clearInvocations(mInjector.getAppStandbyInternal());
|
||||
@@ -930,6 +948,99 @@ public final class BackgroundRestrictionTest {
|
||||
// It'll go back to restricted bucket because it used to behave poorly.
|
||||
listener.verify(timeout, testUid, testPkgName, RESTRICTION_LEVEL_RESTRICTED_BUCKET);
|
||||
verifyRestrictionLevel(RESTRICTION_LEVEL_RESTRICTED_BUCKET, testPkgName, testUid);
|
||||
|
||||
clearInvocations(mInjector.getAppStandbyInternal());
|
||||
// Trigger user interaction.
|
||||
runTestBgCurrentDrainMonitorOnce(listener, stats, uids,
|
||||
new double[]{restrictBucketThresholdMah - 1, 0},
|
||||
new double[]{0, restrictBucketThresholdMah - 1}, zeros, zeros,
|
||||
() -> {
|
||||
doReturn(mCurrentTimeMillis).when(stats).getStatsStartTimestamp();
|
||||
doReturn(mCurrentTimeMillis + windowMs)
|
||||
.when(stats).getStatsEndTimestamp();
|
||||
mCurrentTimeMillis += windowMs + 1;
|
||||
mIdleStateListener.onUserInteractionStarted(testPkgName, testUser);
|
||||
waitForIdleHandler(mBgRestrictionController.getBackgroundHandler());
|
||||
// It should have been back to normal.
|
||||
listener.verify(timeout, testUid, testPkgName,
|
||||
RESTRICTION_LEVEL_ADAPTIVE_BUCKET);
|
||||
verify(mInjector.getAppStandbyInternal(), atLeast(1)).maybeUnrestrictApp(
|
||||
eq(testPkgName),
|
||||
eq(testUser),
|
||||
eq(REASON_MAIN_USAGE),
|
||||
eq(REASON_SUB_USAGE_USER_INTERACTION),
|
||||
eq(REASON_MAIN_USAGE),
|
||||
eq(REASON_SUB_USAGE_USER_INTERACTION));
|
||||
});
|
||||
|
||||
bgCurrentDrainDecoupleThresholds.set(true);
|
||||
clearInvocations(mInjector.getAppStandbyInternal());
|
||||
|
||||
// Go to the threshold right away.
|
||||
runTestBgCurrentDrainMonitorOnce(listener, stats, uids,
|
||||
new double[]{0, restrictBucketThresholdMah - 1},
|
||||
new double[]{bgRestrictedThresholdMah + 1, 0}, zeros, zeros,
|
||||
() -> {
|
||||
doReturn(mCurrentTimeMillis).when(stats).getStatsStartTimestamp();
|
||||
doReturn(mCurrentTimeMillis + windowMs)
|
||||
.when(stats).getStatsEndTimestamp();
|
||||
mCurrentTimeMillis += windowMs + 1;
|
||||
// We won't change restriction level automatically because it needs
|
||||
// user consent.
|
||||
try {
|
||||
listener.verify(timeout, testUid, testPkgName,
|
||||
RESTRICTION_LEVEL_BACKGROUND_RESTRICTED);
|
||||
fail("There shouldn't be level change event like this");
|
||||
} catch (Exception e) {
|
||||
// Expected.
|
||||
}
|
||||
verify(mInjector.getAppStandbyInternal(), never()).setAppStandbyBucket(
|
||||
eq(testPkgName),
|
||||
eq(STANDBY_BUCKET_RARE),
|
||||
eq(testUser),
|
||||
anyInt(), anyInt());
|
||||
// We should have requested to goto background restricted level.
|
||||
verify(mBgRestrictionController, times(1)).handleRequestBgRestricted(
|
||||
eq(testPkgName),
|
||||
eq(testUid));
|
||||
// Verify we have the notification posted now because its FGS is invisible.
|
||||
checkNotificationShown(new String[] {testPkgName}, atLeast(1), true);
|
||||
});
|
||||
|
||||
bgCurrentDrainDecoupleThresholds.set(false);
|
||||
clearInvocations(mInjector.getAppStandbyInternal());
|
||||
clearInvocations(mBgRestrictionController);
|
||||
|
||||
// Go to the threshold right away, but this time, it shouldn't even request to goto
|
||||
// bg restricted level because it requires to be in restricted bucket before that.
|
||||
runTestBgCurrentDrainMonitorOnce(listener, stats, uids,
|
||||
new double[]{0, restrictBucketThresholdMah - 1},
|
||||
new double[]{bgRestrictedThresholdMah + 1, 0}, zeros, zeros,
|
||||
() -> {
|
||||
doReturn(mCurrentTimeMillis).when(stats).getStatsStartTimestamp();
|
||||
doReturn(mCurrentTimeMillis + windowMs)
|
||||
.when(stats).getStatsEndTimestamp();
|
||||
mCurrentTimeMillis += windowMs + 1;
|
||||
// We won't change restriction level automatically because it needs
|
||||
// user consent.
|
||||
try {
|
||||
listener.verify(timeout, testUid, testPkgName,
|
||||
RESTRICTION_LEVEL_BACKGROUND_RESTRICTED);
|
||||
fail("There shouldn't be level change event like this");
|
||||
} catch (Exception e) {
|
||||
// Expected.
|
||||
}
|
||||
verify(mInjector.getAppStandbyInternal(), never()).setAppStandbyBucket(
|
||||
eq(testPkgName),
|
||||
eq(STANDBY_BUCKET_RARE),
|
||||
eq(testUser),
|
||||
anyInt(), anyInt());
|
||||
// We should NOT have requested to goto background restricted level.
|
||||
verify(mBgRestrictionController, never()).handleRequestBgRestricted(
|
||||
eq(testPkgName),
|
||||
eq(testUid));
|
||||
});
|
||||
|
||||
} finally {
|
||||
closeIfNotNull(bgCurrentDrainMonitor);
|
||||
closeIfNotNull(bgCurrentDrainWindow);
|
||||
@@ -938,6 +1049,7 @@ public final class BackgroundRestrictionTest {
|
||||
closeIfNotNull(bgPromptFgsWithNotiToBgRestricted);
|
||||
closeIfNotNull(bgNotificationMinInterval);
|
||||
closeIfNotNull(bgBatteryExemptionTypes);
|
||||
closeIfNotNull(bgCurrentDrainDecoupleThresholds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1441,6 +1553,7 @@ public final class BackgroundRestrictionTest {
|
||||
DeviceConfigSession<Boolean> bgPermissionMonitorEnabled = null;
|
||||
DeviceConfigSession<String> bgPermissionsInMonitor = null;
|
||||
DeviceConfigSession<Boolean> bgCurrentDrainHighThresholdByBgLocation = null;
|
||||
DeviceConfigSession<Boolean> bgCurrentDrainDecoupleThresholds = null;
|
||||
|
||||
mBgRestrictionController.addAppBackgroundRestrictionListener(listener);
|
||||
|
||||
@@ -1572,6 +1685,13 @@ public final class BackgroundRestrictionTest {
|
||||
R.bool.config_bg_current_drain_high_threshold_by_bg_location));
|
||||
bgCurrentDrainHighThresholdByBgLocation.set(true);
|
||||
|
||||
bgCurrentDrainDecoupleThresholds = new DeviceConfigSession<>(
|
||||
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
|
||||
AppBatteryPolicy.KEY_BG_CURRENT_DRAIN_DECOUPLE_THRESHOLDS,
|
||||
DeviceConfig::getBoolean,
|
||||
AppBatteryPolicy.DEFAULT_BG_CURRENT_DRAIN_DECOUPLE_THRESHOLD);
|
||||
bgCurrentDrainDecoupleThresholds.set(true);
|
||||
|
||||
mCurrentTimeMillis = 10_000L;
|
||||
doReturn(mCurrentTimeMillis - windowMs).when(stats).getStatsStartTimestamp();
|
||||
doReturn(mCurrentTimeMillis).when(stats).getStatsEndTimestamp();
|
||||
@@ -1990,6 +2110,7 @@ public final class BackgroundRestrictionTest {
|
||||
closeIfNotNull(bgPermissionMonitorEnabled);
|
||||
closeIfNotNull(bgPermissionsInMonitor);
|
||||
closeIfNotNull(bgCurrentDrainHighThresholdByBgLocation);
|
||||
closeIfNotNull(bgCurrentDrainDecoupleThresholds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user