Merge "UsageStats: Fix issue where initializing data for first time would cause crash" into mnc-dr1.5-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
f2cc98bc96
@@ -547,7 +547,8 @@ public class UsageStatsService extends SystemService implements
|
|||||||
final int userCount = mUserState.size();
|
final int userCount = mUserState.size();
|
||||||
for (int i = 0; i < userCount; i++) {
|
for (int i = 0; i < userCount; i++) {
|
||||||
final UserUsageStatsService service = mUserState.valueAt(i);
|
final UserUsageStatsService service = mUserState.valueAt(i);
|
||||||
service.onTimeChanged(expectedSystemTime, actualSystemTime, resetBeginIdleTime);
|
service.onTimeChanged(expectedSystemTime, actualSystemTime, mScreenOnTime,
|
||||||
|
resetBeginIdleTime);
|
||||||
}
|
}
|
||||||
mRealTimeSnapshot = actualRealtime;
|
mRealTimeSnapshot = actualRealtime;
|
||||||
mSystemTimeSnapshot = actualSystemTime;
|
mSystemTimeSnapshot = actualSystemTime;
|
||||||
|
|||||||
@@ -135,12 +135,12 @@ class UserUsageStatsService {
|
|||||||
stat.updateConfigurationStats(null, stat.lastTimeSaved);
|
stat.updateConfigurationStats(null, stat.lastTimeSaved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
refreshAppIdleRollingWindow(currentTimeMillis, deviceUsageTime);
|
||||||
|
|
||||||
if (mDatabase.isNewUpdate()) {
|
if (mDatabase.isNewUpdate()) {
|
||||||
initializeDefaultsForApps(currentTimeMillis, deviceUsageTime,
|
initializeDefaultsForApps(currentTimeMillis, deviceUsageTime,
|
||||||
mDatabase.isFirstUpdate());
|
mDatabase.isFirstUpdate());
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshAppIdleRollingWindow(currentTimeMillis);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -162,19 +162,23 @@ class UserUsageStatsService {
|
|||||||
for (IntervalStats stats : mCurrentStats) {
|
for (IntervalStats stats : mCurrentStats) {
|
||||||
stats.update(packageName, currentTimeMillis, Event.SYSTEM_INTERACTION);
|
stats.update(packageName, currentTimeMillis, Event.SYSTEM_INTERACTION);
|
||||||
stats.updateBeginIdleTime(packageName, deviceUsageTime);
|
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.
|
// Persist the new OTA-related access stats.
|
||||||
persistActiveStats();
|
persistActiveStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onTimeChanged(long oldTime, long newTime, boolean resetBeginIdleTime) {
|
void onTimeChanged(long oldTime, long newTime, long deviceUsageTime,
|
||||||
|
boolean resetBeginIdleTime) {
|
||||||
persistActiveStats();
|
persistActiveStats();
|
||||||
mDatabase.onTimeChanged(newTime - oldTime);
|
mDatabase.onTimeChanged(newTime - oldTime);
|
||||||
loadActiveStats(newTime, /* force= */ true, resetBeginIdleTime);
|
loadActiveStats(newTime, /* force= */ true, resetBeginIdleTime);
|
||||||
refreshAppIdleRollingWindow(newTime);
|
refreshAppIdleRollingWindow(newTime, deviceUsageTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reportEvent(UsageEvents.Event event, long deviceUsageTime) {
|
void reportEvent(UsageEvents.Event event, long deviceUsageTime) {
|
||||||
@@ -186,7 +190,7 @@ class UserUsageStatsService {
|
|||||||
|
|
||||||
if (event.mTimeStamp >= mDailyExpiryDate.getTimeInMillis()) {
|
if (event.mTimeStamp >= mDailyExpiryDate.getTimeInMillis()) {
|
||||||
// Need to rollover
|
// Need to rollover
|
||||||
rolloverStats(event.mTimeStamp);
|
rolloverStats(event.mTimeStamp, deviceUsageTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
final IntervalStats currentDailyStats = mCurrentStats[UsageStatsManager.INTERVAL_DAILY];
|
final IntervalStats currentDailyStats = mCurrentStats[UsageStatsManager.INTERVAL_DAILY];
|
||||||
@@ -430,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();
|
final long startTime = SystemClock.elapsedRealtime();
|
||||||
Slog.i(TAG, mLogPrefix + "Rolling over usage stats");
|
Slog.i(TAG, mLogPrefix + "Rolling over usage stats");
|
||||||
|
|
||||||
@@ -471,7 +475,7 @@ class UserUsageStatsService {
|
|||||||
}
|
}
|
||||||
persistActiveStats();
|
persistActiveStats();
|
||||||
|
|
||||||
refreshAppIdleRollingWindow(currentTimeMillis);
|
refreshAppIdleRollingWindow(currentTimeMillis, deviceUsageTime);
|
||||||
|
|
||||||
final long totalTime = SystemClock.elapsedRealtime() - startTime;
|
final long totalTime = SystemClock.elapsedRealtime() - startTime;
|
||||||
Slog.i(TAG, mLogPrefix + "Rolling over usage stats complete. Took " + totalTime
|
Slog.i(TAG, mLogPrefix + "Rolling over usage stats complete. Took " + totalTime
|
||||||
@@ -542,43 +546,29 @@ class UserUsageStatsService {
|
|||||||
tempCal.getTimeInMillis() + ")");
|
tempCal.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);
|
dst.endTime = Math.max(dst.endTime, src.endTime);
|
||||||
|
|
||||||
final int srcPackageCount = src.packageStats.size();
|
final int srcPackageCount = src.packageStats.size();
|
||||||
for (int i = 0; i < srcPackageCount; i++) {
|
for (int i = 0; i < srcPackageCount; i++) {
|
||||||
final String packageName = src.packageStats.keyAt(i);
|
final String packageName = src.packageStats.keyAt(i);
|
||||||
final UsageStats srcStats = src.packageStats.valueAt(i);
|
final UsageStats srcStats = src.packageStats.valueAt(i);
|
||||||
final UsageStats dstStats = dst.packageStats.get(packageName);
|
UsageStats dstStats = dst.packageStats.get(packageName);
|
||||||
if (dstStats == null) {
|
if (dstStats == null) {
|
||||||
dst.packageStats.put(packageName, new UsageStats(srcStats));
|
dstStats = new UsageStats(srcStats);
|
||||||
|
dst.packageStats.put(packageName, dstStats);
|
||||||
} else {
|
} else {
|
||||||
dstStats.add(src.packageStats.valueAt(i));
|
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.
|
|
||||||
*/
|
|
||||||
private static final StatCombiner<IntervalStats> sPackageStatsMerger =
|
|
||||||
new StatCombiner<IntervalStats>() {
|
|
||||||
@Override
|
|
||||||
public void combine(IntervalStats stats, boolean mutable,
|
|
||||||
List<IntervalStats> accumulatedResult) {
|
|
||||||
IntervalStats accum;
|
|
||||||
if (accumulatedResult.isEmpty()) {
|
|
||||||
accum = new IntervalStats();
|
|
||||||
accum.beginTime = stats.beginTime;
|
|
||||||
accumulatedResult.add(accum);
|
|
||||||
} else {
|
|
||||||
accum = accumulatedResult.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
mergePackageStats(accum, stats);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App idle operates on a rolling window of time. When we roll over time, we end up with a
|
* 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
|
* period of time where in-memory stats are empty and we don't hit the disk for older stats
|
||||||
@@ -589,16 +579,31 @@ class UserUsageStatsService {
|
|||||||
*
|
*
|
||||||
* @param currentTimeMillis
|
* @param currentTimeMillis
|
||||||
*/
|
*/
|
||||||
void refreshAppIdleRollingWindow(long currentTimeMillis) {
|
void refreshAppIdleRollingWindow(final long currentTimeMillis, final long deviceUsageTime) {
|
||||||
// Start the rolling window for AppIdle requests.
|
// Start the rolling window for AppIdle requests.
|
||||||
List<IntervalStats> stats = mDatabase.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,
|
List<IntervalStats> stats = mDatabase.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,
|
||||||
currentTimeMillis - (1000 * 60 * 60 * 24 * 2), currentTimeMillis,
|
currentTimeMillis - (1000 * 60 * 60 * 24 * 2), currentTimeMillis,
|
||||||
sPackageStatsMerger);
|
new StatCombiner<IntervalStats>() {
|
||||||
|
@Override
|
||||||
|
public void combine(IntervalStats stats, boolean mutable,
|
||||||
|
List<IntervalStats> accumulatedResult) {
|
||||||
|
IntervalStats accum;
|
||||||
|
if (accumulatedResult.isEmpty()) {
|
||||||
|
accum = new IntervalStats();
|
||||||
|
accum.beginTime = stats.beginTime;
|
||||||
|
accumulatedResult.add(accum);
|
||||||
|
} else {
|
||||||
|
accum = accumulatedResult.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
mergePackageStats(accum, stats, deviceUsageTime);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (stats == null || stats.isEmpty()) {
|
if (stats == null || stats.isEmpty()) {
|
||||||
mAppIdleRollingWindow = new IntervalStats();
|
mAppIdleRollingWindow = new IntervalStats();
|
||||||
mergePackageStats(mAppIdleRollingWindow,
|
mergePackageStats(mAppIdleRollingWindow,
|
||||||
mCurrentStats[UsageStatsManager.INTERVAL_YEARLY]);
|
mCurrentStats[UsageStatsManager.INTERVAL_YEARLY], deviceUsageTime);
|
||||||
} else {
|
} else {
|
||||||
mAppIdleRollingWindow = stats.get(0);
|
mAppIdleRollingWindow = stats.get(0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user