Merge "Don't change screen on time on time changes" into mnc-dr1.5-dev

This commit is contained in:
Adam Lesinski
2016-01-28 19:20:49 +00:00
committed by Android (Google) Code Review
3 changed files with 62 additions and 41 deletions

View File

@@ -165,14 +165,18 @@ public final class UsageStats implements Parcelable {
mPackageName + "' with UsageStats for package '" + right.mPackageName + "'.");
}
if (right.mEndTimeStamp > mEndTimeStamp) {
if (right.mBeginTimeStamp > mBeginTimeStamp) {
// The incoming UsageStat begins after this one, so use its last time used fields
// as the source of truth.
// We use the mBeginTimeStamp due to a bug where UsageStats files can overlap with
// regards to their mEndTimeStamp.
mLastEvent = right.mLastEvent;
mEndTimeStamp = right.mEndTimeStamp;
mLastTimeUsed = right.mLastTimeUsed;
mBeginIdleTime = right.mBeginIdleTime;
mLastTimeSystemUsed = right.mLastTimeSystemUsed;
}
mBeginTimeStamp = Math.min(mBeginTimeStamp, right.mBeginTimeStamp);
mEndTimeStamp = Math.max(mEndTimeStamp, right.mEndTimeStamp);
mTotalTimeInForeground += right.mTotalTimeInForeground;
mLaunchCount += right.mLaunchCount;
}

View File

