From 7cc9d2d11e9c48641485baff3d022e9dccb2a12c Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Tue, 15 Mar 2022 13:58:49 -0700 Subject: [PATCH] Initialize lastUsedElapsedTime to Integer.MIN_VALUE. Since 'lastUsedElapsedTime' indicates the timestamp at which the app was last used by the user and this isn't necessarily the reason why we create AppUsageHistory objects, we shouldn't be initializing the 'lastUsedElapsedTime' to the timestamp at which the object is being created. Also, update 'lastPredictedTime' to Integer.MIN_VALUE as getElapsedTime() time doesn't return predictable values for timestamps in the past and passing getElapsedTime(0) isn't accurate as it basically indicates the timestamp at boot. Bug: 206518483 Test: atest tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java Change-Id: Ib90b435b1efc34144f0461aaaf339fc6037ecdc2 --- .../android/server/usage/AppIdleHistory.java | 37 +++++++++++++------ .../server/usage/AppStandbyController.java | 5 ++- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java index e986b1a9bf24d..2e3b377d08a55 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java @@ -384,14 +384,16 @@ public class AppIdleHistory { return userHistory; } + // TODO (206518483): Remove unused parameter 'elapsedRealtime'. private AppUsageHistory getPackageHistory(ArrayMap userHistory, String packageName, long elapsedRealtime, boolean create) { AppUsageHistory appUsageHistory = userHistory.get(packageName); if (appUsageHistory == null && create) { appUsageHistory = new AppUsageHistory(); - appUsageHistory.lastUsedElapsedTime = getElapsedTime(elapsedRealtime); - appUsageHistory.lastUsedScreenTime = getScreenOnTime(elapsedRealtime); - appUsageHistory.lastPredictedTime = getElapsedTime(0); + appUsageHistory.lastUsedByUserElapsedTime = Integer.MIN_VALUE; + appUsageHistory.lastUsedElapsedTime = Integer.MIN_VALUE; + appUsageHistory.lastUsedScreenTime = Integer.MIN_VALUE; + appUsageHistory.lastPredictedTime = Integer.MIN_VALUE; appUsageHistory.currentBucket = STANDBY_BUCKET_NEVER; appUsageHistory.bucketingReason = REASON_MAIN_DEFAULT; appUsageHistory.lastInformedBucket = -1; @@ -544,7 +546,7 @@ public class AppIdleHistory { AppUsageHistory appUsageHistory = getPackageHistory(userHistory, packageName, elapsedRealtime, false); if (appUsageHistory == null || appUsageHistory.lastUsedByUserElapsedTime == Long.MIN_VALUE - || appUsageHistory.lastUsedByUserElapsedTime == 0) { + || appUsageHistory.lastUsedByUserElapsedTime <= 0) { return Long.MAX_VALUE; } return getElapsedTime(elapsedRealtime) - appUsageHistory.lastUsedByUserElapsedTime; @@ -631,8 +633,12 @@ public class AppIdleHistory { // If we don't have any state for the app, assume never used if (appUsageHistory == null) return screenTimeThresholds.length - 1; - long screenOnDelta = getScreenOnTime(elapsedRealtime) - appUsageHistory.lastUsedScreenTime; - long elapsedDelta = getElapsedTime(elapsedRealtime) - appUsageHistory.lastUsedElapsedTime; + long screenOnDelta = appUsageHistory.lastUsedScreenTime >= 0 + ? getScreenOnTime(elapsedRealtime) - appUsageHistory.lastUsedScreenTime + : Long.MAX_VALUE; + long elapsedDelta = appUsageHistory.lastUsedElapsedTime >= 0 + ? getElapsedTime(elapsedRealtime) - appUsageHistory.lastUsedElapsedTime + : Long.MAX_VALUE; if (DEBUG) Slog.d(TAG, packageName + " lastUsedScreen=" + appUsageHistory.lastUsedScreenTime @@ -951,14 +957,14 @@ public class AppIdleHistory { + " reason=" + UsageStatsManager.reasonToString(appUsageHistory.bucketingReason)); idpw.print(" used="); - TimeUtils.formatDuration(totalElapsedTime - appUsageHistory.lastUsedElapsedTime, idpw); + printLastActionElapsedTime(idpw, totalElapsedTime, appUsageHistory.lastUsedElapsedTime); idpw.print(" usedByUser="); - TimeUtils.formatDuration(totalElapsedTime - appUsageHistory.lastUsedByUserElapsedTime, - idpw); + printLastActionElapsedTime(idpw, totalElapsedTime, + appUsageHistory.lastUsedByUserElapsedTime); idpw.print(" usedScr="); - TimeUtils.formatDuration(screenOnTime - appUsageHistory.lastUsedScreenTime, idpw); + printLastActionElapsedTime(idpw, totalElapsedTime, appUsageHistory.lastUsedScreenTime); idpw.print(" lastPred="); - TimeUtils.formatDuration(totalElapsedTime - appUsageHistory.lastPredictedTime, idpw); + printLastActionElapsedTime(idpw, totalElapsedTime, appUsageHistory.lastPredictedTime); dumpBucketExpiryTimes(idpw, appUsageHistory, totalElapsedTime); idpw.print(" lastJob="); TimeUtils.formatDuration(totalElapsedTime - appUsageHistory.lastJobRunTime, idpw); @@ -986,6 +992,15 @@ public class AppIdleHistory { idpw.decreaseIndent(); } + private void printLastActionElapsedTime(IndentingPrintWriter idpw, long totalElapsedTimeMS, + long lastActionTimeMs) { + if (lastActionTimeMs < 0) { + idpw.print(""); + } else { + TimeUtils.formatDuration(totalElapsedTimeMS - lastActionTimeMs, idpw); + } + } + private void dumpBucketExpiryTimes(IndentingPrintWriter idpw, AppUsageHistory appUsageHistory, long totalElapsedTimeMs) { idpw.print(" expiryTimes="); diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java index 4952894c068b2..73c1c0e297201 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java @@ -887,8 +887,11 @@ public class AppStandbyController } } + final long elapsedLastUsedByUserTimeDelta = app.lastUsedByUserElapsedTime >= 0 + ? elapsedTimeAdjusted - app.lastUsedByUserElapsedTime + : Long.MAX_VALUE; if (app.lastRestrictAttemptElapsedTime > app.lastUsedByUserElapsedTime - && elapsedTimeAdjusted - app.lastUsedByUserElapsedTime + && elapsedLastUsedByUserTimeDelta >= mInjector.getAutoRestrictedBucketDelayMs()) { newBucket = STANDBY_BUCKET_RESTRICTED; reason = app.lastRestrictReason;