summaryrefslogtreecommitdiffstats
path: root/services/usage
diff options
context:
space:
mode:
authorAmith Yamasani <yamasani@google.com>2015-05-08 16:36:21 -0700
committerAmith Yamasani <yamasani@google.com>2015-05-11 17:46:14 -0700
commit06bf824628c118fbd5ad6756913d7fd63a6f4ce5 (patch)
tree91e73265354432cf4d82543366ce11dddf19247b /services/usage
parenta5b2684c25add3ba6ebc43c27a1abc6bce2b2af4 (diff)
downloadframeworks_base-06bf824628c118fbd5ad6756913d7fd63a6f4ce5.zip
frameworks_base-06bf824628c118fbd5ad6756913d7fd63a6f4ce5.tar.gz
frameworks_base-06bf824628c118fbd5ad6756913d7fd63a6f4ce5.tar.bz2
Idle timebase
Use screen on time as timebase for idling out apps that have been inactive. Store the time when an app was last active as an additional package state in UsageStats. Compare it to screenOnTime to decide if it's inactive. Exclude device idle whitelist from apps that can go inactive. Bug: 20066058 Change-Id: I709f9f31a9affa7ca6e1ae3e4c5729c5fb221669
Diffstat (limited to 'services/usage')
-rw-r--r--services/usage/java/com/android/server/usage/IntervalStats.java12
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java200
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsXmlV1.java8
-rw-r--r--services/usage/java/com/android/server/usage/UserUsageStatsService.java35
4 files changed, 192 insertions, 63 deletions
diff --git a/services/usage/java/com/android/server/usage/IntervalStats.java b/services/usage/java/com/android/server/usage/IntervalStats.java
index 869d6e1..d6ff475 100644
--- a/services/usage/java/com/android/server/usage/IntervalStats.java
+++ b/services/usage/java/com/android/server/usage/IntervalStats.java
@@ -48,6 +48,7 @@ class IntervalStats {
usageStats.mPackageName = getCachedStringRef(packageName);
usageStats.mBeginTimeStamp = beginTime;
usageStats.mEndTimeStamp = endTime;
+ usageStats.mBeginIdleTime = endTime;
packageStats.put(usageStats.mPackageName, usageStats);
}
return usageStats;
@@ -119,6 +120,17 @@ class IntervalStats {
endTime = timeStamp;
}
+ /**
+ * Updates the last active time for the package. The timestamp uses a timebase that
+ * tracks the device usage time.
+ * @param packageName
+ * @param timeStamp
+ */
+ void updateBeginIdleTime(String packageName, long timeStamp) {
+ UsageStats usageStats = getOrCreateUsageStats(packageName);
+ usageStats.mBeginIdleTime = timeStamp;
+ }
+
void updateConfigurationStats(Configuration config, long timeStamp) {
if (activeConfiguration != null) {
ConfigurationStats activeStats = configurations.get(activeConfiguration);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 48b127a..197daed 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -40,31 +40,39 @@ import android.content.pm.ParceledListSlice;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.database.ContentObserver;
+import android.hardware.display.DisplayManager;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.Binder;
import android.os.Environment;
import android.os.Handler;
+import android.os.IDeviceIdleController;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.util.ArraySet;
+import android.util.AtomicFile;
import android.util.Slog;
import android.util.SparseArray;
+import android.view.Display;
-import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.SystemConfig;
+import com.android.server.DeviceIdleController;
import com.android.server.SystemService;
+import java.io.BufferedReader;
import java.io.File;
import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -76,6 +84,7 @@ import java.util.List;
*/
public class UsageStatsService extends SystemService implements
UserUsageStatsService.StatsUpdatedListener {
+
static final String TAG = "UsageStatsService";
static final boolean DEBUG = false;
@@ -91,7 +100,7 @@ public class UsageStatsService extends SystemService implements
static final int MSG_FLUSH_TO_DISK = 1;
static final int MSG_REMOVE_USER = 2;
static final int MSG_INFORM_LISTENERS = 3;
- static final int MSG_RESET_LAST_TIMESTAMP = 4;
+ static final int MSG_FORCE_IDLE_STATE = 4;
static final int MSG_CHECK_IDLE_STATES = 5;
private final Object mLock = new Object();
@@ -99,16 +108,20 @@ public class UsageStatsService extends SystemService implements
AppOpsManager mAppOps;
UserManager mUserManager;
AppWidgetManager mAppWidgetManager;
+ IDeviceIdleController mDeviceIdleController;
+ private DisplayManager mDisplayManager;
private final SparseArray<UserUsageStatsService> mUserState = new SparseArray<>();
private File mUsageStatsDir;
long mRealTimeSnapshot;
long mSystemTimeSnapshot;
boolean mAppIdleParoled;
+ private boolean mScreenOn;
long mAppIdleDurationMillis;
-
long mCheckIdleIntervalMillis = DEFAULT_CHECK_IDLE_INTERVAL;
+ long mScreenOnTime;
+ long mScreenOnSystemTimeSnapshot;
private ArrayList<UsageStatsManagerInternal.AppIdleStateChangeListener>
mPackageAccessListeners = new ArrayList<>();
@@ -162,6 +175,18 @@ public class UsageStatsService extends SystemService implements
// Observe changes to the threshold
new SettingsObserver(mHandler).registerObserver();
mAppWidgetManager = getContext().getSystemService(AppWidgetManager.class);
+ mDeviceIdleController = IDeviceIdleController.Stub.asInterface(
+ ServiceManager.getService(DeviceIdleController.SERVICE_NAME));
+ mDisplayManager = (DisplayManager) getContext().getSystemService(
+ Context.DISPLAY_SERVICE);
+ mScreenOnSystemTimeSnapshot = System.currentTimeMillis();
+ synchronized (this) {
+ mScreenOnTime = readScreenOnTimeLocked();
+ }
+ mDisplayManager.registerDisplayListener(mDisplayListener, null);
+ synchronized (this) {
+ updateDisplayLocked();
+ }
} else if (phase == PHASE_BOOT_COMPLETED) {
setAppIdleParoled(getContext().getSystemService(BatteryManager.class).isCharging());
}
@@ -195,6 +220,24 @@ public class UsageStatsService extends SystemService implements
}
}
+ private final DisplayManager.DisplayListener mDisplayListener
+ = new DisplayManager.DisplayListener() {
+
+ @Override public void onDisplayAdded(int displayId) {
+ }
+
+ @Override public void onDisplayRemoved(int displayId) {
+ }
+
+ @Override public void onDisplayChanged(int displayId) {
+ if (displayId == Display.DEFAULT_DISPLAY) {
+ synchronized (UsageStatsService.this.mLock) {
+ updateDisplayLocked();
+ }
+ }
+ }
+ };
+
@Override
public void onStatsUpdated() {
mHandler.sendEmptyMessageDelayed(MSG_FLUSH_TO_DISK, FLUSH_INTERVAL);
@@ -261,7 +304,7 @@ public class UsageStatsService extends SystemService implements
final int packageCount = packages.size();
for (int p = 0; p < packageCount; p++) {
final String packageName = packages.get(p).packageName;
- final boolean isIdle = isAppIdle(packageName, userId);
+ final boolean isIdle = isAppIdleFiltered(packageName, userId);
mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS,
userId, isIdle ? 1 : 0, packageName));
}
@@ -270,6 +313,61 @@ public class UsageStatsService extends SystemService implements
mHandler.sendEmptyMessageDelayed(MSG_CHECK_IDLE_STATES, mCheckIdleIntervalMillis);
}
+ void updateDisplayLocked() {
+ boolean screenOn = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY).getState()
+ != Display.STATE_OFF;
+ if (screenOn == mScreenOn) return;
+
+ mScreenOn = screenOn;
+ long now = System.currentTimeMillis();
+ if (mScreenOn) {
+ mScreenOnSystemTimeSnapshot = now;
+ } else {
+ mScreenOnTime += now - mScreenOnSystemTimeSnapshot;
+ writeScreenOnTimeLocked(mScreenOnTime);
+ }
+ }
+
+ private long getScreenOnTimeLocked(long now) {
+ if (mScreenOn) {
+ return now - mScreenOnSystemTimeSnapshot + mScreenOnTime;
+ } else {
+ return mScreenOnTime;
+ }
+ }
+
+ private File getScreenOnTimeFile() {
+ return new File(mUsageStatsDir, UserHandle.USER_OWNER + "/screen_on_time");
+ }
+
+ private long readScreenOnTimeLocked() {
+ long screenOnTime = 0;
+ File screenOnTimeFile = getScreenOnTimeFile();
+ if (screenOnTimeFile.exists()) {
+ try {
+ BufferedReader reader = new BufferedReader(new FileReader(screenOnTimeFile));
+ screenOnTime = Long.parseLong(reader.readLine());
+ reader.close();
+ } catch (IOException | NumberFormatException e) {
+ }
+ } else {
+ writeScreenOnTimeLocked(screenOnTime);
+ }
+ return screenOnTime;
+ }
+
+ private void writeScreenOnTimeLocked(long screenOnTime) {
+ AtomicFile screenOnTimeFile = new AtomicFile(getScreenOnTimeFile());
+ FileOutputStream fos = null;
+ try {
+ fos = screenOnTimeFile.startWrite();
+ fos.write(Long.toString(screenOnTime).getBytes());
+ screenOnTimeFile.finishWrite(fos);
+ } catch (IOException ioe) {
+ screenOnTimeFile.failWrite(fos);
+ }
+ }
+
private static void deleteRecursively(File f) {
File[] files = f.listFiles();
if (files != null) {
@@ -289,7 +387,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);
+ service.init(currentTimeMillis, getScreenOnTimeLocked(currentTimeMillis));
mUserState.put(userId, service);
}
return service;
@@ -343,9 +441,10 @@ public class UsageStatsService extends SystemService implements
final UserUsageStatsService service =
getUserDataAndInitializeIfNeededLocked(userId, timeNow);
- final long lastUsed = service.getLastPackageAccessTime(event.mPackage);
- final boolean previouslyIdle = hasPassedIdleDuration(lastUsed);
- service.reportEvent(event);
+ final long lastUsed = service.getBeginIdleTime(event.mPackage);
+ final long screenOnTime = getScreenOnTimeLocked(timeNow);
+ final boolean previouslyIdle = hasPassedIdleTimeout(lastUsed, screenOnTime);
+ service.reportEvent(event, screenOnTime);
// Inform listeners if necessary
if ((event.mEventType == Event.MOVE_TO_FOREGROUND
|| event.mEventType == Event.MOVE_TO_BACKGROUND
@@ -360,19 +459,21 @@ public class UsageStatsService extends SystemService implements
}
/**
- * Forces the app's timestamp to reflect idle or active. If idle, then it rolls back the
- * last used timestamp to a point in time thats behind the threshold for idle.
+ * Forces the app's beginIdleTime to reflect idle or active. If idle, then it rolls back the
+ * beginIdleTime to a point in time thats behind the threshold for idle.
*/
- void resetLastTimestamp(String packageName, int userId, boolean idle) {
+ void forceIdleState(String packageName, int userId, boolean idle) {
synchronized (mLock) {
final long timeNow = checkAndGetTimeLocked();
- final long lastTimestamp = timeNow - (idle ? mAppIdleDurationMillis : 0) - 5000;
+ final long screenOnTime = getScreenOnTimeLocked(timeNow);
+ final long deviceUsageTime = screenOnTime - (idle ? mAppIdleDurationMillis : 0) - 5000;
final UserUsageStatsService service =
getUserDataAndInitializeIfNeededLocked(userId, timeNow);
- final long lastUsed = service.getLastPackageAccessTime(packageName);
- final boolean previouslyIdle = hasPassedIdleDuration(lastUsed);
- service.setLastTimestamp(packageName, lastTimestamp);
+ final long lastUsed = service.getBeginIdleTime(packageName);
+ final boolean previouslyIdle = hasPassedIdleTimeout(lastUsed,
+ getScreenOnTimeLocked(timeNow));
+ service.setBeginIdleTime(packageName, deviceUsageTime);
// Inform listeners if necessary
if (previouslyIdle != idle) {
// Slog.d(TAG, "Informing listeners of out-of-idle " + event.mPackage);
@@ -451,23 +552,25 @@ public class UsageStatsService extends SystemService implements
}
}
- /**
- * Called by LocalService stub.
- */
- long getLastPackageAccessTime(String packageName, int userId) {
+ private boolean isAppIdleUnfiltered(String packageName, int userId) {
synchronized (mLock) {
final long timeNow = checkAndGetTimeLocked();
- // android package is always considered non-idle.
- // TODO: Add a generic whitelisting mechanism
- if (packageName.equals("android")) {
- return timeNow;
- }
final UserUsageStatsService service =
getUserDataAndInitializeIfNeededLocked(userId, timeNow);
- return service.getLastPackageAccessTime(packageName);
+ long beginIdleTime = service.getBeginIdleTime(packageName);
+ return hasPassedIdleTimeout(beginIdleTime, getScreenOnTimeLocked(timeNow));
}
}
+ /**
+ * @param timestamp when the app was last used in device usage timebase
+ * @param currentTime current time in device usage timebase
+ * @return whether it's been used far enough in the past to be considered inactive
+ */
+ boolean hasPassedIdleTimeout(long timestamp, long currentTime) {
+ return timestamp <= currentTime - mAppIdleDurationMillis;
+ }
+
void addListener(AppIdleStateChangeListener listener) {
synchronized (mLock) {
if (!mPackageAccessListeners.contains(listener)) {
@@ -482,12 +585,13 @@ public class UsageStatsService extends SystemService implements
}
}
- private boolean hasPassedIdleDuration(long lastUsed) {
- final long now = System.currentTimeMillis();
- return lastUsed <= now - mAppIdleDurationMillis;
- }
-
- boolean isAppIdle(String packageName, int userId) {
+ /**
+ * Checks if an app has been idle for a while and filters out apps that are excluded.
+ * It returns false if the current system state allows all apps to be considered active.
+ * This happens if the device is plugged in or temporarily allowed to make exceptions.
+ * Called by interface impls.
+ */
+ boolean isAppIdleFiltered(String packageName, int userId) {
if (packageName == null) return false;
synchronized (mLock) {
// Temporary exemption, probably due to device charging or occasional allowance to
@@ -496,8 +600,12 @@ public class UsageStatsService extends SystemService implements
return false;
}
}
- if (SystemConfig.getInstance().getAllowInPowerSave().contains(packageName)) {
- return false;
+ if (packageName.equals("android")) return false;
+ try {
+ if (mDeviceIdleController.isPowerSaveWhitelistApp(packageName)) {
+ return false;
+ }
+ } catch (RemoteException re) {
}
// TODO: Optimize this check
if (isActiveDeviceAdmin(packageName, userId)) {
@@ -509,14 +617,13 @@ public class UsageStatsService extends SystemService implements
return false;
}
- final long lastUsed = getLastPackageAccessTime(packageName, userId);
- return hasPassedIdleDuration(lastUsed);
+ return isAppIdleUnfiltered(packageName, userId);
}
void setAppIdle(String packageName, boolean idle, int userId) {
if (packageName == null) return;
- mHandler.obtainMessage(MSG_RESET_LAST_TIMESTAMP, userId, idle ? 1 : 0, packageName)
+ mHandler.obtainMessage(MSG_FORCE_IDLE_STATE, userId, idle ? 1 : 0, packageName)
.sendToTarget();
}
@@ -559,6 +666,7 @@ public class UsageStatsService extends SystemService implements
*/
void dump(String[] args, PrintWriter pw) {
synchronized (mLock) {
+ final long screenOnTime = getScreenOnTimeLocked(checkAndGetTimeLocked());
IndentingPrintWriter idpw = new IndentingPrintWriter(pw, " ");
ArraySet<String> argSet = new ArraySet<>();
argSet.addAll(Arrays.asList(args));
@@ -569,12 +677,13 @@ public class UsageStatsService extends SystemService implements
idpw.println();
idpw.increaseIndent();
if (argSet.contains("--checkin")) {
- mUserState.valueAt(i).checkin(idpw);
+ mUserState.valueAt(i).checkin(idpw, screenOnTime);
} else {
- mUserState.valueAt(i).dump(idpw);
+ mUserState.valueAt(i).dump(idpw, screenOnTime);
}
idpw.decreaseIndent();
}
+ pw.write("Screen On Timestamp:" + mScreenOnTime + "\n");
}
}
@@ -602,8 +711,8 @@ public class UsageStatsService extends SystemService implements
informListeners((String) msg.obj, msg.arg1, msg.arg2 == 1);
break;
- case MSG_RESET_LAST_TIMESTAMP:
- resetLastTimestamp((String) msg.obj, msg.arg1, msg.arg2 == 1);
+ case MSG_FORCE_IDLE_STATE:
+ forceIdleState((String) msg.obj, msg.arg1, msg.arg2 == 1);
break;
case MSG_CHECK_IDLE_STATES:
@@ -727,7 +836,7 @@ public class UsageStatsService extends SystemService implements
}
final long token = Binder.clearCallingIdentity();
try {
- return UsageStatsService.this.isAppIdle(packageName, userId);
+ return UsageStatsService.this.isAppIdleFiltered(packageName, userId);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -832,12 +941,7 @@ public class UsageStatsService extends SystemService implements
@Override
public boolean isAppIdle(String packageName, int userId) {
- return UsageStatsService.this.isAppIdle(packageName, userId);
- }
-
- @Override
- public long getLastPackageAccessTime(String packageName, int userId) {
- return UsageStatsService.this.getLastPackageAccessTime(packageName, userId);
+ return UsageStatsService.this.isAppIdleFiltered(packageName, userId);
}
@Override
diff --git a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
index bfb71c5..0111201 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
@@ -26,6 +26,7 @@ import android.app.usage.TimeSparseArray;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStats;
import android.content.res.Configuration;
+import android.text.TextUtils;
import java.io.IOException;
import java.net.ProtocolException;
@@ -54,6 +55,7 @@ final class UsageStatsXmlV1 {
// Time attributes stored as an offset of the beginTime.
private static final String LAST_TIME_ACTIVE_ATTR = "lastTimeActive";
+ private static final String BEGIN_IDLE_TIME_ATTR = "beginIdleTime";
private static final String END_TIME_ATTR = "endTime";
private static final String TIME_ATTR = "time";
@@ -69,7 +71,10 @@ final class UsageStatsXmlV1 {
// Apply the offset to the beginTime to find the absolute time.
stats.mLastTimeUsed = statsOut.beginTime + XmlUtils.readLongAttribute(
parser, LAST_TIME_ACTIVE_ATTR);
-
+ final String beginIdleTime = parser.getAttributeValue(null, BEGIN_IDLE_TIME_ATTR);
+ if (!TextUtils.isEmpty(beginIdleTime)) {
+ stats.mBeginIdleTime = Long.parseLong(beginIdleTime);
+ }
stats.mTotalTimeInForeground = XmlUtils.readLongAttribute(parser, TOTAL_TIME_ACTIVE_ATTR);
stats.mLastEvent = XmlUtils.readIntAttribute(parser, LAST_EVENT_ATTR);
}
@@ -129,6 +134,7 @@ final class UsageStatsXmlV1 {
XmlUtils.writeStringAttribute(xml, PACKAGE_ATTR, usageStats.mPackageName);
XmlUtils.writeLongAttribute(xml, TOTAL_TIME_ACTIVE_ATTR, usageStats.mTotalTimeInForeground);
XmlUtils.writeIntAttribute(xml, LAST_EVENT_ATTR, usageStats.mLastEvent);
+ XmlUtils.writeLongAttribute(xml, BEGIN_IDLE_TIME_ATTR, usageStats.mBeginIdleTime);
xml.endTag(null, PACKAGE_TAG);
}
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index d94759d..b638c8e 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -80,7 +80,7 @@ class UserUsageStatsService {
mUserId = userId;
}
- void init(final long currentTimeMillis) {
+ void init(final long currentTimeMillis, final long deviceUsageTime) {
mDatabase.init(currentTimeMillis);
int nullCount = 0;
@@ -135,7 +135,8 @@ class UserUsageStatsService {
}
if (mDatabase.isNewUpdate()) {
- initializeDefaultsForApps(currentTimeMillis, mDatabase.isFirstUpdate());
+ initializeDefaultsForApps(currentTimeMillis, deviceUsageTime,
+ mDatabase.isFirstUpdate());
}
}
@@ -145,7 +146,8 @@ class UserUsageStatsService {
* @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) {
+ private void initializeDefaultsForApps(long currentTimeMillis, long deviceUsageTime,
+ boolean firstUpdate) {
PackageManager pm = mContext.getPackageManager();
List<PackageInfo> packages = pm.getInstalledPackages(0, mUserId);
final int packageCount = packages.size();
@@ -153,9 +155,10 @@ class UserUsageStatsService {
final PackageInfo pi = packages.get(i);
String packageName = pi.packageName;
if (pi.applicationInfo != null && (firstUpdate || pi.applicationInfo.isSystemApp())
- && getLastPackageAccessTime(packageName) == -1) {
+ && getBeginIdleTime(packageName) == -1) {
for (IntervalStats stats : mCurrentStats) {
stats.update(packageName, currentTimeMillis, Event.INTERACTION);
+ stats.updateBeginIdleTime(packageName, deviceUsageTime);
mStatsChanged = true;
}
}
@@ -170,7 +173,7 @@ class UserUsageStatsService {
loadActiveStats(newTime, true);
}
- void reportEvent(UsageEvents.Event event) {
+ void reportEvent(UsageEvents.Event event, long deviceUsageTime) {
if (DEBUG) {
Slog.d(TAG, mLogPrefix + "Got usage event for " + event.mPackage
+ "[" + event.mTimeStamp + "]: "
@@ -205,6 +208,7 @@ class UserUsageStatsService {
stats.updateConfigurationStats(newFullConfig, event.mTimeStamp);
} else {
stats.update(event.mPackage, event.mTimeStamp, event.mEventType);
+ stats.updateBeginIdleTime(event.mPackage, deviceUsageTime);
}
}
@@ -215,9 +219,9 @@ class UserUsageStatsService {
* Sets the last timestamp for each of the intervals.
* @param lastTimestamp
*/
- void setLastTimestamp(String packageName, long lastTimestamp) {
+ void setBeginIdleTime(String packageName, long deviceUsageTime) {
for (IntervalStats stats : mCurrentStats) {
- stats.update(packageName, lastTimestamp, UsageEvents.Event.NONE);
+ stats.updateBeginIdleTime(packageName, deviceUsageTime);
}
notifyStatsChanged();
}
@@ -376,13 +380,13 @@ class UserUsageStatsService {
return new UsageEvents(results, table);
}
- long getLastPackageAccessTime(String packageName) {
+ long getBeginIdleTime(String packageName) {
final IntervalStats yearly = mCurrentStats[UsageStatsManager.INTERVAL_YEARLY];
UsageStats packageUsage;
if ((packageUsage = yearly.packageStats.get(packageName)) == null) {
return -1;
} else {
- return packageUsage.getLastTimeUsed();
+ return packageUsage.getBeginIdleTime();
}
}
@@ -506,23 +510,23 @@ class UserUsageStatsService {
// -- DUMP related methods --
//
- void checkin(final IndentingPrintWriter pw) {
+ void checkin(final IndentingPrintWriter pw, final long screenOnTime) {
mDatabase.checkinDailyFiles(new UsageStatsDatabase.CheckinAction() {
@Override
public boolean checkin(IntervalStats stats) {
- printIntervalStats(pw, stats, false);
+ printIntervalStats(pw, stats, screenOnTime, false);
return true;
}
});
}
- void dump(IndentingPrintWriter pw) {
+ void dump(IndentingPrintWriter pw, final long screenOnTime) {
// This is not a check-in, only dump in-memory stats.
for (int interval = 0; interval < mCurrentStats.length; interval++) {
pw.print("In-memory ");
pw.print(intervalToString(interval));
pw.println(" stats");
- printIntervalStats(pw, mCurrentStats[interval], true);
+ printIntervalStats(pw, mCurrentStats[interval], screenOnTime, true);
}
}
@@ -540,7 +544,8 @@ class UserUsageStatsService {
return Long.toString(elapsedTime);
}
- void printIntervalStats(IndentingPrintWriter pw, IntervalStats stats, boolean prettyDates) {
+ void printIntervalStats(IndentingPrintWriter pw, IntervalStats stats, long screenOnTime,
+ boolean prettyDates) {
if (prettyDates) {
pw.printPair("timeRange", "\"" + DateUtils.formatDateRange(mContext,
stats.beginTime, stats.endTime, sDateFormatFlags) + "\"");
@@ -559,6 +564,8 @@ class UserUsageStatsService {
pw.printPair("package", usageStats.mPackageName);
pw.printPair("totalTime", formatElapsedTime(usageStats.mTotalTimeInForeground, prettyDates));
pw.printPair("lastTime", formatDateTime(usageStats.mLastTimeUsed, prettyDates));
+ pw.printPair("inactiveTime",
+ formatElapsedTime(screenOnTime - usageStats.mBeginIdleTime, prettyDates));
pw.println();
}
pw.decreaseIndent();