Merge "Convert system forced reasons to flags." into rvc-dev

This commit is contained in:
Kweku Adams
2020-03-17 04:28:24 +00:00
committed by Android (Google) Code Review
6 changed files with 144 additions and 29 deletions

View File

@@ -5,6 +5,7 @@ import android.annotation.UserIdInt;
import android.app.usage.AppStandbyInfo;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManager.StandbyBuckets;
import android.app.usage.UsageStatsManager.SystemForcedReasons;
import android.content.Context;
import android.os.Looper;
@@ -123,9 +124,10 @@ public interface AppStandbyInternal {
* appropriate time.
*
* @param restrictReason The restrictReason for restricting the app. Should be one of the
* UsageStatsManager.REASON_SUB_RESTRICT_* reasons.
* UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_* reasons.
*/
void restrictApp(@NonNull String packageName, int userId, int restrictReason);
void restrictApp(@NonNull String packageName, int userId,
@SystemForcedReasons int restrictReason);
void addActiveDeviceAdmin(String adminPkg, int userId);

View File

@@ -974,7 +974,7 @@ public class JobSchedulerService extends com.android.server.SystemService
if (!mQuotaTracker.isWithinQuota(userId, pkg, QUOTA_TRACKER_SCHEDULE_PERSISTED_TAG)) {
Slog.e(TAG, userId + "-" + pkg + " has called schedule() too many times");
mAppStandbyInternal.restrictApp(
pkg, userId, UsageStatsManager.REASON_SUB_RESTRICT_BUGGY);
pkg, userId, UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY);
if (mConstants.API_QUOTA_SCHEDULE_THROW_EXCEPTION) {
final boolean isDebuggable;
synchronized (mLock) {

View File

@@ -58,6 +58,7 @@ import android.app.AppGlobals;
import android.app.usage.AppStandbyInfo;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManager.StandbyBuckets;
import android.app.usage.UsageStatsManager.SystemForcedReasons;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -1153,6 +1154,13 @@ public class AppStandbyController implements AppStandbyInternal {
}
}
@VisibleForTesting
int getAppStandbyBucketReason(String packageName, int userId, long elapsedRealtime) {
synchronized (mAppIdleLock) {
return mAppIdleHistory.getAppStandbyReason(packageName, userId, elapsedRealtime);
}
}
@Override
public List<AppStandbyInfo> getAppStandbyBuckets(int userId) {
synchronized (mAppIdleLock) {
@@ -1161,7 +1169,8 @@ public class AppStandbyController implements AppStandbyInternal {
}
@Override
public void restrictApp(@NonNull String packageName, int userId, int restrictReason) {
public void restrictApp(@NonNull String packageName, int userId,
@SystemForcedReasons int restrictReason) {
// If the package is not installed, don't allow the bucket to be set.
if (!mInjector.isPackageInstalled(packageName, 0, userId)) {
Slog.e(TAG, "Tried to restrict uninstalled app: " + packageName);
@@ -1254,10 +1263,28 @@ public class AppStandbyController implements AppStandbyInternal {
return;
}
final boolean wasForcedBySystem =
(app.bucketingReason & REASON_MAIN_MASK) == REASON_MAIN_FORCED_BY_SYSTEM;
// If the bucket was forced, don't allow prediction to override
if (predicted
&& ((app.bucketingReason & REASON_MAIN_MASK) == REASON_MAIN_FORCED_BY_USER
|| (app.bucketingReason & REASON_MAIN_MASK) == REASON_MAIN_FORCED_BY_SYSTEM)) {
|| wasForcedBySystem)) {
return;
}
final boolean isForcedBySystem =
(reason & REASON_MAIN_MASK) == REASON_MAIN_FORCED_BY_SYSTEM;
if (app.currentBucket == newBucket && wasForcedBySystem && isForcedBySystem) {
mAppIdleHistory
.noteRestrictionAttempt(packageName, userId, elapsedRealtime, reason);
// Keep track of all restricting reasons
reason = REASON_MAIN_FORCED_BY_SYSTEM
| (app.bucketingReason & REASON_SUB_MASK)
| (reason & REASON_SUB_MASK);
mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime,
newBucket, reason, resetTimeout);
return;
}

View File

@@ -288,25 +288,25 @@ public final class UsageStatsManager {
*/
public static final int REASON_SUB_PREDICTED_RESTORED = 0x0001;
/**
* The reason for restricting the app is unknown or undefined.
* The reason the system forced the app into the bucket is unknown or undefined.
* @hide
*/
public static final int REASON_SUB_RESTRICT_UNDEFINED = 0x0000;
public static final int REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED = 0;
/**
* The app was unnecessarily using system resources (battery, memory, etc) in the background.
* @hide
*/
public static final int REASON_SUB_RESTRICT_BACKGROUND_RESOURCE_USAGE = 0x0001;
public static final int REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE = 1 << 0;
/**
* The app was deemed to be intentionally abusive.
* @hide
*/
public static final int REASON_SUB_RESTRICT_ABUSE = 0x0002;
public static final int REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE = 1 << 1;
/**
* The app was displaying buggy behavior.
* @hide
*/
public static final int REASON_SUB_RESTRICT_BUGGY = 0x0003;
public static final int REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY = 1 << 2;
/** @hide */
@@ -322,6 +322,17 @@ public final class UsageStatsManager {
@Retention(RetentionPolicy.SOURCE)
public @interface StandbyBuckets {}
/** @hide */
@IntDef(flag = true, prefix = {"REASON_SUB_FORCED_SYSTEM_FLAG_FLAG_"}, value = {
REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED,
REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE,
REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE,
REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY,
})
@Retention(RetentionPolicy.SOURCE)
public @interface SystemForcedReasons {
}
/**
* Observer id of the registered observer for the group of packages that reached the usage
* time limit. Included as an extra in the PendingIntent that was registered.
@@ -1053,6 +1064,7 @@ public final class UsageStatsManager {
/** @hide */
public static String reasonToString(int standbyReason) {
final int subReason = standbyReason & REASON_SUB_MASK;
StringBuilder sb = new StringBuilder();
switch (standbyReason & REASON_MAIN_MASK) {
case REASON_MAIN_DEFAULT:
@@ -1060,19 +1072,8 @@ public final class UsageStatsManager {
break;
case REASON_MAIN_FORCED_BY_SYSTEM:
sb.append("s");
switch (standbyReason & REASON_SUB_MASK) {
case REASON_SUB_RESTRICT_ABUSE:
sb.append("-ra");
break;
case REASON_SUB_RESTRICT_BACKGROUND_RESOURCE_USAGE:
sb.append("-rbru");
break;
case REASON_SUB_RESTRICT_BUGGY:
sb.append("-rb");
break;
case REASON_SUB_RESTRICT_UNDEFINED:
sb.append("-r");
break;
if (subReason > 0) {
sb.append("-").append(Integer.toBinaryString(subReason));
}
break;
case REASON_MAIN_FORCED_BY_USER:
@@ -1080,7 +1081,7 @@ public final class UsageStatsManager {
break;
case REASON_MAIN_PREDICTED:
sb.append("p");
switch (standbyReason & REASON_SUB_MASK) {
switch (subReason) {
case REASON_SUB_PREDICTED_RESTORED:
sb.append("-r");
break;
@@ -1091,7 +1092,7 @@ public final class UsageStatsManager {
break;
case REASON_MAIN_USAGE:
sb.append("u");
switch (standbyReason & REASON_SUB_MASK) {
switch (subReason) {
case REASON_SUB_USAGE_SYSTEM_INTERACTION:
sb.append("-si");
break;

View File

@@ -20,7 +20,7 @@ import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED_BY_SYSTEM;
import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED_BY_USER;
import static android.app.usage.UsageStatsManager.REASON_MAIN_TIMEOUT;
import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE;
import static android.app.usage.UsageStatsManager.REASON_SUB_RESTRICT_BACKGROUND_RESOURCE_USAGE;
import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_FOREGROUND;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT;
@@ -103,7 +103,8 @@ public class AppIdleHistoryTests extends AndroidTestCase {
aih.setAppStandbyBucket(PACKAGE_2, USER_ID, 2000, STANDBY_BUCKET_ACTIVE,
REASON_MAIN_USAGE);
aih.setAppStandbyBucket(PACKAGE_3, USER_ID, 2500, STANDBY_BUCKET_RESTRICTED,
REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_RESTRICT_BACKGROUND_RESOURCE_USAGE);
REASON_MAIN_FORCED_BY_SYSTEM
| REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE);
aih.setAppStandbyBucket(PACKAGE_4, USER_ID, 2750, STANDBY_BUCKET_RESTRICTED,
REASON_MAIN_FORCED_BY_USER);
aih.setAppStandbyBucket(PACKAGE_1, USER_ID, 3000, STANDBY_BUCKET_RARE,
@@ -114,7 +115,8 @@ public class AppIdleHistoryTests extends AndroidTestCase {
assertEquals(aih.getAppStandbyReason(PACKAGE_1, USER_ID, 3000), REASON_MAIN_TIMEOUT);
assertEquals(aih.getAppStandbyBucket(PACKAGE_3, USER_ID, 3000), STANDBY_BUCKET_RESTRICTED);
assertEquals(aih.getAppStandbyReason(PACKAGE_3, USER_ID, 3000),
REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_RESTRICT_BACKGROUND_RESOURCE_USAGE);
REASON_MAIN_FORCED_BY_SYSTEM
| REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE);
assertEquals(aih.getAppStandbyReason(PACKAGE_4, USER_ID, 3000),
REASON_MAIN_FORCED_BY_USER);
@@ -133,7 +135,8 @@ public class AppIdleHistoryTests extends AndroidTestCase {
assertEquals(aih.getAppStandbyReason(PACKAGE_1, USER_ID, 5000), REASON_MAIN_TIMEOUT);
assertEquals(aih.getAppStandbyBucket(PACKAGE_3, USER_ID, 3000), STANDBY_BUCKET_RESTRICTED);
assertEquals(aih.getAppStandbyReason(PACKAGE_3, USER_ID, 3000),
REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_RESTRICT_BACKGROUND_RESOURCE_USAGE);
REASON_MAIN_FORCED_BY_SYSTEM
| REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE);
assertEquals(aih.getAppStandbyReason(PACKAGE_4, USER_ID, 3000),
REASON_MAIN_FORCED_BY_USER);

View File

@@ -28,6 +28,10 @@ import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED_BY_USER;
import static android.app.usage.UsageStatsManager.REASON_MAIN_PREDICTED;
import static android.app.usage.UsageStatsManager.REASON_MAIN_TIMEOUT;
import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE;
import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE;
import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE;
import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY;
import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_FOREGROUND;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SYNC_ADAPTER;
@@ -434,6 +438,11 @@ public class AppStandbyControllerTests {
true);
}
private int getStandbyBucketReason(String packageName) {
return mController.getAppStandbyBucketReason(packageName, USER_ID,
mInjector.mElapsedRealtime);
}
private void assertBucket(int bucket) {
assertEquals(bucket, getStandbyBucket(mController, PACKAGE_1));
}
@@ -1004,6 +1013,79 @@ public class AppStandbyControllerTests {
assertBucket(STANDBY_BUCKET_FREQUENT);
}
@Test
public void testSystemForcedFlags_NotAddedForUserForce() throws Exception {
final int expectedReason = REASON_MAIN_FORCED_BY_USER;
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED,
REASON_MAIN_FORCED_BY_USER);
assertEquals(STANDBY_BUCKET_RESTRICTED, getStandbyBucket(mController, PACKAGE_1));
assertEquals(expectedReason, getStandbyBucketReason(PACKAGE_1));
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED,
REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE);
assertEquals(STANDBY_BUCKET_RESTRICTED, getStandbyBucket(mController, PACKAGE_1));
assertEquals(expectedReason, getStandbyBucketReason(PACKAGE_1));
}
@Test
public void testSystemForcedFlags_AddedForSystemForce() throws Exception {
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
REASON_MAIN_DEFAULT);
mInjector.mElapsedRealtime += 4 * RESTRICTED_THRESHOLD;
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED,
REASON_MAIN_FORCED_BY_SYSTEM
| REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE);
assertEquals(STANDBY_BUCKET_RESTRICTED, getStandbyBucket(mController, PACKAGE_1));
assertEquals(REASON_MAIN_FORCED_BY_SYSTEM
| REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE,
getStandbyBucketReason(PACKAGE_1));
mController.restrictApp(PACKAGE_1, USER_ID, REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE);
assertEquals(STANDBY_BUCKET_RESTRICTED, getStandbyBucket(mController, PACKAGE_1));
// Flags should be combined
assertEquals(REASON_MAIN_FORCED_BY_SYSTEM
| REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE
| REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE, getStandbyBucketReason(PACKAGE_1));
}
@Test
public void testSystemForcedFlags_SystemForceChangesBuckets() throws Exception {
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
REASON_MAIN_DEFAULT);
mInjector.mElapsedRealtime += 4 * RESTRICTED_THRESHOLD;
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
REASON_MAIN_FORCED_BY_SYSTEM
| REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE);
assertEquals(STANDBY_BUCKET_FREQUENT, getStandbyBucket(mController, PACKAGE_1));
assertEquals(REASON_MAIN_FORCED_BY_SYSTEM
| REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE,
getStandbyBucketReason(PACKAGE_1));
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE);
assertEquals(STANDBY_BUCKET_FREQUENT, getStandbyBucket(mController, PACKAGE_1));
// Flags should be combined
assertEquals(REASON_MAIN_FORCED_BY_SYSTEM
| REASON_SUB_FORCED_SYSTEM_FLAG_BACKGROUND_RESOURCE_USAGE
| REASON_SUB_FORCED_SYSTEM_FLAG_ABUSE,
getStandbyBucketReason(PACKAGE_1));
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE,
REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY);
assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1));
// Flags should be combined
assertEquals(REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY,
getStandbyBucketReason(PACKAGE_1));
mController.restrictApp(PACKAGE_1, USER_ID, REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED);
assertEquals(STANDBY_BUCKET_RESTRICTED, getStandbyBucket(mController, PACKAGE_1));
// Flags should not be combined since the bucket changed.
assertEquals(REASON_MAIN_FORCED_BY_SYSTEM | REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED,
getStandbyBucketReason(PACKAGE_1));
}
@Test
public void testAddActiveDeviceAdmin() {
assertActiveAdmins(USER_ID, (String[]) null);