summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Michael Wachenschwanz <mwachens@google.com> 2019-04-15 16:43:28 -0700
committer Michael Wachenschwanz <mwachens@google.com> 2019-04-16 14:00:37 -0700
commit6ced0ee15adb7d40b30d60e26d65527c3640a524 (patch)
treeb655a5a85a652f90c84238ad127668876ada2def
parent11141109f4c9f8f423245113f8588d0371015bc1 (diff)
Elevate standby bucket on first foreground service start
If an app is in the NEVER standby bucket, a foreground service start will bring the app up to the ACTIVE bucket for 30 min (by default). Foreground service starts in other circumstances will not affect the standby bucket Bug: 111578623 Test: atest AppStandbyControllerTests#testInitialForegroundServiceTimeout Change-Id: Ia9d5fd7a04d2378a5525457d465da7ed463fe8fc
-rw-r--r--core/java/android/app/usage/UsageStatsManager.java5
-rw-r--r--core/java/android/provider/Settings.java1
-rw-r--r--services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java36
-rw-r--r--services/usage/java/com/android/server/usage/AppStandbyController.java30
4 files changed, 71 insertions, 1 deletions
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index f8dc20e9af09..7fa436084246 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -198,6 +198,8 @@ public final class UsageStatsManager {
/** @hide */
public static final int REASON_SUB_USAGE_UNEXEMPTED_SYNC_SCHEDULED = 0x000E;
/** @hide */
+ public static final int REASON_SUB_USAGE_FOREGROUND_SERVICE_START = 0x000F;
+ /** @hide */
public static final int REASON_SUB_PREDICTED_RESTORED = 0x0001;
@@ -997,6 +999,9 @@ public final class UsageStatsManager {
case REASON_SUB_USAGE_UNEXEMPTED_SYNC_SCHEDULED:
sb.append("-uss");
break;
+ case REASON_SUB_USAGE_FOREGROUND_SERVICE_START:
+ sb.append("-fss");
+ break;
}
break;
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 0491c732db81..2c8e68cbe196 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -11811,6 +11811,7 @@ public final class Settings {
* sync_adapter_duration (long)
* exempted_sync_duration (long)
* system_interaction_duration (long)
+ * initial_foreground_service_start_duration (long)
* stable_charging_threshold (long)
*
* idle_duration (long) // This is deprecated and used to circumvent b/26355386.
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 6ec864c05258..f4a6231e43fb 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -16,6 +16,7 @@
package com.android.server.usage;
+import static android.app.usage.UsageEvents.Event.FOREGROUND_SERVICE_START;
import static android.app.usage.UsageEvents.Event.NOTIFICATION_SEEN;
import static android.app.usage.UsageEvents.Event.SLICE_PINNED;
import static android.app.usage.UsageEvents.Event.SLICE_PINNED_PRIV;
@@ -821,6 +822,41 @@ public class AppStandbyControllerTests {
}
@Test
+ public void testInitialForegroundServiceTimeout() throws Exception {
+ setChargingState(mController, false);
+
+ mInjector.mElapsedRealtime = 1 * RARE_THRESHOLD + 100;
+ // Make sure app is in NEVER bucket
+ mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
+ REASON_MAIN_FORCED, mInjector.mElapsedRealtime);
+ mController.checkIdleStates(USER_ID);
+ assertBucket(STANDBY_BUCKET_NEVER);
+
+ mInjector.mElapsedRealtime += 100;
+
+ // Trigger a FOREGROUND_SERVICE_START and verify bucket
+ reportEvent(mController, FOREGROUND_SERVICE_START, mInjector.mElapsedRealtime, PACKAGE_1);
+ mController.checkIdleStates(USER_ID);
+ assertBucket(STANDBY_BUCKET_ACTIVE);
+
+ // Verify it's still in ACTIVE close to end of timeout
+ mInjector.mElapsedRealtime += mController.mInitialForegroundServiceStartTimeoutMillis - 100;
+ mController.checkIdleStates(USER_ID);
+ assertBucket(STANDBY_BUCKET_ACTIVE);
+
+ // Verify bucket moves to RARE after timeout
+ mInjector.mElapsedRealtime += 200;
+ mController.checkIdleStates(USER_ID);
+ assertBucket(STANDBY_BUCKET_RARE);
+
+ // Trigger a FOREGROUND_SERVICE_START again
+ reportEvent(mController, FOREGROUND_SERVICE_START, mInjector.mElapsedRealtime, PACKAGE_1);
+ mController.checkIdleStates(USER_ID);
+ // Bucket should not be immediately elevated on subsequent service starts
+ assertBucket(STANDBY_BUCKET_RARE);
+ }
+
+ @Test
public void testPredictionNotOverridden() throws Exception {
reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
diff --git a/services/usage/java/com/android/server/usage/AppStandbyController.java b/services/usage/java/com/android/server/usage/AppStandbyController.java
index 4b33e165bfeb..77866279a751 100644
--- a/services/usage/java/com/android/server/usage/AppStandbyController.java
+++ b/services/usage/java/com/android/server/usage/AppStandbyController.java
@@ -27,6 +27,7 @@ import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_ACTIVE_TIMEOU
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_START;
+import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_FOREGROUND_SERVICE_START;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_BACKGROUND;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_FOREGROUND;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_NOTIFICATION_SEEN;
@@ -238,6 +239,11 @@ public class AppStandbyController {
long mUnexemptedSyncScheduledTimeoutMillis;
/** Maximum time a system interaction should keep the buckets elevated. */
long mSystemInteractionTimeoutMillis;
+ /**
+ * Maximum time a foreground service start should keep the buckets elevated if the service
+ * start is the first usage of the app
+ */
+ long mInitialForegroundServiceStartTimeoutMillis;
/** The length of time phone must be charging before considered stable enough to run jobs */
long mStableChargingThresholdMillis;
@@ -877,7 +883,8 @@ public class AppStandbyController {
|| event.mEventType == UsageEvents.Event.USER_INTERACTION
|| event.mEventType == UsageEvents.Event.NOTIFICATION_SEEN
|| event.mEventType == UsageEvents.Event.SLICE_PINNED
- || event.mEventType == UsageEvents.Event.SLICE_PINNED_PRIV)) {
+ || event.mEventType == UsageEvents.Event.SLICE_PINNED_PRIV
+ || event.mEventType == UsageEvents.Event.FOREGROUND_SERVICE_START)) {
final AppUsageHistory appHistory = mAppIdleHistory.getAppUsageHistory(
event.mPackage, userId, elapsedRealtime);
@@ -898,6 +905,13 @@ public class AppStandbyController {
STANDBY_BUCKET_ACTIVE, subReason,
0, elapsedRealtime + mSystemInteractionTimeoutMillis);
nextCheckTime = mSystemInteractionTimeoutMillis;
+ } else if (event.mEventType == UsageEvents.Event.FOREGROUND_SERVICE_START) {
+ // Only elevate bucket if this is the first usage of the app
+ if (prevBucket != STANDBY_BUCKET_NEVER) return;
+ mAppIdleHistory.reportUsage(appHistory, event.mPackage,
+ STANDBY_BUCKET_ACTIVE, subReason,
+ 0, elapsedRealtime + mInitialForegroundServiceStartTimeoutMillis);
+ nextCheckTime = mInitialForegroundServiceStartTimeoutMillis;
} else {
mAppIdleHistory.reportUsage(appHistory, event.mPackage,
STANDBY_BUCKET_ACTIVE, subReason,
@@ -930,6 +944,8 @@ public class AppStandbyController {
case UsageEvents.Event.NOTIFICATION_SEEN: return REASON_SUB_USAGE_NOTIFICATION_SEEN;
case UsageEvents.Event.SLICE_PINNED: return REASON_SUB_USAGE_SLICE_PINNED;
case UsageEvents.Event.SLICE_PINNED_PRIV: return REASON_SUB_USAGE_SLICE_PINNED_PRIV;
+ case UsageEvents.Event.FOREGROUND_SERVICE_START:
+ return REASON_SUB_USAGE_FOREGROUND_SERVICE_START;
default: return 0;
}
}
@@ -1509,6 +1525,9 @@ public class AppStandbyController {
pw.print(" mSystemInteractionTimeoutMillis=");
TimeUtils.formatDuration(mSystemInteractionTimeoutMillis, pw);
pw.println();
+ pw.print(" mInitialForegroundServiceStartTimeoutMillis=");
+ TimeUtils.formatDuration(mInitialForegroundServiceStartTimeoutMillis, pw);
+ pw.println();
pw.print(" mPredictionTimeoutMillis=");
TimeUtils.formatDuration(mPredictionTimeoutMillis, pw);
@@ -1848,6 +1867,8 @@ public class AppStandbyController {
"unexempted_sync_scheduled_duration";
private static final String KEY_SYSTEM_INTERACTION_HOLD_DURATION =
"system_interaction_duration";
+ private static final String KEY_INITIAL_FOREGROUND_SERVICE_START_HOLD_DURATION =
+ "initial_foreground_service_start_duration";
private static final String KEY_STABLE_CHARGING_THRESHOLD = "stable_charging_threshold";
public static final long DEFAULT_STRONG_USAGE_TIMEOUT = 1 * ONE_HOUR;
public static final long DEFAULT_NOTIFICATION_TIMEOUT = 12 * ONE_HOUR;
@@ -1859,6 +1880,7 @@ public class AppStandbyController {
public static final long DEFAULT_EXEMPTED_SYNC_START_TIMEOUT = 10 * ONE_MINUTE;
public static final long DEFAULT_UNEXEMPTED_SYNC_SCHEDULED_TIMEOUT = 10 * ONE_MINUTE;
public static final long DEFAULT_STABLE_CHARGING_THRESHOLD = 10 * ONE_MINUTE;
+ public static final long DEFAULT_INITIAL_FOREGROUND_SERVICE_START_TIMEOUT = 30 * ONE_MINUTE;
private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -1964,6 +1986,12 @@ public class AppStandbyController {
mSystemInteractionTimeoutMillis = mParser.getDurationMillis(
KEY_SYSTEM_INTERACTION_HOLD_DURATION,
COMPRESS_TIME ? ONE_MINUTE : DEFAULT_SYSTEM_INTERACTION_TIMEOUT);
+
+ mInitialForegroundServiceStartTimeoutMillis = mParser.getDurationMillis(
+ KEY_INITIAL_FOREGROUND_SERVICE_START_HOLD_DURATION,
+ COMPRESS_TIME ? ONE_MINUTE :
+ DEFAULT_INITIAL_FOREGROUND_SERVICE_START_TIMEOUT);
+
mStableChargingThresholdMillis = mParser.getDurationMillis(
KEY_STABLE_CHARGING_THRESHOLD,
COMPRESS_TIME ? ONE_MINUTE : DEFAULT_STABLE_CHARGING_THRESHOLD);