From 55717a613c23fc6b05cab86c3b0de283a027e9f6 Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Fri, 3 Apr 2015 17:22:36 -0700 Subject: Mark apps as not-idle at least once On a fresh boot or update to M, mark existing apps as being used if there is no existing entry in the usage stats. On subsequent OTAs, make sure that at least the new system apps are marked as used. Reduce idle threshold to 1 day. Bug: 20066058 Change-Id: I9a273c051d04432877bacd381c85bf6e721c1a85 --- .../android/server/usage/UsageStatsDatabase.java | 46 ++++++++++++++++++++-- .../android/server/usage/UsageStatsService.java | 2 +- .../server/usage/UserUsageStatsService.java | 34 ++++++++++++++++ 3 files changed, 78 insertions(+), 4 deletions(-) (limited to 'services/usage') diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java index 235567c..4498b84 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java +++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java @@ -18,6 +18,7 @@ package com.android.server.usage; import android.app.usage.TimeSparseArray; import android.app.usage.UsageStatsManager; +import android.os.Build; import android.util.AtomicFile; import android.util.Slog; @@ -35,7 +36,7 @@ import java.util.List; * Provides an interface to query for UsageStat data from an XML database. */ class UsageStatsDatabase { - private static final int CURRENT_VERSION = 2; + private static final int CURRENT_VERSION = 3; private static final String TAG = "UsageStatsDatabase"; private static final boolean DEBUG = UsageStatsService.DEBUG; @@ -47,6 +48,8 @@ class UsageStatsDatabase { private final TimeSparseArray[] mSortedStatFiles; private final UnixCalendar mCal; private final File mVersionFile; + private boolean mFirstUpdate; + private boolean mNewUpdate; public UsageStatsDatabase(File dir) { mIntervalDirs = new File[] { @@ -73,7 +76,7 @@ class UsageStatsDatabase { } } - checkVersionLocked(); + checkVersionAndBuildLocked(); indexFilesLocked(); // Delete files that are in the future. @@ -194,10 +197,35 @@ class UsageStatsDatabase { } } - private void checkVersionLocked() { + /** + * Is this the first update to the system from L to M? + */ + boolean isFirstUpdate() { + return mFirstUpdate; + } + + /** + * Is this a system update since we started tracking build fingerprint in the version file? + */ + boolean isNewUpdate() { + return mNewUpdate; + } + + private void checkVersionAndBuildLocked() { int version; + String buildFingerprint; + String currentFingerprint = getBuildFingerprint(); + mFirstUpdate = true; + mNewUpdate = true; try (BufferedReader reader = new BufferedReader(new FileReader(mVersionFile))) { version = Integer.parseInt(reader.readLine()); + buildFingerprint = reader.readLine(); + if (buildFingerprint != null) { + mFirstUpdate = false; + } + if (currentFingerprint.equals(buildFingerprint)) { + mNewUpdate = false; + } } catch (NumberFormatException | IOException e) { version = 0; } @@ -205,9 +233,15 @@ class UsageStatsDatabase { if (version != CURRENT_VERSION) { Slog.i(TAG, "Upgrading from version " + version + " to " + CURRENT_VERSION); doUpgradeLocked(version); + } + if (version != CURRENT_VERSION || mNewUpdate) { try (BufferedWriter writer = new BufferedWriter(new FileWriter(mVersionFile))) { writer.write(Integer.toString(CURRENT_VERSION)); + writer.write("\n"); + writer.write(currentFingerprint); + writer.write("\n"); + writer.flush(); } catch (IOException e) { Slog.e(TAG, "Failed to write new version"); throw new RuntimeException(e); @@ -215,6 +249,12 @@ class UsageStatsDatabase { } } + private String getBuildFingerprint() { + return Build.VERSION.RELEASE + ";" + + Build.VERSION.CODENAME + ";" + + Build.VERSION.INCREMENTAL; + } + private void doUpgradeLocked(int thisVersion) { if (thisVersion < 2) { // Delete all files if we are version 0. This is a pre-release version, diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index f458dbc..cc0ab81 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -92,7 +92,7 @@ public class UsageStatsService extends SystemService implements long mRealTimeSnapshot; long mSystemTimeSnapshot; - private static final long DEFAULT_APP_IDLE_THRESHOLD_MILLIS = 3L * 24 * 60 * 60 * 1000; //3 days + private static final long DEFAULT_APP_IDLE_THRESHOLD_MILLIS = 1L * 24 * 60 * 60 * 1000; // 1 day private long mAppIdleDurationMillis; private ArrayList diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java index afe27c7..0a9481a 100644 --- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java @@ -19,8 +19,11 @@ package com.android.server.usage; import android.app.usage.ConfigurationStats; import android.app.usage.TimeSparseArray; import android.app.usage.UsageEvents; +import android.app.usage.UsageEvents.Event; import android.app.usage.UsageStats; import android.app.usage.UsageStatsManager; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; import android.content.res.Configuration; import android.os.SystemClock; import android.content.Context; @@ -60,6 +63,7 @@ class UserUsageStatsService { private final UnixCalendar mDailyExpiryDate; private final StatsUpdatedListener mListener; private final String mLogPrefix; + private final int mUserId; interface StatsUpdatedListener { void onStatsUpdated(); @@ -73,6 +77,7 @@ class UserUsageStatsService { mCurrentStats = new IntervalStats[UsageStatsManager.INTERVAL_COUNT]; mListener = listener; mLogPrefix = "User[" + Integer.toString(userId) + "] "; + mUserId = userId; } void init(final long currentTimeMillis) { @@ -128,6 +133,35 @@ class UserUsageStatsService { stat.updateConfigurationStats(null, stat.lastTimeSaved); } + + if (mDatabase.isNewUpdate()) { + initializeDefaultsForApps(currentTimeMillis, mDatabase.isFirstUpdate()); + } + } + + /** + * If any of the apps don't have a last-used entry, add one now. + * @param currentTimeMillis the current time + * @param firstUpdate if it is the first update, touch all installed apps, otherwise only + * touch the system apps + */ + private void initializeDefaultsForApps(long currentTimeMillis, boolean firstUpdate) { + PackageManager pm = mContext.getPackageManager(); + List packages = pm.getInstalledPackages(0, mUserId); + final int packageCount = packages.size(); + for (int i = 0; i < packageCount; i++) { + final PackageInfo pi = packages.get(i); + String packageName = pi.packageName; + if (pi.applicationInfo != null && (firstUpdate || pi.applicationInfo.isSystemApp()) + && getLastPackageAccessTime(packageName) == -1) { + for (IntervalStats stats : mCurrentStats) { + stats.update(packageName, currentTimeMillis, Event.INTERACTION); + mStatsChanged = true; + } + } + } + // Persist the new OTA-related access stats. + persistActiveStats(); } void onTimeChanged(long oldTime, long newTime) { -- cgit v1.1