Add Configuration changes to UsageStats
Bug:17354208
Change-Id: I9b2f595e51b656607e30e798926cfb7e25134944
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 6951590..7142a99 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -16,13 +16,17 @@
package com.android.server.usage;
+import android.app.usage.ConfigurationStats;
import android.app.usage.TimeSparseArray;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
+import android.content.res.Configuration;
import android.util.ArraySet;
import android.util.Slog;
+import com.android.server.usage.UsageStatsDatabase.StatCombiner;
+
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
@@ -108,35 +112,91 @@
notifyStatsChanged();
}
}
+
+ stat.updateConfigurationStats(null, stat.lastTimeSaved);
}
}
void reportEvent(UsageEvents.Event event) {
if (DEBUG) {
Slog.d(TAG, mLogPrefix + "Got usage event for " + event.mPackage
- + "[" + event.getTimeStamp() + "]: "
- + eventToString(event.getEventType()));
+ + "[" + event.mTimeStamp + "]: "
+ + eventToString(event.mEventType));
}
- if (event.getTimeStamp() >= mDailyExpiryDate.getTimeInMillis()) {
+ if (event.mTimeStamp >= mDailyExpiryDate.getTimeInMillis()) {
// Need to rollover
rolloverStats();
}
- if (mCurrentStats[UsageStatsManager.INTERVAL_DAILY].events == null) {
- mCurrentStats[UsageStatsManager.INTERVAL_DAILY].events = new TimeSparseArray<>();
+ final IntervalStats currentDailyStats = mCurrentStats[UsageStatsManager.INTERVAL_DAILY];
+
+ final Configuration newFullConfig = event.mConfiguration;
+ if (event.mEventType == UsageEvents.Event.CONFIGURATION_CHANGE &&
+ currentDailyStats.activeConfiguration != null) {
+ // Make the event configuration a delta.
+ event.mConfiguration = Configuration.generateDelta(
+ currentDailyStats.activeConfiguration, newFullConfig);
}
- mCurrentStats[UsageStatsManager.INTERVAL_DAILY].events.put(event.getTimeStamp(), event);
+
+ // Add the event to the daily list.
+ if (currentDailyStats.events == null) {
+ currentDailyStats.events = new TimeSparseArray<>();
+ }
+ currentDailyStats.events.put(event.mTimeStamp, event);
for (IntervalStats stats : mCurrentStats) {
- stats.update(event.mPackage, event.getTimeStamp(),
- event.getEventType());
+ if (event.mEventType == UsageEvents.Event.CONFIGURATION_CHANGE) {
+ stats.updateConfigurationStats(newFullConfig, event.mTimeStamp);
+ } else {
+ stats.update(event.mPackage, event.mTimeStamp, event.mEventType);
+ }
}
notifyStatsChanged();
}
- List<UsageStats> queryUsageStats(int bucketType, long beginTime, long endTime) {
+ private static final StatCombiner<UsageStats> sUsageStatsCombiner =
+ new StatCombiner<UsageStats>() {
+ @Override
+ public void combine(IntervalStats stats, boolean mutable,
+ List<UsageStats> accResult) {
+ if (!mutable) {
+ accResult.addAll(stats.stats.values());
+ return;
+ }
+
+ final int statCount = stats.stats.size();
+ for (int i = 0; i < statCount; i++) {
+ accResult.add(new UsageStats(stats.stats.valueAt(i)));
+ }
+ }
+ };
+
+ private static final StatCombiner<ConfigurationStats> sConfigStatsCombiner =
+ new StatCombiner<ConfigurationStats>() {
+ @Override
+ public void combine(IntervalStats stats, boolean mutable,
+ List<ConfigurationStats> accResult) {
+ if (!mutable) {
+ accResult.addAll(stats.configurations.values());
+ return;
+ }
+
+ final int configCount = stats.configurations.size();
+ for (int i = 0; i < configCount; i++) {
+ accResult.add(new ConfigurationStats(stats.configurations.valueAt(i)));
+ }
+ }
+ };
+
+ /**
+ * Generic query method that selects the appropriate IntervalStats for the specified time range
+ * and bucket, then calls the {@link com.android.server.usage.UsageStatsDatabase.StatCombiner}
+ * provided to select the stats to use from the IntervalStats object.
+ */
+ private <T> List<T> queryStats(int bucketType, long beginTime, long endTime,
+ StatCombiner<T> combiner) {
if (bucketType == UsageStatsManager.INTERVAL_BEST) {
bucketType = mDatabase.findBestFitBucket(beginTime, endTime);
}
@@ -161,11 +221,8 @@
Slog.d(TAG, mLogPrefix + "Returning in-memory stats for bucket " + bucketType);
}
// Fast path for retrieving in-memory state.
- ArrayList<UsageStats> results = new ArrayList<>();
- final int packageCount = mCurrentStats[bucketType].stats.size();
- for (int i = 0; i < packageCount; i++) {
- results.add(new UsageStats(mCurrentStats[bucketType].stats.valueAt(i)));
- }
+ ArrayList<T> results = new ArrayList<>();
+ combiner.combine(mCurrentStats[bucketType], true, results);
return results;
}
@@ -178,13 +235,21 @@
+ beginTime + " AND endTime < " + endTime);
}
- final List<UsageStats> results = mDatabase.queryUsageStats(bucketType, beginTime, endTime);
+ final List<T> results = mDatabase.queryUsageStats(bucketType, beginTime, endTime, combiner);
if (DEBUG) {
Slog.d(TAG, mLogPrefix + "Results: " + (results == null ? 0 : results.size()));
}
return results;
}
+ List<UsageStats> queryUsageStats(int bucketType, long beginTime, long endTime) {
+ return queryStats(bucketType, beginTime, endTime, sUsageStatsCombiner);
+ }
+
+ List<ConfigurationStats> queryConfigurationStats(int bucketType, long beginTime, long endTime) {
+ return queryStats(bucketType, beginTime, endTime, sConfigStatsCombiner);
+ }
+
UsageEvents queryEvents(long beginTime, long endTime) {
if (endTime > mCurrentStats[UsageStatsManager.INTERVAL_DAILY].beginTime) {
if (beginTime > mCurrentStats[UsageStatsManager.INTERVAL_DAILY].endTime) {
@@ -245,6 +310,8 @@
// Finish any ongoing events with an END_OF_DAY event. Make a note of which components
// need a new CONTINUE_PREVIOUS_DAY entry.
+ final Configuration previousConfig =
+ mCurrentStats[UsageStatsManager.INTERVAL_DAILY].activeConfiguration;
ArraySet<String> continuePreviousDay = new ArraySet<>();
for (IntervalStats stat : mCurrentStats) {
final int pkgCount = stat.stats.size();
@@ -253,11 +320,13 @@
if (pkgStats.mLastEvent == UsageEvents.Event.MOVE_TO_FOREGROUND ||
pkgStats.mLastEvent == UsageEvents.Event.CONTINUE_PREVIOUS_DAY) {
continuePreviousDay.add(pkgStats.mPackageName);
- stat.update(pkgStats.mPackageName,
- mDailyExpiryDate.getTimeInMillis() - 1, UsageEvents.Event.END_OF_DAY);
+ stat.update(pkgStats.mPackageName, mDailyExpiryDate.getTimeInMillis() - 1,
+ UsageEvents.Event.END_OF_DAY);
mStatsChanged = true;
}
}
+
+ stat.updateConfigurationStats(null, mDailyExpiryDate.getTimeInMillis() - 1);
}
persistActiveStats();
@@ -267,9 +336,10 @@
final int continueCount = continuePreviousDay.size();
for (int i = 0; i < continueCount; i++) {
String name = continuePreviousDay.valueAt(i);
+ final long beginTime = mCurrentStats[UsageStatsManager.INTERVAL_DAILY].beginTime;
for (IntervalStats stat : mCurrentStats) {
- stat.update(name, mCurrentStats[UsageStatsManager.INTERVAL_DAILY].beginTime,
- UsageEvents.Event.CONTINUE_PREVIOUS_DAY);
+ stat.update(name, beginTime, UsageEvents.Event.CONTINUE_PREVIOUS_DAY);
+ stat.updateConfigurationStats(previousConfig, beginTime);
mStatsChanged = true;
}
}
@@ -353,6 +423,8 @@
return "END_OF_DAY";
case UsageEvents.Event.CONTINUE_PREVIOUS_DAY:
return "CONTINUE_PREVIOUS_DAY";
+ case UsageEvents.Event.CONFIGURATION_CHANGE:
+ return "CONFIGURATION_CHANGE";
default:
return "UNKNOWN";
}