Loading services/usage/java/com/android/server/usage/UsageStatsService.java +2 −1 Original line number Diff line number Diff line Loading @@ -548,7 +548,8 @@ public class UsageStatsService extends SystemService implements final int userCount = mUserState.size(); for (int i = 0; i < userCount; i++) { final UserUsageStatsService service = mUserState.valueAt(i); service.onTimeChanged(expectedSystemTime, actualSystemTime, resetBeginIdleTime); service.onTimeChanged(expectedSystemTime, actualSystemTime, mScreenOnTime, resetBeginIdleTime); } mRealTimeSnapshot = actualRealtime; mSystemTimeSnapshot = actualSystemTime; Loading services/usage/java/com/android/server/usage/UserUsageStatsService.java +40 −34 Original line number Diff line number Diff line Loading @@ -134,12 +134,12 @@ class UserUsageStatsService { stat.updateConfigurationStats(null, stat.lastTimeSaved); } refreshAppIdleRollingWindow(currentTimeMillis, deviceUsageTime); if (mDatabase.isNewUpdate()) { initializeDefaultsForApps(currentTimeMillis, deviceUsageTime, mDatabase.isFirstUpdate()); } refreshAppIdleRollingWindow(currentTimeMillis); } /** Loading @@ -161,19 +161,24 @@ class UserUsageStatsService { for (IntervalStats stats : mCurrentStats) { stats.update(packageName, currentTimeMillis, Event.SYSTEM_INTERACTION); stats.updateBeginIdleTime(packageName, deviceUsageTime); mStatsChanged = true; } mAppIdleRollingWindow.update(packageName, currentTimeMillis, Event.SYSTEM_INTERACTION); mAppIdleRollingWindow.updateBeginIdleTime(packageName, deviceUsageTime); mStatsChanged = true; } } // Persist the new OTA-related access stats. persistActiveStats(); } void onTimeChanged(long oldTime, long newTime, boolean resetBeginIdleTime) { void onTimeChanged(long oldTime, long newTime, long deviceUsageTime, boolean resetBeginIdleTime) { persistActiveStats(); mDatabase.onTimeChanged(newTime - oldTime); loadActiveStats(newTime, resetBeginIdleTime); refreshAppIdleRollingWindow(newTime); refreshAppIdleRollingWindow(newTime, deviceUsageTime); } void reportEvent(UsageEvents.Event event, long deviceUsageTime) { Loading @@ -185,7 +190,7 @@ class UserUsageStatsService { if (event.mTimeStamp >= mDailyExpiryDate.getTimeInMillis()) { // Need to rollover rolloverStats(event.mTimeStamp); rolloverStats(event.mTimeStamp, deviceUsageTime); } final IntervalStats currentDailyStats = mCurrentStats[UsageStatsManager.INTERVAL_DAILY]; Loading Loading @@ -429,7 +434,7 @@ class UserUsageStatsService { } } private void rolloverStats(final long currentTimeMillis) { private void rolloverStats(final long currentTimeMillis, final long deviceUsageTime) { final long startTime = SystemClock.elapsedRealtime(); Slog.i(TAG, mLogPrefix + "Rolling over usage stats"); Loading Loading @@ -470,7 +475,7 @@ class UserUsageStatsService { } persistActiveStats(); refreshAppIdleRollingWindow(currentTimeMillis); refreshAppIdleRollingWindow(currentTimeMillis, deviceUsageTime); final long totalTime = SystemClock.elapsedRealtime() - startTime; Slog.i(TAG, mLogPrefix + "Rolling over usage stats complete. Took " + totalTime Loading Loading @@ -528,26 +533,43 @@ class UserUsageStatsService { mDailyExpiryDate.getTimeInMillis() + ")"); } private static void mergePackageStats(IntervalStats dst, IntervalStats src) { private static void mergePackageStats(IntervalStats dst, IntervalStats src, final long deviceUsageTime) { dst.endTime = Math.max(dst.endTime, src.endTime); final int srcPackageCount = src.packageStats.size(); for (int i = 0; i < srcPackageCount; i++) { final String packageName = src.packageStats.keyAt(i); final UsageStats srcStats = src.packageStats.valueAt(i); final UsageStats dstStats = dst.packageStats.get(packageName); UsageStats dstStats = dst.packageStats.get(packageName); if (dstStats == null) { dst.packageStats.put(packageName, new UsageStats(srcStats)); dstStats = new UsageStats(srcStats); dst.packageStats.put(packageName, dstStats); } else { dstStats.add(src.packageStats.valueAt(i)); } // App idle times can not begin in the future. This happens if we had a time change. if (dstStats.mBeginIdleTime > deviceUsageTime) { dstStats.mBeginIdleTime = deviceUsageTime; } } } /** * Merges all the stats into the first element of the resulting list. * App idle operates on a rolling window of time. When we roll over time, we end up with a * period of time where in-memory stats are empty and we don't hit the disk for older stats * for performance reasons. Suddenly all apps will become idle. * * Instead, at times we do a deep query to find all the apps that have run in the past few * days and keep the cached data up to date. * * @param currentTimeMillis */ private static final StatCombiner<IntervalStats> sPackageStatsMerger = void refreshAppIdleRollingWindow(final long currentTimeMillis, final long deviceUsageTime) { // Start the rolling window for AppIdle requests. List<IntervalStats> stats = mDatabase.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, currentTimeMillis - (1000 * 60 * 60 * 24 * 2), currentTimeMillis, new StatCombiner<IntervalStats>() { @Override public void combine(IntervalStats stats, boolean mutable, Loading @@ -561,30 +583,14 @@ class UserUsageStatsService { accum = accumulatedResult.get(0); } mergePackageStats(accum, stats); mergePackageStats(accum, stats, deviceUsageTime); } }; /** * App idle operates on a rolling window of time. When we roll over time, we end up with a * period of time where in-memory stats are empty and we don't hit the disk for older stats * for performance reasons. Suddenly all apps will become idle. * * Instead, at times we do a deep query to find all the apps that have run in the past few * days and keep the cached data up to date. * * @param currentTimeMillis */ void refreshAppIdleRollingWindow(long currentTimeMillis) { // Start the rolling window for AppIdle requests. List<IntervalStats> stats = mDatabase.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, currentTimeMillis - (1000 * 60 * 60 * 24 * 2), currentTimeMillis, sPackageStatsMerger); }); if (stats == null || stats.isEmpty()) { mAppIdleRollingWindow = new IntervalStats(); mergePackageStats(mAppIdleRollingWindow, mCurrentStats[UsageStatsManager.INTERVAL_YEARLY]); mCurrentStats[UsageStatsManager.INTERVAL_YEARLY], deviceUsageTime); } else { mAppIdleRollingWindow = stats.get(0); } Loading Loading
services/usage/java/com/android/server/usage/UsageStatsService.java +2 −1 Original line number Diff line number Diff line Loading @@ -548,7 +548,8 @@ public class UsageStatsService extends SystemService implements final int userCount = mUserState.size(); for (int i = 0; i < userCount; i++) { final UserUsageStatsService service = mUserState.valueAt(i); service.onTimeChanged(expectedSystemTime, actualSystemTime, resetBeginIdleTime); service.onTimeChanged(expectedSystemTime, actualSystemTime, mScreenOnTime, resetBeginIdleTime); } mRealTimeSnapshot = actualRealtime; mSystemTimeSnapshot = actualSystemTime; Loading
services/usage/java/com/android/server/usage/UserUsageStatsService.java +40 −34 Original line number Diff line number Diff line Loading @@ -134,12 +134,12 @@ class UserUsageStatsService { stat.updateConfigurationStats(null, stat.lastTimeSaved); } refreshAppIdleRollingWindow(currentTimeMillis, deviceUsageTime); if (mDatabase.isNewUpdate()) { initializeDefaultsForApps(currentTimeMillis, deviceUsageTime, mDatabase.isFirstUpdate()); } refreshAppIdleRollingWindow(currentTimeMillis); } /** Loading @@ -161,19 +161,24 @@ class UserUsageStatsService { for (IntervalStats stats : mCurrentStats) { stats.update(packageName, currentTimeMillis, Event.SYSTEM_INTERACTION); stats.updateBeginIdleTime(packageName, deviceUsageTime); mStatsChanged = true; } mAppIdleRollingWindow.update(packageName, currentTimeMillis, Event.SYSTEM_INTERACTION); mAppIdleRollingWindow.updateBeginIdleTime(packageName, deviceUsageTime); mStatsChanged = true; } } // Persist the new OTA-related access stats. persistActiveStats(); } void onTimeChanged(long oldTime, long newTime, boolean resetBeginIdleTime) { void onTimeChanged(long oldTime, long newTime, long deviceUsageTime, boolean resetBeginIdleTime) { persistActiveStats(); mDatabase.onTimeChanged(newTime - oldTime); loadActiveStats(newTime, resetBeginIdleTime); refreshAppIdleRollingWindow(newTime); refreshAppIdleRollingWindow(newTime, deviceUsageTime); } void reportEvent(UsageEvents.Event event, long deviceUsageTime) { Loading @@ -185,7 +190,7 @@ class UserUsageStatsService { if (event.mTimeStamp >= mDailyExpiryDate.getTimeInMillis()) { // Need to rollover rolloverStats(event.mTimeStamp); rolloverStats(event.mTimeStamp, deviceUsageTime); } final IntervalStats currentDailyStats = mCurrentStats[UsageStatsManager.INTERVAL_DAILY]; Loading Loading @@ -429,7 +434,7 @@ class UserUsageStatsService { } } private void rolloverStats(final long currentTimeMillis) { private void rolloverStats(final long currentTimeMillis, final long deviceUsageTime) { final long startTime = SystemClock.elapsedRealtime(); Slog.i(TAG, mLogPrefix + "Rolling over usage stats"); Loading Loading @@ -470,7 +475,7 @@ class UserUsageStatsService { } persistActiveStats(); refreshAppIdleRollingWindow(currentTimeMillis); refreshAppIdleRollingWindow(currentTimeMillis, deviceUsageTime); final long totalTime = SystemClock.elapsedRealtime() - startTime; Slog.i(TAG, mLogPrefix + "Rolling over usage stats complete. Took " + totalTime Loading Loading @@ -528,26 +533,43 @@ class UserUsageStatsService { mDailyExpiryDate.getTimeInMillis() + ")"); } private static void mergePackageStats(IntervalStats dst, IntervalStats src) { private static void mergePackageStats(IntervalStats dst, IntervalStats src, final long deviceUsageTime) { dst.endTime = Math.max(dst.endTime, src.endTime); final int srcPackageCount = src.packageStats.size(); for (int i = 0; i < srcPackageCount; i++) { final String packageName = src.packageStats.keyAt(i); final UsageStats srcStats = src.packageStats.valueAt(i); final UsageStats dstStats = dst.packageStats.get(packageName); UsageStats dstStats = dst.packageStats.get(packageName); if (dstStats == null) { dst.packageStats.put(packageName, new UsageStats(srcStats)); dstStats = new UsageStats(srcStats); dst.packageStats.put(packageName, dstStats); } else { dstStats.add(src.packageStats.valueAt(i)); } // App idle times can not begin in the future. This happens if we had a time change. if (dstStats.mBeginIdleTime > deviceUsageTime) { dstStats.mBeginIdleTime = deviceUsageTime; } } } /** * Merges all the stats into the first element of the resulting list. * App idle operates on a rolling window of time. When we roll over time, we end up with a * period of time where in-memory stats are empty and we don't hit the disk for older stats * for performance reasons. Suddenly all apps will become idle. * * Instead, at times we do a deep query to find all the apps that have run in the past few * days and keep the cached data up to date. * * @param currentTimeMillis */ private static final StatCombiner<IntervalStats> sPackageStatsMerger = void refreshAppIdleRollingWindow(final long currentTimeMillis, final long deviceUsageTime) { // Start the rolling window for AppIdle requests. List<IntervalStats> stats = mDatabase.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, currentTimeMillis - (1000 * 60 * 60 * 24 * 2), currentTimeMillis, new StatCombiner<IntervalStats>() { @Override public void combine(IntervalStats stats, boolean mutable, Loading @@ -561,30 +583,14 @@ class UserUsageStatsService { accum = accumulatedResult.get(0); } mergePackageStats(accum, stats); mergePackageStats(accum, stats, deviceUsageTime); } }; /** * App idle operates on a rolling window of time. When we roll over time, we end up with a * period of time where in-memory stats are empty and we don't hit the disk for older stats * for performance reasons. Suddenly all apps will become idle. * * Instead, at times we do a deep query to find all the apps that have run in the past few * days and keep the cached data up to date. * * @param currentTimeMillis */ void refreshAppIdleRollingWindow(long currentTimeMillis) { // Start the rolling window for AppIdle requests. List<IntervalStats> stats = mDatabase.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, currentTimeMillis - (1000 * 60 * 60 * 24 * 2), currentTimeMillis, sPackageStatsMerger); }); if (stats == null || stats.isEmpty()) { mAppIdleRollingWindow = new IntervalStats(); mergePackageStats(mAppIdleRollingWindow, mCurrentStats[UsageStatsManager.INTERVAL_YEARLY]); mCurrentStats[UsageStatsManager.INTERVAL_YEARLY], deviceUsageTime); } else { mAppIdleRollingWindow = stats.get(0); } Loading