summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2017-12-15 00:46:24 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2017-12-15 00:46:24 +0000
commitd361a51596790be25ac7be9fd8fe80e2da8e5df0 (patch)
tree3a21efec881e2a5654726408e9483e134a25679e
parentf8f9e5da97af5a2ae644c0106efd1017726767e7 (diff)
parent9388519d5e66a84485f8951242b9756e586a85ac (diff)
Merge "Don't allow certain bucket overrides"
-rw-r--r--services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java147
-rw-r--r--services/usage/java/com/android/server/usage/AppStandbyController.java32
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java14
3 files changed, 126 insertions, 67 deletions
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index 86ce90c03ae4..b792d821ae93 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -18,9 +18,14 @@ package com.android.server.usage;
import static android.app.usage.UsageEvents.Event.NOTIFICATION_SEEN;
import static android.app.usage.UsageEvents.Event.USER_INTERACTION;
+import static android.app.usage.UsageStatsManager.REASON_DEFAULT;
+import static android.app.usage.UsageStatsManager.REASON_FORCED;
import static android.app.usage.UsageStatsManager.REASON_PREDICTED;
+import static android.app.usage.UsageStatsManager.REASON_TIMEOUT;
+import static android.app.usage.UsageStatsManager.REASON_USAGE;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT;
+import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_NEVER;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
@@ -79,6 +84,7 @@ public class AppStandbyControllerTests {
private static final long RARE_THRESHOLD = 48 * HOUR_MS;
private MyInjector mInjector;
+ private AppStandbyController mController;
static class MyContextWrapper extends ContextWrapper {
PackageManager mockPm = mock(PackageManager.class);
@@ -237,24 +243,23 @@ public class AppStandbyControllerTests {
public void setUp() throws Exception {
MyContextWrapper myContext = new MyContextWrapper(InstrumentationRegistry.getContext());
mInjector = new MyInjector(myContext, Looper.getMainLooper());
+ mController = setupController();
}
@Test
public void testCharging() throws Exception {
- AppStandbyController controller = setupController();
-
- setChargingState(controller, true);
+ setChargingState(mController, true);
mInjector.mElapsedRealtime = RARE_THRESHOLD + 1;
- assertFalse(controller.isAppIdleFilteredOrParoled(PACKAGE_1, USER_ID,
+ assertFalse(mController.isAppIdleFilteredOrParoled(PACKAGE_1, USER_ID,
mInjector.mElapsedRealtime, false));
- setChargingState(controller, false);
+ setChargingState(mController, false);
mInjector.mElapsedRealtime = 2 * RARE_THRESHOLD + 2;
- controller.checkIdleStates(USER_ID);
- assertTrue(controller.isAppIdleFilteredOrParoled(PACKAGE_1, USER_ID,
+ mController.checkIdleStates(USER_ID);
+ assertTrue(mController.isAppIdleFilteredOrParoled(PACKAGE_1, USER_ID,
mInjector.mElapsedRealtime, false));
- setChargingState(controller, true);
- assertFalse(controller.isAppIdleFilteredOrParoled(PACKAGE_1,USER_ID,
+ setChargingState(mController, true);
+ assertFalse(mController.isAppIdleFilteredOrParoled(PACKAGE_1,USER_ID,
mInjector.mElapsedRealtime, false));
}
@@ -282,112 +287,142 @@ public class AppStandbyControllerTests {
@Test
public void testBuckets() throws Exception {
- AppStandbyController controller = setupController();
-
- assertTimeout(controller, 0, UsageStatsManager.STANDBY_BUCKET_NEVER);
+ assertTimeout(mController, 0, STANDBY_BUCKET_NEVER);
- reportEvent(controller, USER_INTERACTION, 0);
+ reportEvent(mController, USER_INTERACTION, 0);
// ACTIVE bucket
- assertTimeout(controller, WORKING_SET_THRESHOLD - 1, STANDBY_BUCKET_ACTIVE);
+ assertTimeout(mController, WORKING_SET_THRESHOLD - 1, STANDBY_BUCKET_ACTIVE);
// WORKING_SET bucket
- assertTimeout(controller, WORKING_SET_THRESHOLD + 1, STANDBY_BUCKET_WORKING_SET);
+ assertTimeout(mController, WORKING_SET_THRESHOLD + 1, STANDBY_BUCKET_WORKING_SET);
// WORKING_SET bucket
- assertTimeout(controller, FREQUENT_THRESHOLD - 1, STANDBY_BUCKET_WORKING_SET);
+ assertTimeout(mController, FREQUENT_THRESHOLD - 1, STANDBY_BUCKET_WORKING_SET);
// FREQUENT bucket
- assertTimeout(controller, FREQUENT_THRESHOLD + 1, STANDBY_BUCKET_FREQUENT);
+ assertTimeout(mController, FREQUENT_THRESHOLD + 1, STANDBY_BUCKET_FREQUENT);
// RARE bucket
- assertTimeout(controller, RARE_THRESHOLD + 1, STANDBY_BUCKET_RARE);
+ assertTimeout(mController, RARE_THRESHOLD + 1, STANDBY_BUCKET_RARE);
- reportEvent(controller, USER_INTERACTION, RARE_THRESHOLD + 1);
+ reportEvent(mController, USER_INTERACTION, RARE_THRESHOLD + 1);
- assertTimeout(controller, RARE_THRESHOLD + 1, STANDBY_BUCKET_ACTIVE);
+ assertTimeout(mController, RARE_THRESHOLD + 1, STANDBY_BUCKET_ACTIVE);
// RARE bucket
- assertTimeout(controller, RARE_THRESHOLD * 2 + 2, STANDBY_BUCKET_RARE);
+ assertTimeout(mController, RARE_THRESHOLD * 2 + 2, STANDBY_BUCKET_RARE);
}
@Test
public void testScreenTimeAndBuckets() throws Exception {
- AppStandbyController controller = setupController();
mInjector.setDisplayOn(false);
- assertTimeout(controller, 0, UsageStatsManager.STANDBY_BUCKET_NEVER);
+ assertTimeout(mController, 0, STANDBY_BUCKET_NEVER);
- reportEvent(controller, USER_INTERACTION, 0);
+ reportEvent(mController, USER_INTERACTION, 0);
// ACTIVE bucket
- assertTimeout(controller, WORKING_SET_THRESHOLD - 1, STANDBY_BUCKET_ACTIVE);
+ assertTimeout(mController, WORKING_SET_THRESHOLD - 1, STANDBY_BUCKET_ACTIVE);
// WORKING_SET bucket
- assertTimeout(controller, WORKING_SET_THRESHOLD + 1, STANDBY_BUCKET_WORKING_SET);
+ assertTimeout(mController, WORKING_SET_THRESHOLD + 1, STANDBY_BUCKET_WORKING_SET);
// RARE bucket, should fail because the screen wasn't ON.
mInjector.mElapsedRealtime = RARE_THRESHOLD + 1;
- controller.checkIdleStates(USER_ID);
- assertNotEquals(STANDBY_BUCKET_RARE, getStandbyBucket(controller));
+ mController.checkIdleStates(USER_ID);
+ assertNotEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController));
mInjector.setDisplayOn(true);
- assertTimeout(controller, RARE_THRESHOLD * 2 + 2, STANDBY_BUCKET_RARE);
+ assertTimeout(mController, RARE_THRESHOLD * 2 + 2, STANDBY_BUCKET_RARE);
}
@Test
public void testForcedIdle() throws Exception {
- AppStandbyController controller = setupController();
- setChargingState(controller, false);
+ setChargingState(mController, false);
- controller.forceIdleState(PACKAGE_1, USER_ID, true);
- assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(controller));
- assertTrue(controller.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, 0));
+ mController.forceIdleState(PACKAGE_1, USER_ID, true);
+ assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController));
+ assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, 0));
- controller.forceIdleState(PACKAGE_1, USER_ID, false);
- assertEquals(STANDBY_BUCKET_ACTIVE, controller.getAppStandbyBucket(PACKAGE_1, USER_ID, 0,
+ mController.forceIdleState(PACKAGE_1, USER_ID, false);
+ assertEquals(STANDBY_BUCKET_ACTIVE, mController.getAppStandbyBucket(PACKAGE_1, USER_ID, 0,
true));
- assertFalse(controller.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, 0));
+ assertFalse(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, 0));
}
@Test
public void testNotificationEvent() throws Exception {
- AppStandbyController controller = setupController();
- setChargingState(controller, false);
+ setChargingState(mController, false);
- reportEvent(controller, USER_INTERACTION, 0);
- assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(controller));
+ reportEvent(mController, USER_INTERACTION, 0);
+ assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
mInjector.mElapsedRealtime = 1;
- reportEvent(controller, NOTIFICATION_SEEN, mInjector.mElapsedRealtime);
- assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(controller));
+ reportEvent(mController, NOTIFICATION_SEEN, mInjector.mElapsedRealtime);
+ assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
- controller.forceIdleState(PACKAGE_1, USER_ID, true);
- reportEvent(controller, NOTIFICATION_SEEN, mInjector.mElapsedRealtime);
- assertEquals(STANDBY_BUCKET_WORKING_SET, getStandbyBucket(controller));
+ mController.forceIdleState(PACKAGE_1, USER_ID, true);
+ reportEvent(mController, NOTIFICATION_SEEN, mInjector.mElapsedRealtime);
+ assertEquals(STANDBY_BUCKET_WORKING_SET, getStandbyBucket(mController));
}
@Test
public void testPredictionTimedout() throws Exception {
- AppStandbyController controller = setupController();
- setChargingState(controller, false);
- controller.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
- REASON_PREDICTED + "CTS", 1 * HOUR_MS);
+ setChargingState(mController, false);
+ // Set it to timeout or usage, so that prediction can override it
+ mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE,
+ REASON_TIMEOUT, 1 * HOUR_MS);
+ assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController));
+
+ mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
+ REASON_PREDICTED + ":CTS", 1 * HOUR_MS);
+ assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
// Fast forward 12 hours
mInjector.mElapsedRealtime += WORKING_SET_THRESHOLD;
- controller.checkIdleStates(USER_ID);
+ mController.checkIdleStates(USER_ID);
// Should still be in predicted bucket, since prediction timeout is 1 day since prediction
- assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(controller));
+ assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
// Fast forward two more hours
mInjector.mElapsedRealtime += 2 * HOUR_MS;
- controller.checkIdleStates(USER_ID);
+ mController.checkIdleStates(USER_ID);
// Should have now applied prediction timeout
- assertEquals(STANDBY_BUCKET_WORKING_SET, getStandbyBucket(controller));
+ assertEquals(STANDBY_BUCKET_WORKING_SET, getStandbyBucket(mController));
// Fast forward RARE bucket
mInjector.mElapsedRealtime += RARE_THRESHOLD;
- controller.checkIdleStates(USER_ID);
+ mController.checkIdleStates(USER_ID);
// Should continue to apply prediction timeout
- assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(controller));
+ assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController));
+ }
+
+ @Test
+ public void testOverrides() throws Exception {
+ setChargingState(mController, false);
+ // Can force to NEVER
+ mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
+ REASON_FORCED, 1 * HOUR_MS);
+ assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController));
+
+ // Prediction can't override FORCED reason
+ mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
+ REASON_FORCED, 1 * HOUR_MS);
+ mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_WORKING_SET,
+ REASON_PREDICTED, 1 * HOUR_MS);
+ assertEquals(STANDBY_BUCKET_FREQUENT, getStandbyBucket(mController));
+
+ // Prediction can't override NEVER
+ mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
+ REASON_DEFAULT, 2 * HOUR_MS);
+ mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
+ REASON_PREDICTED, 2 * HOUR_MS);
+ assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController));
+
+ // Prediction can't set to NEVER
+ mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
+ REASON_USAGE, 2 * HOUR_MS);
+ mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
+ REASON_PREDICTED, 2 * HOUR_MS);
+ assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
}
}
diff --git a/services/usage/java/com/android/server/usage/AppStandbyController.java b/services/usage/java/com/android/server/usage/AppStandbyController.java
index 46efbd059d52..cc0259ddaa2b 100644
--- a/services/usage/java/com/android/server/usage/AppStandbyController.java
+++ b/services/usage/java/com/android/server/usage/AppStandbyController.java
@@ -24,6 +24,7 @@ import static android.app.usage.UsageStatsManager.REASON_USAGE;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_EXEMPTED;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT;
+import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_NEVER;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
@@ -133,7 +134,7 @@ public class AppStandbyController {
@GuardedBy("mAppIdleLock")
private AppIdleHistory mAppIdleHistory;
- @GuardedBy("mAppIdleLock")
+ @GuardedBy("mPackageAccessListeners")
private ArrayList<AppIdleStateChangeListener>
mPackageAccessListeners = new ArrayList<>();
@@ -592,7 +593,7 @@ public class AppStandbyController {
}
void addListener(AppIdleStateChangeListener listener) {
- synchronized (mAppIdleLock) {
+ synchronized (mPackageAccessListeners) {
if (!mPackageAccessListeners.contains(listener)) {
mPackageAccessListeners.add(listener);
}
@@ -600,7 +601,7 @@ public class AppStandbyController {
}
void removeListener(AppIdleStateChangeListener listener) {
- synchronized (mAppIdleLock) {
+ synchronized (mPackageAccessListeners) {
mPackageAccessListeners.remove(listener);
}
}
@@ -789,6 +790,19 @@ public class AppStandbyController {
void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
String reason, long elapsedRealtime) {
synchronized (mAppIdleLock) {
+ AppIdleHistory.AppUsageHistory app = mAppIdleHistory.getAppUsageHistory(packageName,
+ userId, elapsedRealtime);
+ boolean predicted = reason != null && reason.startsWith(REASON_PREDICTED);
+ // Don't allow changing bucket if higher than ACTIVE
+ if (app.currentBucket < STANDBY_BUCKET_ACTIVE) return;
+ // Don't allow prediction to change from or to NEVER
+ if ((app.currentBucket == STANDBY_BUCKET_NEVER
+ || newBucket == STANDBY_BUCKET_NEVER)
+ && predicted) {
+ return;
+ }
+ // If the bucket was forced, don't allow prediction to override
+ if (app.bucketingReason.equals(REASON_FORCED) && predicted) return;
mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime, newBucket,
reason);
}
@@ -852,15 +866,19 @@ public class AppStandbyController {
void informListeners(String packageName, int userId, int bucket) {
final boolean idle = bucket >= STANDBY_BUCKET_RARE;
- for (AppIdleStateChangeListener listener : mPackageAccessListeners) {
- listener.onAppIdleStateChanged(packageName, userId, idle, bucket);
+ synchronized (mPackageAccessListeners) {
+ for (AppIdleStateChangeListener listener : mPackageAccessListeners) {
+ listener.onAppIdleStateChanged(packageName, userId, idle, bucket);
+ }
}
}
void informParoleStateChanged() {
final boolean paroled = isParoledOrCharging();
- for (AppIdleStateChangeListener listener : mPackageAccessListeners) {
- listener.onParoleStateChanged(paroled);
+ synchronized (mPackageAccessListeners) {
+ for (AppIdleStateChangeListener listener : mPackageAccessListeners) {
+ listener.onParoleStateChanged(paroled);
+ }
}
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 15284d5e3dec..07c860b54413 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -728,6 +728,10 @@ public class UsageStatsService extends SystemService implements
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
+ final boolean shellCaller = callingUid == 0 || callingUid == Process.SHELL_UID;
+ final String reason = shellCaller
+ ? UsageStatsManager.REASON_FORCED
+ : UsageStatsManager.REASON_PREDICTED + ":" + callingUid;
final long token = Binder.clearCallingIdentity();
try {
// Caller cannot set their own standby state
@@ -735,8 +739,7 @@ public class UsageStatsService extends SystemService implements
PackageManager.MATCH_ANY_USER, userId) == callingUid) {
throw new IllegalArgumentException("Cannot set your own standby bucket");
}
- mAppStandby.setAppStandbyBucket(packageName, userId, bucket,
- UsageStatsManager.REASON_PREDICTED + ":" + callingUid,
+ mAppStandby.setAppStandbyBucket(packageName, userId, bucket, reason,
SystemClock.elapsedRealtime());
} finally {
Binder.restoreCallingIdentity(token);
@@ -779,6 +782,10 @@ public class UsageStatsService extends SystemService implements
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
+ final boolean shellCaller = callingUid == 0 || callingUid == Process.SHELL_UID;
+ final String reason = shellCaller
+ ? UsageStatsManager.REASON_FORCED
+ : UsageStatsManager.REASON_PREDICTED + ":" + callingUid;
final long token = Binder.clearCallingIdentity();
try {
final long elapsedRealtime = SystemClock.elapsedRealtime();
@@ -796,8 +803,7 @@ public class UsageStatsService extends SystemService implements
PackageManager.MATCH_ANY_USER, userId) == callingUid) {
throw new IllegalArgumentException("Cannot set your own standby bucket");
}
- mAppStandby.setAppStandbyBucket(packageName, userId, bucket,
- UsageStatsManager.REASON_PREDICTED + ":" + callingUid,
+ mAppStandby.setAppStandbyBucket(packageName, userId, bucket, reason,
elapsedRealtime);
}
} finally {