@@ -123,6 +123,7 @@ public class UsageStatsService extends SystemService implements
static final int MSG_PAROLE_END_TIMEOUT = 7;
static final int MSG_REPORT_CONTENT_PROVIDER_USAGE = 8;
static final int MSG_PAROLE_STATE_CHANGED = 9;
static final int MSG_ONE_TIME_CHECK_IDLE_STATES = 10;
private final Object mLock = new Object();
Handler mHandler;
@@ -145,7 +146,7 @@ public class UsageStatsService extends SystemService implements
private long mLastAppIdleParoledTime;
long mScreenOnTime;
long mScreenOnSystemTimeSnapshot;
long mLastScreenOnEventRealtime;
@GuardedBy("mLock")
private AppIdleHistory mAppIdleHistory = new AppIdleHistory();
@@ -188,6 +189,8 @@ public class UsageStatsService extends SystemService implements
synchronized (mLock) {
cleanUpRemovedUsersLocked();
mLastScreenOnEventRealtime = SystemClock.elapsedRealtime();
mScreenOnTime = readScreenOnTimeLocked();
}
mRealTimeSnapshot = SystemClock.elapsedRealtime();
@@ -214,10 +217,6 @@ public class UsageStatsService extends SystemService implements
Context.DISPLAY_SERVICE);
mPowerManager = getContext().getSystemService(PowerManager.class);
mScreenOnSystemTimeSnapshot = System.currentTimeMillis();
synchronized (this) {
mScreenOnTime = readScreenOnTimeLocked();
}
mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);
synchronized (this) {
updateDisplayLocked();
@@ -280,6 +279,11 @@ public class UsageStatsService extends SystemService implements
mHandler.sendEmptyMessageDelayed(MSG_FLUSH_TO_DISK, FLUSH_INTERVAL);
}
@Override
public void onStatsReloaded() {
postOneTimeCheckIdleStates();
}
@Override
public long getAppIdleRollingWindowDurationMillis() {
return mAppIdleWallclockThresholdMillis * 2;
@@ -359,6 +363,14 @@ public class UsageStatsService extends SystemService implements
mHandler.sendMessage(mHandler.obtainMessage(MSG_CHECK_IDLE_STATES, userId, 0));
}
/**
* We send a different message to check idle states once, otherwise we would end up
* scheduling a series of repeating checkIdleStates each time we fired off one.
*/
void postOneTimeCheckIdleStates() {
mHandler.sendEmptyMessage(MSG_ONE_TIME_CHECK_IDLE_STATES);
}
/** Check all running users' or specified user's apps to see if they enter an idle state. */
void checkIdleStates(int checkUserId) {
if (!mAppIdleEnabled) {
@@ -385,7 +397,7 @@ public class UsageStatsService extends SystemService implements
userId);
synchronized (mLock) {
final long timeNow = checkAndGetTimeLocked();
final long screenOnTime = getScreenOnTimeLocked(timeNow);
final long screenOnTime = getScreenOnTimeLocked();
UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId,
timeNow);
final int packageCount = packages.size();
@@ -401,8 +413,6 @@ public class UsageStatsService extends SystemService implements
}
}
}
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CHECK_IDLE_STATES, checkUserId, 0),
mCheckIdleIntervalMillis);
}
/** Check if it's been a while since last parole and let idle apps do some work */
@@ -442,21 +452,21 @@ public class UsageStatsService extends SystemService implements
if (screenOn == mScreenOn) return;
mScreenOn = screenOn;
long now = System.currentTimeMillis();
long now = SystemClock.elapsedRealtime();
if (mScreenOn) {
mScreenOnSystemTimeSnapshot = now;
mLastScreenOnEventRealtime = now;
} else {
mScreenOnTime += now - mScreenOnSystemTimeSnapshot;
mScreenOnTime += now - mLastScreenOnEventRealtime;
writeScreenOnTimeLocked(mScreenOnTime);
}
}
private long getScreenOnTimeLocked(long now) {
long getScreenOnTimeLocked() {
long screenOnTime = mScreenOnTime;
if (mScreenOn) {
return now - mScreenOnSystemTimeSnapshot + mScreenOnTime;
} else {
return mScreenOnTime;
screenOnTime += SystemClock.elapsedRealtime() - mLastScreenOnEventRealtime;
}
return screenOnTime;
}
private File getScreenOnTimeFile() {
@@ -526,7 +536,7 @@ public class UsageStatsService extends SystemService implements
if (service == null) {
service = new UserUsageStatsService(getContext(), userId,
new File(mUsageStatsDir, Integer.toString(userId)), this);
service.init(currentTimeMillis, getScreenOnTimeLocked(currentTimeMillis));
service.init(currentTimeMillis, getScreenOnTimeLocked());
mUserState.put(userId, service);
}
return service;
@@ -539,25 +549,18 @@ public class UsageStatsService extends SystemService implements
final long actualSystemTime = System.currentTimeMillis();
final long actualRealtime = SystemClock.elapsedRealtime();
final long expectedSystemTime = (actualRealtime - mRealTimeSnapshot) + mSystemTimeSnapshot;
boolean resetBeginIdleTime = false;
if (Math.abs(actualSystemTime - expectedSystemTime) > TIME_CHANGE_THRESHOLD_MILLIS) {
final long diffSystemTime = actualSystemTime - expectedSystemTime;
if (Math.abs(diffSystemTime) > TIME_CHANGE_THRESHOLD_MILLIS) {
// The time has changed.
// Check if it's severe enough a change to reset screenOnTime
if (Math.abs(actualSystemTime - expectedSystemTime) > mAppIdleDurationMillis) {
mScreenOnSystemTimeSnapshot = actualSystemTime;
mScreenOnTime = 0;
resetBeginIdleTime = true;
}
Slog.i(TAG, "Time changed in UsageStats by " + (diffSystemTime / 1000) + " seconds");
final int userCount = mUserState.size();
for (int i = 0; i < userCount; i++) {
final UserUsageStatsService service = mUserState.valueAt(i);
service.onTimeChanged(expectedSystemTime, actualSystemTime, mScreenOnTime,
resetBeginIdleTime);
service.onTimeChanged(expectedSystemTime, actualSystemTime, getScreenOnTimeLocked(),
false);
}
mRealTimeSnapshot = actualRealtime;
mSystemTimeSnapshot = actualSystemTime;
postCheckIdleStates(UserHandle.USER_ALL);
}
return actualSystemTime;
}
@@ -586,7 +589,7 @@ public class UsageStatsService extends SystemService implements
void reportEvent(UsageEvents.Event event, int userId) {
synchronized (mLock) {
final long timeNow = checkAndGetTimeLocked();
final long screenOnTime = getScreenOnTimeLocked(timeNow);
final long screenOnTime = getScreenOnTimeLocked();
convertToSystemTimeLocked(event);
final UserUsageStatsService service =
@@ -602,7 +605,6 @@ public class UsageStatsService extends SystemService implements
|| event.mEventType == Event.SYSTEM_INTERACTION
|| event.mEventType == Event.USER_INTERACTION)) {
if (previouslyIdle) {
//Slog.d(TAG, "Informing listeners of out-of-idle " + event.mPackage);
mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, userId,
/* idle = */ 0, event.mPackage));
notifyBatteryStats(event.mPackage, userId, false);
@@ -643,7 +645,7 @@ public class UsageStatsService extends SystemService implements
void forceIdleState(String packageName, int userId, boolean idle) {
synchronized (mLock) {
final long timeNow = checkAndGetTimeLocked();
final long screenOnTime = getScreenOnTimeLocked(timeNow);
final long screenOnTime = getScreenOnTimeLocked();
final long deviceUsageTime = screenOnTime - (idle ? mAppIdleDurationMillis : 0) - 5000;
final UserUsageStatsService service =
@@ -657,7 +659,6 @@ public class UsageStatsService extends SystemService implements
timeNow - (idle ? mAppIdleWallclockThresholdMillis : 0) - 5000);
// Inform listeners if necessary
if (previouslyIdle != idle) {
// Slog.d(TAG, "Informing listeners of out-of-idle " + packageName);
mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, userId,
/* idle = */ idle ? 1 : 0, packageName));
if (!idle) {
@@ -796,7 +797,7 @@ public class UsageStatsService extends SystemService implements
timeNow = checkAndGetTimeLocked();
}
userService = getUserDataAndInitializeIfNeededLocked(userId, timeNow);
screenOnTime = getScreenOnTimeLocked(timeNow);
screenOnTime = getScreenOnTimeLocked();
}
return isAppIdleFiltered(packageName, UserHandle.getAppId(uidForAppId), userId,
userService, timeNow, screenOnTime);
@@ -865,7 +866,7 @@ public class UsageStatsService extends SystemService implements
synchronized (mLock) {
timeNow = checkAndGetTimeLocked();
userService = getUserDataAndInitializeIfNeededLocked(userId, timeNow);
screenOnTime = getScreenOnTimeLocked(timeNow);
screenOnTime = getScreenOnTimeLocked();
}
List<ApplicationInfo> apps;
@@ -987,7 +988,7 @@ public class UsageStatsService extends SystemService implements
*/
void dump(String[] args, PrintWriter pw) {
synchronized (mLock) {
final long screenOnTime = getScreenOnTimeLocked(checkAndGetTimeLocked());
final long screenOnTime = getScreenOnTimeLocked();
IndentingPrintWriter idpw = new IndentingPrintWriter(pw, " ");
ArraySet<String> argSet = new ArraySet<>();
argSet.addAll(Arrays.asList(args));
@@ -1008,7 +1009,11 @@ public class UsageStatsService extends SystemService implements
}
idpw.decreaseIndent();
}
pw.println("Screen On Timebase:" + mScreenOnTime);
pw.print("Screen On Timebase: ");
pw.print(screenOnTime);
pw.print(" (");
TimeUtils.formatDuration(screenOnTime, pw);
pw.println(")");
pw.println();
pw.println("Settings:");
@@ -1042,8 +1047,8 @@ public class UsageStatsService extends SystemService implements
pw.println();
pw.print("mScreenOnTime="); TimeUtils.formatDuration(mScreenOnTime, pw);
pw.println();
pw.print("mScreenOnSystemTimeSnapshot=");
TimeUtils.formatDuration(mScreenOnSystemTimeSnapshot, pw);
pw.print("mLastScreenOnEventRealtime=");
TimeUtils.formatDuration(mLastScreenOnEventRealtime, pw);
pw.println();
}
}
@@ -1078,6 +1083,14 @@ public class UsageStatsService extends SystemService implements
case MSG_CHECK_IDLE_STATES:
checkIdleStates(msg.arg1);
mHandler.sendMessageDelayed(mHandler.obtainMessage(
MSG_CHECK_IDLE_STATES, msg.arg1, 0),
mCheckIdleIntervalMillis);
break;
case MSG_ONE_TIME_CHECK_IDLE_STATES:
mHandler.removeMessages(MSG_ONE_TIME_CHECK_IDLE_STATES);
checkIdleStates(UserHandle.USER_ALL);
break;
case MSG_CHECK_PAROLE_TIMEOUT:
@@ -1138,7 +1151,7 @@ public class UsageStatsService extends SystemService implements
@Override
public void onChange(boolean selfChange) {
updateSettings();
postCheckIdleStates(UserHandle.USER_ALL);
postOneTimeCheckIdleStates();
}
void updateSettings() {

View File

@@ -68,6 +68,7 @@ class UserUsageStatsService {
interface StatsUpdatedListener {
void onStatsUpdated();
void onStatsReloaded();
long getAppIdleRollingWindowDurationMillis();
}
@@ -545,6 +546,9 @@ class UserUsageStatsService {
Slog.i(TAG, mLogPrefix + "Rollover scheduled @ " +
sDateFormat.format(mDailyExpiryDate.getTimeInMillis()) + "(" +
tempCal.getTimeInMillis() + ")");
// Tell the listener that the stats reloaded, which may have changed idle states.
mListener.onStatsReloaded();
}
private static void mergePackageStats(IntervalStats dst, IntervalStats src,