diff options
11 files changed, 76 insertions, 30 deletions
diff --git a/api/current.txt b/api/current.txt index 058297ad5d3c..24ad077275f1 100644 --- a/api/current.txt +++ b/api/current.txt @@ -6148,10 +6148,10 @@ package android.app.usage { method public java.lang.String getPackageName(); method public long getTimeStamp(); field public static final int CONFIGURATION_CHANGE = 5; // 0x5 - field public static final int INTERACTION = 6; // 0x6 field public static final int MOVE_TO_BACKGROUND = 2; // 0x2 field public static final int MOVE_TO_FOREGROUND = 1; // 0x1 field public static final int NONE = 0; // 0x0 + field public static final int USER_INTERACTION = 7; // 0x7 } public final class UsageStats implements android.os.Parcelable { diff --git a/api/system-current.txt b/api/system-current.txt index ea2de6b2d36a..0d10c43e2812 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -6341,10 +6341,10 @@ package android.app.usage { method public java.lang.String getPackageName(); method public long getTimeStamp(); field public static final int CONFIGURATION_CHANGE = 5; // 0x5 - field public static final int INTERACTION = 6; // 0x6 field public static final int MOVE_TO_BACKGROUND = 2; // 0x2 field public static final int MOVE_TO_FOREGROUND = 1; // 0x1 field public static final int NONE = 0; // 0x0 + field public static final int USER_INTERACTION = 7; // 0x7 } public final class UsageStats implements android.os.Parcelable { diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java index 58279d744124..369b692a1213 100644 --- a/core/java/android/app/usage/UsageEvents.java +++ b/core/java/android/app/usage/UsageEvents.java @@ -68,9 +68,15 @@ public final class UsageEvents implements Parcelable { public static final int CONFIGURATION_CHANGE = 5; /** - * An event type denoting that a package was interacted with in some way. + * An event type denoting that a package was interacted with in some way by the system. + * @hide */ - public static final int INTERACTION = 6; + public static final int SYSTEM_INTERACTION = 6; + + /** + * An event type denoting that a package was interacted with in some way by the user. + */ + public static final int USER_INTERACTION = 7; /** * {@hide} diff --git a/core/java/android/app/usage/UsageStats.java b/core/java/android/app/usage/UsageStats.java index 81c74227edd4..0fce4e2cd184 100644 --- a/core/java/android/app/usage/UsageStats.java +++ b/core/java/android/app/usage/UsageStats.java @@ -41,11 +41,19 @@ public final class UsageStats implements Parcelable { public long mEndTimeStamp; /** + * Last time used by the user with an explicit action (notification, activity launch). * {@hide} */ public long mLastTimeUsed; /** + * The last time the package was used via implicit, non-user initiated actions (service + * was bound, etc). + * {@hide} + */ + public long mLastTimeSystemUsed; + + /** * Last time the package was used and the beginning of the idle countdown. * This uses a different timebase that is about how much the device has been in use in general. * {@hide} @@ -82,6 +90,7 @@ public final class UsageStats implements Parcelable { mLaunchCount = stats.mLaunchCount; mLastEvent = stats.mLastEvent; mBeginIdleTime = stats.mBeginIdleTime; + mLastTimeSystemUsed = stats.mLastTimeSystemUsed; } public String getPackageName() { @@ -119,6 +128,16 @@ public final class UsageStats implements Parcelable { /** * @hide + * Get the last time this package was used by the system (not the user). This can be different + * from {@link #getLastTimeUsed()} when the system binds to one of this package's services. + * See {@link System#currentTimeMillis()}. + */ + public long getLastTimeSystemUsed() { + return mLastTimeSystemUsed; + } + + /** + * @hide * Get the last time this package was active, measured in milliseconds. This timestamp * uses a timebase that represents how much the device was used and not wallclock time. */ @@ -151,6 +170,7 @@ public final class UsageStats implements Parcelable { mEndTimeStamp = right.mEndTimeStamp; mLastTimeUsed = right.mLastTimeUsed; mBeginIdleTime = right.mBeginIdleTime; + mLastTimeSystemUsed = right.mLastTimeSystemUsed; } mBeginTimeStamp = Math.min(mBeginTimeStamp, right.mBeginTimeStamp); mTotalTimeInForeground += right.mTotalTimeInForeground; @@ -172,6 +192,7 @@ public final class UsageStats implements Parcelable { dest.writeInt(mLaunchCount); dest.writeInt(mLastEvent); dest.writeLong(mBeginIdleTime); + dest.writeLong(mLastTimeSystemUsed); } public static final Creator<UsageStats> CREATOR = new Creator<UsageStats>() { @@ -186,6 +207,7 @@ public final class UsageStats implements Parcelable { stats.mLaunchCount = in.readInt(); stats.mLastEvent = in.readInt(); stats.mBeginIdleTime = in.readLong(); + stats.mLastTimeSystemUsed = in.readLong(); return stats; } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 0d08c2ab5ea2..d974de07dd71 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -18617,7 +18617,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (packages != null) { for (int i = 0; i < packages.length; i++) { mUsageStatsService.reportEvent(packages[i], app.userId, - UsageEvents.Event.INTERACTION); + UsageEvents.Event.SYSTEM_INTERACTION); } } } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 8ee20766ee72..90e912d03e60 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -1407,7 +1407,7 @@ public class NotificationManagerService extends SystemService { mAppUsageStats.reportEvent(r.sbn.getPackageName(), userId == UserHandle.USER_ALL ? UserHandle.USER_OWNER : userId, - UsageEvents.Event.INTERACTION); + UsageEvents.Event.USER_INTERACTION); r.setSeen(); } } diff --git a/services/usage/java/com/android/server/usage/IntervalStats.java b/services/usage/java/com/android/server/usage/IntervalStats.java index a61567567b76..1aa297854e72 100644 --- a/services/usage/java/com/android/server/usage/IntervalStats.java +++ b/services/usage/java/com/android/server/usage/IntervalStats.java @@ -110,7 +110,10 @@ class IntervalStats { usageStats.mLastEvent = eventType; } - usageStats.mLastTimeUsed = timeStamp; + if (eventType != UsageEvents.Event.SYSTEM_INTERACTION) { + usageStats.mLastTimeUsed = timeStamp; + } + usageStats.mLastTimeSystemUsed = timeStamp; usageStats.mEndTimeStamp = timeStamp; if (eventType == UsageEvents.Event.MOVE_TO_FOREGROUND) { @@ -131,9 +134,9 @@ class IntervalStats { usageStats.mBeginIdleTime = timeStamp; } - void updateLastUsedTime(String packageName, long lastUsedTime) { + void updateSystemLastUsedTime(String packageName, long lastUsedTime) { UsageStats usageStats = getOrCreateUsageStats(packageName); - usageStats.mLastTimeUsed = lastUsedTime; + usageStats.mLastTimeSystemUsed = lastUsedTime; } void updateConfigurationStats(Configuration config, long timeStamp) { diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 633aee82b384..7a3475790ce2 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -60,7 +60,6 @@ import android.provider.Settings; import android.telephony.TelephonyManager; import android.util.ArraySet; import android.util.AtomicFile; -import android.util.Log; import android.util.Slog; import android.util.SparseArray; import android.view.Display; @@ -543,14 +542,15 @@ public class UsageStatsService extends SystemService implements final UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId, timeNow); final long beginIdleTime = service.getBeginIdleTime(event.mPackage); - final long lastUsedTime = service.getLastUsedTime(event.mPackage); + final long lastUsedTime = service.getSystemLastUsedTime(event.mPackage); final boolean previouslyIdle = hasPassedIdleTimeoutLocked(beginIdleTime, lastUsedTime, screenOnTime, timeNow); service.reportEvent(event, getScreenOnTimeLocked(timeNow)); // Inform listeners if necessary if ((event.mEventType == Event.MOVE_TO_FOREGROUND || event.mEventType == Event.MOVE_TO_BACKGROUND - || event.mEventType == Event.INTERACTION)) { + || 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, @@ -575,11 +575,11 @@ public class UsageStatsService extends SystemService implements final UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId, timeNow); final long beginIdleTime = service.getBeginIdleTime(packageName); - final long lastUsedTime = service.getLastUsedTime(packageName); + final long lastUsedTime = service.getSystemLastUsedTime(packageName); final boolean previouslyIdle = hasPassedIdleTimeoutLocked(beginIdleTime, lastUsedTime, screenOnTime, timeNow); service.setBeginIdleTime(packageName, deviceUsageTime); - service.setLastUsedTime(packageName, + service.setSystemLastUsedTime(packageName, timeNow - (idle ? DEFAULT_WALLCLOCK_APP_IDLE_THRESHOLD_MILLIS : 0) - 5000); // Inform listeners if necessary if (previouslyIdle != idle) { @@ -666,7 +666,7 @@ public class UsageStatsService extends SystemService implements final UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId, timeNow); long beginIdleTime = service.getBeginIdleTime(packageName); - long lastUsedTime = service.getLastUsedTime(packageName); + long lastUsedTime = service.getSystemLastUsedTime(packageName); return hasPassedIdleTimeoutLocked(beginIdleTime, lastUsedTime, screenOnTime, timeNow); } } diff --git a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java index 01112014c753..f2ca3a4047fa 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java +++ b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java @@ -55,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 LAST_TIME_ACTIVE_SYSTEM_ATTR = "lastTimeActiveSystem"; private static final String BEGIN_IDLE_TIME_ATTR = "beginIdleTime"; private static final String END_TIME_ATTR = "endTime"; private static final String TIME_ATTR = "time"; @@ -71,6 +72,16 @@ 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 lastTimeUsedSystem = parser.getAttributeValue(null, + LAST_TIME_ACTIVE_SYSTEM_ATTR); + if (TextUtils.isEmpty(lastTimeUsedSystem)) { + // If the field isn't present, use the old one. + stats.mLastTimeSystemUsed = stats.mLastTimeUsed; + } else { + stats.mLastTimeSystemUsed = statsOut.beginTime + Long.parseLong(lastTimeUsedSystem); + } + final String beginIdleTime = parser.getAttributeValue(null, BEGIN_IDLE_TIME_ATTR); if (!TextUtils.isEmpty(beginIdleTime)) { stats.mBeginIdleTime = Long.parseLong(beginIdleTime); @@ -130,6 +141,8 @@ final class UsageStatsXmlV1 { // Write the time offset. XmlUtils.writeLongAttribute(xml, LAST_TIME_ACTIVE_ATTR, usageStats.mLastTimeUsed - stats.beginTime); + XmlUtils.writeLongAttribute(xml, LAST_TIME_ACTIVE_SYSTEM_ATTR, + usageStats.mLastTimeSystemUsed - stats.beginTime); XmlUtils.writeStringAttribute(xml, PACKAGE_ATTR, usageStats.mPackageName); XmlUtils.writeLongAttribute(xml, TOTAL_TIME_ACTIVE_ATTR, usageStats.mTotalTimeInForeground); diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java index 7c00dae8e2f0..b07b8153279d 100644 --- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java @@ -157,7 +157,7 @@ class UserUsageStatsService { if (pi.applicationInfo != null && (firstUpdate || pi.applicationInfo.isSystemApp()) && getBeginIdleTime(packageName) == -1) { for (IntervalStats stats : mCurrentStats) { - stats.update(packageName, currentTimeMillis, Event.INTERACTION); + stats.update(packageName, currentTimeMillis, Event.SYSTEM_INTERACTION); stats.updateBeginIdleTime(packageName, deviceUsageTime); mStatsChanged = true; } @@ -199,7 +199,7 @@ class UserUsageStatsService { if (currentDailyStats.events == null) { currentDailyStats.events = new TimeSparseArray<>(); } - if (event.mEventType != UsageEvents.Event.INTERACTION) { + if (event.mEventType != UsageEvents.Event.SYSTEM_INTERACTION) { currentDailyStats.events.put(event.mTimeStamp, event); } @@ -226,9 +226,9 @@ class UserUsageStatsService { notifyStatsChanged(); } - void setLastUsedTime(String packageName, long lastUsedTime) { + void setSystemLastUsedTime(String packageName, long lastUsedTime) { for (IntervalStats stats : mCurrentStats) { - stats.updateLastUsedTime(packageName, lastUsedTime); + stats.updateSystemLastUsedTime(packageName, lastUsedTime); } notifyStatsChanged(); } @@ -397,13 +397,13 @@ class UserUsageStatsService { } } - long getLastUsedTime(String packageName) { + long getSystemLastUsedTime(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.getLastTimeSystemUsed(); } } @@ -586,8 +586,11 @@ class UserUsageStatsService { for (int i = 0; i < pkgCount; i++) { final UsageStats usageStats = pkgStats.valueAt(i); pw.printPair("package", usageStats.mPackageName); - pw.printPair("totalTime", formatElapsedTime(usageStats.mTotalTimeInForeground, prettyDates)); + pw.printPair("totalTime", + formatElapsedTime(usageStats.mTotalTimeInForeground, prettyDates)); pw.printPair("lastTime", formatDateTime(usageStats.mLastTimeUsed, prettyDates)); + pw.printPair("lastTimeSystem", + formatDateTime(usageStats.mLastTimeSystemUsed, prettyDates)); pw.printPair("inactiveTime", formatElapsedTime(screenOnTime - usageStats.mBeginIdleTime, prettyDates)); pw.println(); @@ -596,8 +599,7 @@ class UserUsageStatsService { pw.println("configurations"); pw.increaseIndent(); - final ArrayMap<Configuration, ConfigurationStats> configStats = - stats.configurations; + final ArrayMap<Configuration, ConfigurationStats> configStats = stats.configurations; final int configCount = configStats.size(); for (int i = 0; i < configCount; i++) { final ConfigurationStats config = configStats.valueAt(i); @@ -659,8 +661,10 @@ class UserUsageStatsService { return "CONTINUE_PREVIOUS_DAY"; case UsageEvents.Event.CONFIGURATION_CHANGE: return "CONFIGURATION_CHANGE"; - case UsageEvents.Event.INTERACTION: - return "INTERACTION"; + case UsageEvents.Event.SYSTEM_INTERACTION: + return "SYSTEM_INTERACTION"; + case UsageEvents.Event.USER_INTERACTION: + return "USER_INTERACTION"; default: return "UNKNOWN"; } diff --git a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java index 8e6daea43367..05cac10f92c6 100644 --- a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java +++ b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java @@ -28,8 +28,6 @@ import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; -import java.util.ArrayList; - public class UsageLogActivity extends ListActivity implements Runnable { private static final long USAGE_STATS_PERIOD = 1000 * 60 * 60 * 24 * 14; @@ -166,8 +164,8 @@ public class UsageLogActivity extends ListActivity implements Runnable { case UsageEvents.Event.CONFIGURATION_CHANGE: return "Config change"; - case UsageEvents.Event.INTERACTION: - return "Interaction"; + case UsageEvents.Event.USER_INTERACTION: + return "User Interaction"; default: return "Unknown: " + eventType; |