Merge "Update standby buckets for restored apps." into tm-qpr-dev

This commit is contained in:
TreeHugger Robot
2022-06-27 23:22:37 +00:00
committed by Android (Google) Code Review
8 changed files with 99 additions and 8 deletions

View File

@@ -163,6 +163,13 @@ public interface AppStandbyInternal {
int getAppStandbyBucketReason(@NonNull String packageName, @UserIdInt int userId,
@ElapsedRealtimeLong long elapsedRealtime);
/**
* Puts the list of apps in the {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RARE}
* bucket.
* @param restoredApps the list of restored apps
*/
void restoreAppsToRare(@NonNull Set<String> restoredApps, int userId);
/**
* Put the specified app in the
* {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED}

View File

@@ -23,6 +23,7 @@ import static android.app.usage.UsageStatsManager.REASON_MAIN_MASK;
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_DEFAULT_APP_RESTORED;
import static android.app.usage.UsageStatsManager.REASON_SUB_DEFAULT_APP_UPDATE;
import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY;
import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_USER_FLAG_INTERACTION;
@@ -1604,6 +1605,26 @@ public class AppStandbyController
setAppStandbyBucket(packageName, userId, bucket, reason, nowElapsed, false);
}
@Override
public void restoreAppsToRare(Set<String> restoredApps, int userId) {
final int reason = REASON_MAIN_DEFAULT | REASON_SUB_DEFAULT_APP_RESTORED;
final long nowElapsed = mInjector.elapsedRealtime();
for (String packageName : restoredApps) {
// 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 restore bucket for uninstalled app: " + packageName);
continue;
}
final int standbyBucket = getAppStandbyBucket(packageName, userId, nowElapsed, false);
// Only update the standby bucket to RARE if the app is still in the NEVER bucket.
if (standbyBucket == STANDBY_BUCKET_NEVER) {
setAppStandbyBucket(packageName, userId, STANDBY_BUCKET_RARE, reason,
nowElapsed, false);
}
}
}
@Override
public void setAppStandbyBucket(@NonNull String packageName, int bucket, int userId,
int callingUid, int callingPid) {

View File

@@ -292,6 +292,17 @@ public final class UsageStats implements Parcelable {
return mLastTimeComponentUsed;
}
/**
* Returns the last time the package was used - defined by the latest of
* mLastTimeUsed, mLastTimeVisible, mLastTimeForegroundServiceUsed, or mLastTimeComponentUsed.
* @hide
*/
public long getLastTimePackageUsed() {
return Math.max(mLastTimeUsed,
Math.max(mLastTimeVisible,
Math.max(mLastTimeForegroundServiceUsed, mLastTimeComponentUsed)));
}
/**
* Returns the number of times the app was launched as an activity from outside of the app.
* Excludes intra-app activity transitions.

View File

@@ -219,6 +219,11 @@ public final class UsageStatsManager {
* @hide
*/
public static final int REASON_SUB_DEFAULT_APP_UPDATE = 0x0001;
/**
* The app was restored.
* @hide
*/
public static final int REASON_SUB_DEFAULT_APP_RESTORED = 0x0002;
/**
* The app was interacted with in some way by the system.
* @hide
@@ -1209,6 +1214,9 @@ public final class UsageStatsManager {
case REASON_SUB_DEFAULT_APP_UPDATE:
sb.append("-au");
break;
case REASON_SUB_DEFAULT_APP_RESTORED:
sb.append("-ar");
break;
}
break;
case REASON_MAIN_FORCED_BY_SYSTEM:

View File

@@ -22,6 +22,7 @@ import static junit.framework.TestCase.fail;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import android.app.usage.TimeSparseArray;
import android.app.usage.UsageEvents.Event;
@@ -440,6 +441,7 @@ public class UsageStatsDatabaseTest {
prevDB.readMappingsLocked();
prevDB.init(1);
prevDB.putUsageStats(UsageStatsManager.INTERVAL_DAILY, mIntervalStats);
Set<String> prevDBApps = mIntervalStats.packageStats.keySet();
// Create a backup with a specific version
byte[] blob = prevDB.getBackupPayload(KEY_USAGE_STATS, version);
if (version >= 1 && version <= 3) {
@@ -447,6 +449,11 @@ public class UsageStatsDatabaseTest {
"UsageStatsDatabase shouldn't be able to write backups as XML");
return;
}
if (version < 1 || version > UsageStatsDatabase.BACKUP_VERSION) {
assertFalse(blob != null && blob.length != 0,
"UsageStatsDatabase shouldn't be able to write backups for unknown versions");
return;
}
clearUsageStatsFiles();
@@ -454,9 +461,11 @@ public class UsageStatsDatabaseTest {
newDB.readMappingsLocked();
newDB.init(1);
// Attempt to restore the usage stats from the backup
newDB.applyRestoredPayload(KEY_USAGE_STATS, blob);
List<IntervalStats> stats = newDB.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, 0, mEndTime,
mIntervalStatsVerifier);
Set<String> restoredApps = newDB.applyRestoredPayload(KEY_USAGE_STATS, blob);
assertTrue(restoredApps.containsAll(prevDBApps),
"List of restored apps does not match list backed-up apps list.");
List<IntervalStats> stats = newDB.queryUsageStats(
UsageStatsManager.INTERVAL_DAILY, 0, mEndTime, mIntervalStatsVerifier);
if (version > UsageStatsDatabase.BACKUP_VERSION || version < 1) {
assertFalse(stats != null && !stats.isEmpty(),

View File

@@ -16,6 +16,7 @@
package com.android.server.usage;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.usage.TimeSparseArray;
import android.app.usage.UsageEvents;
@@ -24,6 +25,7 @@ import android.app.usage.UsageStatsManager;
import android.os.Build;
import android.os.SystemProperties;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.Slog;
import android.util.SparseArray;
@@ -55,8 +57,11 @@ import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* Provides an interface to query for UsageStat data from a Protocol Buffer database.
@@ -1252,6 +1257,10 @@ public class UsageStatsDatabase {
Slog.wtf(TAG, "Attempting to backup UsageStats as XML with version " + version);
return null;
}
if (version < 1 || version > BACKUP_VERSION) {
Slog.wtf(TAG, "Attempting to backup UsageStats with an unknown version: " + version);
return null;
}
synchronized (mLock) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (KEY_USAGE_STATS.equals(key)) {
@@ -1300,14 +1309,26 @@ public class UsageStatsDatabase {
}
return baos.toByteArray();
}
}
/**
* Updates the set of packages given to only include those that have been used within the
* given timeframe (as defined by {@link UsageStats#getLastTimePackageUsed()}).
*/
private void calculatePackagesUsedWithinTimeframe(
IntervalStats stats, Set<String> packagesList, long timeframeMs) {
for (UsageStats stat : stats.packageStats.values()) {
if (stat.getLastTimePackageUsed() > timeframeMs) {
packagesList.add(stat.mPackageName);
}
}
}
/**
* @hide
*/
@VisibleForTesting
public void applyRestoredPayload(String key, byte[] payload) {
public @NonNull Set<String> applyRestoredPayload(String key, byte[] payload) {
synchronized (mLock) {
if (KEY_USAGE_STATS.equals(key)) {
// Read stats files for the current device configs
@@ -1320,12 +1341,15 @@ public class UsageStatsDatabase {
IntervalStats yearlyConfigSource =
getLatestUsageStats(UsageStatsManager.INTERVAL_YEARLY);
final Set<String> packagesRestored = new ArraySet<>();
try {
DataInputStream in = new DataInputStream(new ByteArrayInputStream(payload));
int backupDataVersion = in.readInt();
// Can't handle this backup set
if (backupDataVersion < 1 || backupDataVersion > BACKUP_VERSION) return;
if (backupDataVersion < 1 || backupDataVersion > BACKUP_VERSION) {
return packagesRestored;
}
// Delete all stats files
// Do this after reading version and before actually restoring
@@ -1333,10 +1357,14 @@ public class UsageStatsDatabase {
deleteDirectoryContents(mIntervalDirs[i]);
}
// 90 days before today in epoch
final long timeframe = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(90);
int fileCount = in.readInt();
for (int i = 0; i < fileCount; i++) {
IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in),
backupDataVersion);
calculatePackagesUsedWithinTimeframe(stats, packagesRestored, timeframe);
packagesRestored.addAll(stats.packageStats.keySet());
stats = mergeStats(stats, dailyConfigSource);
putUsageStats(UsageStatsManager.INTERVAL_DAILY, stats);
}
@@ -1345,6 +1373,7 @@ public class UsageStatsDatabase {
for (int i = 0; i < fileCount; i++) {
IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in),
backupDataVersion);
calculatePackagesUsedWithinTimeframe(stats, packagesRestored, timeframe);
stats = mergeStats(stats, weeklyConfigSource);
putUsageStats(UsageStatsManager.INTERVAL_WEEKLY, stats);
}
@@ -1353,6 +1382,7 @@ public class UsageStatsDatabase {
for (int i = 0; i < fileCount; i++) {
IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in),
backupDataVersion);
calculatePackagesUsedWithinTimeframe(stats, packagesRestored, timeframe);
stats = mergeStats(stats, monthlyConfigSource);
putUsageStats(UsageStatsManager.INTERVAL_MONTHLY, stats);
}
@@ -1361,6 +1391,7 @@ public class UsageStatsDatabase {
for (int i = 0; i < fileCount; i++) {
IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in),
backupDataVersion);
calculatePackagesUsedWithinTimeframe(stats, packagesRestored, timeframe);
stats = mergeStats(stats, yearlyConfigSource);
putUsageStats(UsageStatsManager.INTERVAL_YEARLY, stats);
}
@@ -1370,7 +1401,9 @@ public class UsageStatsDatabase {
} finally {
indexFilesLocked();
}
return packagesRestored;
}
return Collections.EMPTY_SET;
}
}

View File

@@ -3034,7 +3034,8 @@ public class UsageStatsService extends SystemService implements
if (userStats == null) {
return; // user was stopped or removed
}
userStats.applyRestoredPayload(key, payload);
final Set<String> restoredApps = userStats.applyRestoredPayload(key, payload);
mAppStandby.restoreAppsToRare(restoredApps, user);
}
}
}

View File

@@ -63,6 +63,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
/**
* A per-user UsageStatsService. All methods are meant to be called with the main lock held
@@ -1374,8 +1375,8 @@ class UserUsageStatsService {
return mDatabase.getBackupPayload(key);
}
void applyRestoredPayload(String key, byte[] payload){
Set<String> applyRestoredPayload(String key, byte[] payload) {
checkAndGetTimeLocked();
mDatabase.applyRestoredPayload(key, payload);
return mDatabase.applyRestoredPayload(key, payload);
}
}