Loading api/current.txt +4 −0 Original line number Diff line number Diff line Loading @@ -7580,6 +7580,8 @@ package android.app.usage { method public java.lang.String getShortcutId(); method public long getTimeStamp(); field public static final int CONFIGURATION_CHANGE = 5; // 0x5 field public static final int FOREGROUND_SERVICE_START = 19; // 0x13 field public static final int FOREGROUND_SERVICE_STOP = 20; // 0x14 field public static final int KEYGUARD_HIDDEN = 18; // 0x12 field public static final int KEYGUARD_SHOWN = 17; // 0x11 field public static final int MOVE_TO_BACKGROUND = 2; // 0x2 Loading @@ -7597,9 +7599,11 @@ package android.app.usage { method public void add(android.app.usage.UsageStats); method public int describeContents(); method public long getFirstTimeStamp(); method public long getLastTimeForegroundServiceUsed(); method public long getLastTimeStamp(); method public long getLastTimeUsed(); method public java.lang.String getPackageName(); method public long getTotalTimeForegroundServiceUsed(); method public long getTotalTimeInForeground(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.usage.UsageStats> CREATOR; core/java/android/app/usage/UsageEvents.java +44 −3 Original line number Diff line number Diff line Loading @@ -50,12 +50,20 @@ public final class UsageEvents implements Parcelable { public static final int NONE = 0; /** * An event type denoting that a component moved to the foreground. * An event type denoting that an {@link android.app.Activity} moved to the foreground. * This event has a package name and class name associated with it and can be retrieved * using {@link #getPackageName()} and {@link #getClassName()}. * If a package has multiple activities, this event is reported for each activity that moves * to foreground. */ public static final int MOVE_TO_FOREGROUND = 1; /** * An event type denoting that a component moved to the background. * An event type denoting that an {@link android.app.Activity} moved to the background. * This event has a package name and class name associated with it and can be retrieved * using {@link #getPackageName()} and {@link #getClassName()}. * If a package has multiple activities, this event is reported for each activity that moves * to background. */ public static final int MOVE_TO_BACKGROUND = 2; Loading Loading @@ -165,11 +173,44 @@ public final class UsageEvents implements Parcelable { */ public static final int KEYGUARD_HIDDEN = 18; /** * An event type denoting start of a foreground service. * This event has a package name and class name associated with it and can be retrieved * using {@link #getPackageName()} and {@link #getClassName()}. * If a package has multiple foreground services, this event is reported for each service * that is started. */ public static final int FOREGROUND_SERVICE_START = 19; /** * An event type denoting stop of a foreground service. * This event has a package name and class name associated with it and can be retrieved * using {@link #getPackageName()} and {@link #getClassName()}. * If a package has multiple foreground services, this event is reported for each service * that is stopped. */ public static final int FOREGROUND_SERVICE_STOP = 20; /** * An event type denoting that a foreground service is at started state at beginning of a * time interval. * This is effectively treated as a {@link #FOREGROUND_SERVICE_START}. * {@hide} */ public static final int CONTINUING_FOREGROUND_SERVICE = 21; /** * An event type denoting that a foreground service is at started state when the stats * rolled-over at the end of a time interval. * {@hide} */ public static final int ROLLOVER_FOREGROUND_SERVICE = 22; /** * Keep in sync with the greatest event type value. * @hide */ public static final int MAX_EVENT_TYPE = 18; public static final int MAX_EVENT_TYPE = 22; /** @hide */ public static final int FLAG_IS_PACKAGE_INSTANT_APP = 1 << 0; Loading core/java/android/app/usage/UsageStats.java +271 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,15 @@ package android.app.usage; import static android.app.usage.UsageEvents.Event.CONTINUE_PREVIOUS_DAY; import static android.app.usage.UsageEvents.Event.CONTINUING_FOREGROUND_SERVICE; import static android.app.usage.UsageEvents.Event.END_OF_DAY; import static android.app.usage.UsageEvents.Event.FOREGROUND_SERVICE_START; import static android.app.usage.UsageEvents.Event.FOREGROUND_SERVICE_STOP; import static android.app.usage.UsageEvents.Event.MOVE_TO_BACKGROUND; import static android.app.usage.UsageEvents.Event.MOVE_TO_FOREGROUND; import static android.app.usage.UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.os.Bundle; Loading Loading @@ -48,18 +57,31 @@ public final class UsageStats implements Parcelable { public long mEndTimeStamp; /** * Last time used by the user with an explicit action (notification, activity launch). * Last time used by the user with an explicit action (notification, activity launch) * {@hide} */ @UnsupportedAppUsage public long mLastTimeUsed; /** * Total time this package's activity is in foreground. * {@hide} */ @UnsupportedAppUsage public long mTotalTimeInForeground; /** * Last time foreground service is started. * {@hide} */ public long mLastTimeForegroundServiceUsed; /** * Total time this package's foreground service is started. * {@hide} */ public long mTotalTimeForegroundServiceUsed; /** * {@hide} */ Loading @@ -71,16 +93,36 @@ public final class UsageStats implements Parcelable { */ public int mAppLaunchCount; /** /** Last activity MOVE_TO_FOREGROUND or MOVE_TO_BACKGROUND event. * {@hide} * @deprecated use {@link #mLastForegroundActivityEventMap} instead. */ @UnsupportedAppUsage @Deprecated public int mLastEvent; /** * If an activity is in foreground, it has one entry in this map. * When activity moves to background, it is removed from this map. * Key is activity class name. * Value is last time this activity MOVE_TO_FOREGROUND or MOVE_TO_BACKGROUND event. * {@hide} */ public ArrayMap<String, Integer> mLastForegroundActivityEventMap = new ArrayMap<>(); /** * If a foreground service is started, it has one entry in this map. * When a foreground service is stopped, it is removed from this map. * Key is foreground service class name. * Value is last foreground service FOREGROUND_SERVICE_START ot FOREGROUND_SERVICE_STOP event. * {@hide} */ public ArrayMap<String, ArrayMap<String, Integer>> mChooserCounts; public ArrayMap<String, Integer> mLastForegroundServiceEventMap = new ArrayMap<>(); /** * {@hide} */ public ArrayMap<String, ArrayMap<String, Integer>> mChooserCounts = new ArrayMap<>(); /** * {@hide} Loading @@ -93,10 +135,14 @@ public final class UsageStats implements Parcelable { mBeginTimeStamp = stats.mBeginTimeStamp; mEndTimeStamp = stats.mEndTimeStamp; mLastTimeUsed = stats.mLastTimeUsed; mLastTimeForegroundServiceUsed = stats.mLastTimeForegroundServiceUsed; mTotalTimeInForeground = stats.mTotalTimeInForeground; mTotalTimeForegroundServiceUsed = stats.mTotalTimeForegroundServiceUsed; mLaunchCount = stats.mLaunchCount; mAppLaunchCount = stats.mAppLaunchCount; mLastEvent = stats.mLastEvent; mLastForegroundActivityEventMap = stats.mLastForegroundActivityEventMap; mLastForegroundServiceEventMap = stats.mLastForegroundServiceEventMap; mChooserCounts = stats.mChooserCounts; } Loading Loading @@ -136,7 +182,7 @@ public final class UsageStats implements Parcelable { } /** * Get the last time this package was used, measured in milliseconds since the epoch. * Get the last time this package's activity was used, measured in milliseconds since the epoch. * <p/> * See {@link System#currentTimeMillis()}. */ Loading @@ -151,6 +197,23 @@ public final class UsageStats implements Parcelable { return mTotalTimeInForeground; } /** * Get the last time this package's foreground service was used, measured in milliseconds since * the epoch. * <p/> * See {@link System#currentTimeMillis()}. */ public long getLastTimeForegroundServiceUsed() { return mLastTimeForegroundServiceUsed; } /** * Get the total time this package's foreground services are started, measured in milliseconds. */ public long getTotalTimeForegroundServiceUsed() { return mTotalTimeForegroundServiceUsed; } /** * Returns the number of times the app was launched as an activity from outside of the app. * Excludes intra-app activity transitions. Loading @@ -161,6 +224,19 @@ public final class UsageStats implements Parcelable { return mAppLaunchCount; } private void mergeEventMap(ArrayMap<String, Integer> left, ArrayMap<String, Integer> right) { final int size = right.size(); for (int i = 0; i < size; i++) { final String className = right.keyAt(i); final Integer event = right.valueAt(i); if (left.containsKey(className)) { left.put(className, Math.max(left.get(className), event)); } else { left.put(className, event); } } } /** * Add the statistics from the right {@link UsageStats} to the left. The package name for * both {@link UsageStats} objects must be the same. Loading @@ -179,12 +255,16 @@ public final class UsageStats implements Parcelable { if (right.mBeginTimeStamp > mBeginTimeStamp) { // Even though incoming UsageStat begins after this one, its last time used fields // may somehow be empty or chronologically preceding the older UsageStat. mLastEvent = Math.max(mLastEvent, right.mLastEvent); mergeEventMap(mLastForegroundActivityEventMap, right.mLastForegroundActivityEventMap); mergeEventMap(mLastForegroundServiceEventMap, right.mLastForegroundServiceEventMap); mLastTimeUsed = Math.max(mLastTimeUsed, right.mLastTimeUsed); mLastTimeForegroundServiceUsed = Math.max(mLastTimeForegroundServiceUsed, right.mLastTimeForegroundServiceUsed); } mBeginTimeStamp = Math.min(mBeginTimeStamp, right.mBeginTimeStamp); mEndTimeStamp = Math.max(mEndTimeStamp, right.mEndTimeStamp); mTotalTimeInForeground += right.mTotalTimeInForeground; mTotalTimeForegroundServiceUsed += right.mTotalTimeForegroundServiceUsed; mLaunchCount += right.mLaunchCount; mAppLaunchCount += right.mAppLaunchCount; if (mChooserCounts == null) { Loading @@ -209,6 +289,161 @@ public final class UsageStats implements Parcelable { } } /** * Tell if an event indicate activity is in foreground or not. * @param event the activity event. * @return true if activity is in foreground, false otherwise. * @hide */ private boolean isActivityInForeground(int event) { return event == MOVE_TO_FOREGROUND || event == CONTINUE_PREVIOUS_DAY; } /** * Tell if an event indicate foreground sevice is started or not. * @param event the foreground service event. * @return true if foreground service is started, false if stopped. * @hide */ private boolean isForegroundServiceStarted(int event) { return event == FOREGROUND_SERVICE_START || event == CONTINUING_FOREGROUND_SERVICE; } /** * If any activity in foreground or any foreground service is started, the app is considered in * use. * @return true if in use, false otherwise. * @hide */ private boolean isAppInUse() { return !mLastForegroundActivityEventMap.isEmpty() || !mLastForegroundServiceEventMap.isEmpty(); } /** * Update by an event of an activity. * @param className className of the activity. * @param timeStamp timeStamp of the event. * @param eventType type of the event. * @hide */ private void updateForegroundActivity(String className, long timeStamp, int eventType) { if (eventType != MOVE_TO_BACKGROUND && eventType != MOVE_TO_FOREGROUND && eventType != END_OF_DAY) { return; } final Integer lastEvent = mLastForegroundActivityEventMap.get(className); if (lastEvent != null) { if (isActivityInForeground(lastEvent)) { if (timeStamp > mLastTimeUsed) { mTotalTimeInForeground += timeStamp - mLastTimeUsed; mLastTimeUsed = timeStamp; } } if (eventType == MOVE_TO_BACKGROUND) { mLastForegroundActivityEventMap.remove(className); } else { mLastForegroundActivityEventMap.put(className, eventType); } } else if (eventType == MOVE_TO_FOREGROUND) { if (!isAppInUse()) { mLastTimeUsed = timeStamp; } mLastForegroundActivityEventMap.put(className, eventType); } } /** * Update by an event of an foreground service. * @param className className of the foreground service. * @param timeStamp timeStamp of the event. * @param eventType type of the event. * @hide */ private void updateForegroundService(String className, long timeStamp, int eventType) { if (eventType != FOREGROUND_SERVICE_STOP && eventType != FOREGROUND_SERVICE_START && eventType != ROLLOVER_FOREGROUND_SERVICE) { return; } final Integer lastEvent = mLastForegroundServiceEventMap.get(className); if (lastEvent != null) { if (isForegroundServiceStarted(lastEvent)) { if (timeStamp > mLastTimeForegroundServiceUsed) { mTotalTimeForegroundServiceUsed += timeStamp - mLastTimeForegroundServiceUsed; mLastTimeForegroundServiceUsed = timeStamp; } } if (eventType == FOREGROUND_SERVICE_STOP) { mLastForegroundServiceEventMap.remove(className); } else { mLastForegroundServiceEventMap.put(className, eventType); } } else if (eventType == FOREGROUND_SERVICE_START) { if (!isAppInUse()) { mLastTimeForegroundServiceUsed = timeStamp; } mLastForegroundServiceEventMap.put(className, eventType); } } /** * Update the UsageStats by a activity or foreground service event. * @param className class name of a activity or foreground service, could be null to mark * END_OF_DAY or rollover. * @param timeStamp Epoch timestamp in milliseconds. * @param eventType event type as in {@link UsageEvents.Event} * @hide */ public void update(String className, long timeStamp, int eventType) { switch(eventType) { case MOVE_TO_BACKGROUND: case MOVE_TO_FOREGROUND: updateForegroundActivity(className, timeStamp, eventType); break; case END_OF_DAY: // END_OF_DAY means updating all activities. final int size = mLastForegroundActivityEventMap.size(); for (int i = 0; i < size; i++) { final String name = mLastForegroundActivityEventMap.keyAt(i); updateForegroundActivity(name, timeStamp, eventType); } break; case CONTINUE_PREVIOUS_DAY: mLastTimeUsed = timeStamp; mLastForegroundActivityEventMap.put(className, eventType); break; case FOREGROUND_SERVICE_STOP: case FOREGROUND_SERVICE_START: updateForegroundService(className, timeStamp, eventType); break; case ROLLOVER_FOREGROUND_SERVICE: // ROLLOVER_FOREGROUND_SERVICE means updating all foreground services. final int size2 = mLastForegroundServiceEventMap.size(); for (int i = 0; i < size2; i++) { final String name = mLastForegroundServiceEventMap.keyAt(i); updateForegroundService(name, timeStamp, eventType); } break; case CONTINUING_FOREGROUND_SERVICE: mLastTimeForegroundServiceUsed = timeStamp; mLastForegroundServiceEventMap.put(className, eventType); break; default: break; } mEndTimeStamp = timeStamp; if (eventType == MOVE_TO_FOREGROUND) { mLaunchCount += 1; } } @Override public int describeContents() { return 0; Loading @@ -220,7 +455,9 @@ public final class UsageStats implements Parcelable { dest.writeLong(mBeginTimeStamp); dest.writeLong(mEndTimeStamp); dest.writeLong(mLastTimeUsed); dest.writeLong(mLastTimeForegroundServiceUsed); dest.writeLong(mTotalTimeInForeground); dest.writeLong(mTotalTimeForegroundServiceUsed); dest.writeInt(mLaunchCount); dest.writeInt(mAppLaunchCount); dest.writeInt(mLastEvent); Loading @@ -239,6 +476,22 @@ public final class UsageStats implements Parcelable { } } dest.writeBundle(allCounts); final Bundle foregroundActivityEventBundle = new Bundle(); final int foregroundEventSize = mLastForegroundActivityEventMap.size(); for (int i = 0; i < foregroundEventSize; i++) { foregroundActivityEventBundle.putInt(mLastForegroundActivityEventMap.keyAt(i), mLastForegroundActivityEventMap.valueAt(i)); } dest.writeBundle(foregroundActivityEventBundle); final Bundle foregroundServiceEventBundle = new Bundle(); final int foregroundServiceEventSize = mLastForegroundServiceEventMap.size(); for (int i = 0; i < foregroundServiceEventSize; i++) { foregroundServiceEventBundle.putInt(mLastForegroundServiceEventMap.keyAt(i), mLastForegroundServiceEventMap.valueAt(i)); } dest.writeBundle(foregroundServiceEventBundle); } public static final Creator<UsageStats> CREATOR = new Creator<UsageStats>() { Loading @@ -249,7 +502,9 @@ public final class UsageStats implements Parcelable { stats.mBeginTimeStamp = in.readLong(); stats.mEndTimeStamp = in.readLong(); stats.mLastTimeUsed = in.readLong(); stats.mLastTimeForegroundServiceUsed = in.readLong(); stats.mTotalTimeInForeground = in.readLong(); stats.mTotalTimeForegroundServiceUsed = in.readLong(); stats.mLaunchCount = in.readInt(); stats.mAppLaunchCount = in.readInt(); stats.mLastEvent = in.readInt(); Loading @@ -272,9 +527,20 @@ public final class UsageStats implements Parcelable { } } } readBundleToEventMap(stats.mLastForegroundActivityEventMap, in.readBundle()); readBundleToEventMap(stats.mLastForegroundServiceEventMap, in.readBundle()); return stats; } private void readBundleToEventMap(ArrayMap<String, Integer> eventMap, Bundle bundle) { if (bundle != null) { for (String className : bundle.keySet()) { final int event = bundle.getInt(className); eventMap.put(className, event); } } } @Override public UsageStats[] newArray(int size) { return new UsageStats[size]; Loading core/java/android/app/usage/UsageStatsManager.java +4 −1 Original line number Diff line number Diff line Loading @@ -192,7 +192,10 @@ public final class UsageStatsManager { public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE = 0x000C; /** @hide */ public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_START = 0x000D; /** @hide */ public static final int REASON_SUB_USAGE_FOREGROUND_SERVICE_START = 0x000E; /** @hide */ public static final int REASON_SUB_USAGE_FOREGROUND_SERVICE_STOP = 0x000F; /** @hide */ public static final int REASON_SUB_PREDICTED_RESTORED = 0x0001; Loading core/proto/android/server/usagestatsservice.proto +6 −0 Original line number Diff line number Diff line Loading @@ -45,11 +45,15 @@ message IntervalStatsProto { optional string package = 1; // package_index contains the index + 1 of the package name in the string pool optional int32 package_index = 2; // Time attributes stored as an offset of the IntervalStats's beginTime. optional int64 last_time_active_ms = 3; optional int64 total_time_active_ms = 4; optional int32 last_event = 5; optional int32 app_launch_count = 6; repeated ChooserAction chooser_actions = 7; // Time attributes stored as an offset of the IntervalStats's beginTime. optional int64 last_time_service_used_ms = 8; optional int64 total_time_service_used_ms = 9; } // Stores the relevant information an IntervalStats will have about a Configuration Loading Loading @@ -86,6 +90,8 @@ message IntervalStatsProto { // stringpool contains all the package and class names used by UsageStats and Event // They will hold a number that is equal to the index + 1 of their string in the pool optional StringPool stringpool = 2; optional int32 major_version = 3; optional int32 minor_version = 4; // The following fields contain aggregated usage stats data optional CountAndTime interactive = 10; Loading Loading
api/current.txt +4 −0 Original line number Diff line number Diff line Loading @@ -7580,6 +7580,8 @@ package android.app.usage { method public java.lang.String getShortcutId(); method public long getTimeStamp(); field public static final int CONFIGURATION_CHANGE = 5; // 0x5 field public static final int FOREGROUND_SERVICE_START = 19; // 0x13 field public static final int FOREGROUND_SERVICE_STOP = 20; // 0x14 field public static final int KEYGUARD_HIDDEN = 18; // 0x12 field public static final int KEYGUARD_SHOWN = 17; // 0x11 field public static final int MOVE_TO_BACKGROUND = 2; // 0x2 Loading @@ -7597,9 +7599,11 @@ package android.app.usage { method public void add(android.app.usage.UsageStats); method public int describeContents(); method public long getFirstTimeStamp(); method public long getLastTimeForegroundServiceUsed(); method public long getLastTimeStamp(); method public long getLastTimeUsed(); method public java.lang.String getPackageName(); method public long getTotalTimeForegroundServiceUsed(); method public long getTotalTimeInForeground(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.usage.UsageStats> CREATOR;
core/java/android/app/usage/UsageEvents.java +44 −3 Original line number Diff line number Diff line Loading @@ -50,12 +50,20 @@ public final class UsageEvents implements Parcelable { public static final int NONE = 0; /** * An event type denoting that a component moved to the foreground. * An event type denoting that an {@link android.app.Activity} moved to the foreground. * This event has a package name and class name associated with it and can be retrieved * using {@link #getPackageName()} and {@link #getClassName()}. * If a package has multiple activities, this event is reported for each activity that moves * to foreground. */ public static final int MOVE_TO_FOREGROUND = 1; /** * An event type denoting that a component moved to the background. * An event type denoting that an {@link android.app.Activity} moved to the background. * This event has a package name and class name associated with it and can be retrieved * using {@link #getPackageName()} and {@link #getClassName()}. * If a package has multiple activities, this event is reported for each activity that moves * to background. */ public static final int MOVE_TO_BACKGROUND = 2; Loading Loading @@ -165,11 +173,44 @@ public final class UsageEvents implements Parcelable { */ public static final int KEYGUARD_HIDDEN = 18; /** * An event type denoting start of a foreground service. * This event has a package name and class name associated with it and can be retrieved * using {@link #getPackageName()} and {@link #getClassName()}. * If a package has multiple foreground services, this event is reported for each service * that is started. */ public static final int FOREGROUND_SERVICE_START = 19; /** * An event type denoting stop of a foreground service. * This event has a package name and class name associated with it and can be retrieved * using {@link #getPackageName()} and {@link #getClassName()}. * If a package has multiple foreground services, this event is reported for each service * that is stopped. */ public static final int FOREGROUND_SERVICE_STOP = 20; /** * An event type denoting that a foreground service is at started state at beginning of a * time interval. * This is effectively treated as a {@link #FOREGROUND_SERVICE_START}. * {@hide} */ public static final int CONTINUING_FOREGROUND_SERVICE = 21; /** * An event type denoting that a foreground service is at started state when the stats * rolled-over at the end of a time interval. * {@hide} */ public static final int ROLLOVER_FOREGROUND_SERVICE = 22; /** * Keep in sync with the greatest event type value. * @hide */ public static final int MAX_EVENT_TYPE = 18; public static final int MAX_EVENT_TYPE = 22; /** @hide */ public static final int FLAG_IS_PACKAGE_INSTANT_APP = 1 << 0; Loading
core/java/android/app/usage/UsageStats.java +271 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,15 @@ package android.app.usage; import static android.app.usage.UsageEvents.Event.CONTINUE_PREVIOUS_DAY; import static android.app.usage.UsageEvents.Event.CONTINUING_FOREGROUND_SERVICE; import static android.app.usage.UsageEvents.Event.END_OF_DAY; import static android.app.usage.UsageEvents.Event.FOREGROUND_SERVICE_START; import static android.app.usage.UsageEvents.Event.FOREGROUND_SERVICE_STOP; import static android.app.usage.UsageEvents.Event.MOVE_TO_BACKGROUND; import static android.app.usage.UsageEvents.Event.MOVE_TO_FOREGROUND; import static android.app.usage.UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.os.Bundle; Loading Loading @@ -48,18 +57,31 @@ public final class UsageStats implements Parcelable { public long mEndTimeStamp; /** * Last time used by the user with an explicit action (notification, activity launch). * Last time used by the user with an explicit action (notification, activity launch) * {@hide} */ @UnsupportedAppUsage public long mLastTimeUsed; /** * Total time this package's activity is in foreground. * {@hide} */ @UnsupportedAppUsage public long mTotalTimeInForeground; /** * Last time foreground service is started. * {@hide} */ public long mLastTimeForegroundServiceUsed; /** * Total time this package's foreground service is started. * {@hide} */ public long mTotalTimeForegroundServiceUsed; /** * {@hide} */ Loading @@ -71,16 +93,36 @@ public final class UsageStats implements Parcelable { */ public int mAppLaunchCount; /** /** Last activity MOVE_TO_FOREGROUND or MOVE_TO_BACKGROUND event. * {@hide} * @deprecated use {@link #mLastForegroundActivityEventMap} instead. */ @UnsupportedAppUsage @Deprecated public int mLastEvent; /** * If an activity is in foreground, it has one entry in this map. * When activity moves to background, it is removed from this map. * Key is activity class name. * Value is last time this activity MOVE_TO_FOREGROUND or MOVE_TO_BACKGROUND event. * {@hide} */ public ArrayMap<String, Integer> mLastForegroundActivityEventMap = new ArrayMap<>(); /** * If a foreground service is started, it has one entry in this map. * When a foreground service is stopped, it is removed from this map. * Key is foreground service class name. * Value is last foreground service FOREGROUND_SERVICE_START ot FOREGROUND_SERVICE_STOP event. * {@hide} */ public ArrayMap<String, ArrayMap<String, Integer>> mChooserCounts; public ArrayMap<String, Integer> mLastForegroundServiceEventMap = new ArrayMap<>(); /** * {@hide} */ public ArrayMap<String, ArrayMap<String, Integer>> mChooserCounts = new ArrayMap<>(); /** * {@hide} Loading @@ -93,10 +135,14 @@ public final class UsageStats implements Parcelable { mBeginTimeStamp = stats.mBeginTimeStamp; mEndTimeStamp = stats.mEndTimeStamp; mLastTimeUsed = stats.mLastTimeUsed; mLastTimeForegroundServiceUsed = stats.mLastTimeForegroundServiceUsed; mTotalTimeInForeground = stats.mTotalTimeInForeground; mTotalTimeForegroundServiceUsed = stats.mTotalTimeForegroundServiceUsed; mLaunchCount = stats.mLaunchCount; mAppLaunchCount = stats.mAppLaunchCount; mLastEvent = stats.mLastEvent; mLastForegroundActivityEventMap = stats.mLastForegroundActivityEventMap; mLastForegroundServiceEventMap = stats.mLastForegroundServiceEventMap; mChooserCounts = stats.mChooserCounts; } Loading Loading @@ -136,7 +182,7 @@ public final class UsageStats implements Parcelable { } /** * Get the last time this package was used, measured in milliseconds since the epoch. * Get the last time this package's activity was used, measured in milliseconds since the epoch. * <p/> * See {@link System#currentTimeMillis()}. */ Loading @@ -151,6 +197,23 @@ public final class UsageStats implements Parcelable { return mTotalTimeInForeground; } /** * Get the last time this package's foreground service was used, measured in milliseconds since * the epoch. * <p/> * See {@link System#currentTimeMillis()}. */ public long getLastTimeForegroundServiceUsed() { return mLastTimeForegroundServiceUsed; } /** * Get the total time this package's foreground services are started, measured in milliseconds. */ public long getTotalTimeForegroundServiceUsed() { return mTotalTimeForegroundServiceUsed; } /** * Returns the number of times the app was launched as an activity from outside of the app. * Excludes intra-app activity transitions. Loading @@ -161,6 +224,19 @@ public final class UsageStats implements Parcelable { return mAppLaunchCount; } private void mergeEventMap(ArrayMap<String, Integer> left, ArrayMap<String, Integer> right) { final int size = right.size(); for (int i = 0; i < size; i++) { final String className = right.keyAt(i); final Integer event = right.valueAt(i); if (left.containsKey(className)) { left.put(className, Math.max(left.get(className), event)); } else { left.put(className, event); } } } /** * Add the statistics from the right {@link UsageStats} to the left. The package name for * both {@link UsageStats} objects must be the same. Loading @@ -179,12 +255,16 @@ public final class UsageStats implements Parcelable { if (right.mBeginTimeStamp > mBeginTimeStamp) { // Even though incoming UsageStat begins after this one, its last time used fields // may somehow be empty or chronologically preceding the older UsageStat. mLastEvent = Math.max(mLastEvent, right.mLastEvent); mergeEventMap(mLastForegroundActivityEventMap, right.mLastForegroundActivityEventMap); mergeEventMap(mLastForegroundServiceEventMap, right.mLastForegroundServiceEventMap); mLastTimeUsed = Math.max(mLastTimeUsed, right.mLastTimeUsed); mLastTimeForegroundServiceUsed = Math.max(mLastTimeForegroundServiceUsed, right.mLastTimeForegroundServiceUsed); } mBeginTimeStamp = Math.min(mBeginTimeStamp, right.mBeginTimeStamp); mEndTimeStamp = Math.max(mEndTimeStamp, right.mEndTimeStamp); mTotalTimeInForeground += right.mTotalTimeInForeground; mTotalTimeForegroundServiceUsed += right.mTotalTimeForegroundServiceUsed; mLaunchCount += right.mLaunchCount; mAppLaunchCount += right.mAppLaunchCount; if (mChooserCounts == null) { Loading @@ -209,6 +289,161 @@ public final class UsageStats implements Parcelable { } } /** * Tell if an event indicate activity is in foreground or not. * @param event the activity event. * @return true if activity is in foreground, false otherwise. * @hide */ private boolean isActivityInForeground(int event) { return event == MOVE_TO_FOREGROUND || event == CONTINUE_PREVIOUS_DAY; } /** * Tell if an event indicate foreground sevice is started or not. * @param event the foreground service event. * @return true if foreground service is started, false if stopped. * @hide */ private boolean isForegroundServiceStarted(int event) { return event == FOREGROUND_SERVICE_START || event == CONTINUING_FOREGROUND_SERVICE; } /** * If any activity in foreground or any foreground service is started, the app is considered in * use. * @return true if in use, false otherwise. * @hide */ private boolean isAppInUse() { return !mLastForegroundActivityEventMap.isEmpty() || !mLastForegroundServiceEventMap.isEmpty(); } /** * Update by an event of an activity. * @param className className of the activity. * @param timeStamp timeStamp of the event. * @param eventType type of the event. * @hide */ private void updateForegroundActivity(String className, long timeStamp, int eventType) { if (eventType != MOVE_TO_BACKGROUND && eventType != MOVE_TO_FOREGROUND && eventType != END_OF_DAY) { return; } final Integer lastEvent = mLastForegroundActivityEventMap.get(className); if (lastEvent != null) { if (isActivityInForeground(lastEvent)) { if (timeStamp > mLastTimeUsed) { mTotalTimeInForeground += timeStamp - mLastTimeUsed; mLastTimeUsed = timeStamp; } } if (eventType == MOVE_TO_BACKGROUND) { mLastForegroundActivityEventMap.remove(className); } else { mLastForegroundActivityEventMap.put(className, eventType); } } else if (eventType == MOVE_TO_FOREGROUND) { if (!isAppInUse()) { mLastTimeUsed = timeStamp; } mLastForegroundActivityEventMap.put(className, eventType); } } /** * Update by an event of an foreground service. * @param className className of the foreground service. * @param timeStamp timeStamp of the event. * @param eventType type of the event. * @hide */ private void updateForegroundService(String className, long timeStamp, int eventType) { if (eventType != FOREGROUND_SERVICE_STOP && eventType != FOREGROUND_SERVICE_START && eventType != ROLLOVER_FOREGROUND_SERVICE) { return; } final Integer lastEvent = mLastForegroundServiceEventMap.get(className); if (lastEvent != null) { if (isForegroundServiceStarted(lastEvent)) { if (timeStamp > mLastTimeForegroundServiceUsed) { mTotalTimeForegroundServiceUsed += timeStamp - mLastTimeForegroundServiceUsed; mLastTimeForegroundServiceUsed = timeStamp; } } if (eventType == FOREGROUND_SERVICE_STOP) { mLastForegroundServiceEventMap.remove(className); } else { mLastForegroundServiceEventMap.put(className, eventType); } } else if (eventType == FOREGROUND_SERVICE_START) { if (!isAppInUse()) { mLastTimeForegroundServiceUsed = timeStamp; } mLastForegroundServiceEventMap.put(className, eventType); } } /** * Update the UsageStats by a activity or foreground service event. * @param className class name of a activity or foreground service, could be null to mark * END_OF_DAY or rollover. * @param timeStamp Epoch timestamp in milliseconds. * @param eventType event type as in {@link UsageEvents.Event} * @hide */ public void update(String className, long timeStamp, int eventType) { switch(eventType) { case MOVE_TO_BACKGROUND: case MOVE_TO_FOREGROUND: updateForegroundActivity(className, timeStamp, eventType); break; case END_OF_DAY: // END_OF_DAY means updating all activities. final int size = mLastForegroundActivityEventMap.size(); for (int i = 0; i < size; i++) { final String name = mLastForegroundActivityEventMap.keyAt(i); updateForegroundActivity(name, timeStamp, eventType); } break; case CONTINUE_PREVIOUS_DAY: mLastTimeUsed = timeStamp; mLastForegroundActivityEventMap.put(className, eventType); break; case FOREGROUND_SERVICE_STOP: case FOREGROUND_SERVICE_START: updateForegroundService(className, timeStamp, eventType); break; case ROLLOVER_FOREGROUND_SERVICE: // ROLLOVER_FOREGROUND_SERVICE means updating all foreground services. final int size2 = mLastForegroundServiceEventMap.size(); for (int i = 0; i < size2; i++) { final String name = mLastForegroundServiceEventMap.keyAt(i); updateForegroundService(name, timeStamp, eventType); } break; case CONTINUING_FOREGROUND_SERVICE: mLastTimeForegroundServiceUsed = timeStamp; mLastForegroundServiceEventMap.put(className, eventType); break; default: break; } mEndTimeStamp = timeStamp; if (eventType == MOVE_TO_FOREGROUND) { mLaunchCount += 1; } } @Override public int describeContents() { return 0; Loading @@ -220,7 +455,9 @@ public final class UsageStats implements Parcelable { dest.writeLong(mBeginTimeStamp); dest.writeLong(mEndTimeStamp); dest.writeLong(mLastTimeUsed); dest.writeLong(mLastTimeForegroundServiceUsed); dest.writeLong(mTotalTimeInForeground); dest.writeLong(mTotalTimeForegroundServiceUsed); dest.writeInt(mLaunchCount); dest.writeInt(mAppLaunchCount); dest.writeInt(mLastEvent); Loading @@ -239,6 +476,22 @@ public final class UsageStats implements Parcelable { } } dest.writeBundle(allCounts); final Bundle foregroundActivityEventBundle = new Bundle(); final int foregroundEventSize = mLastForegroundActivityEventMap.size(); for (int i = 0; i < foregroundEventSize; i++) { foregroundActivityEventBundle.putInt(mLastForegroundActivityEventMap.keyAt(i), mLastForegroundActivityEventMap.valueAt(i)); } dest.writeBundle(foregroundActivityEventBundle); final Bundle foregroundServiceEventBundle = new Bundle(); final int foregroundServiceEventSize = mLastForegroundServiceEventMap.size(); for (int i = 0; i < foregroundServiceEventSize; i++) { foregroundServiceEventBundle.putInt(mLastForegroundServiceEventMap.keyAt(i), mLastForegroundServiceEventMap.valueAt(i)); } dest.writeBundle(foregroundServiceEventBundle); } public static final Creator<UsageStats> CREATOR = new Creator<UsageStats>() { Loading @@ -249,7 +502,9 @@ public final class UsageStats implements Parcelable { stats.mBeginTimeStamp = in.readLong(); stats.mEndTimeStamp = in.readLong(); stats.mLastTimeUsed = in.readLong(); stats.mLastTimeForegroundServiceUsed = in.readLong(); stats.mTotalTimeInForeground = in.readLong(); stats.mTotalTimeForegroundServiceUsed = in.readLong(); stats.mLaunchCount = in.readInt(); stats.mAppLaunchCount = in.readInt(); stats.mLastEvent = in.readInt(); Loading @@ -272,9 +527,20 @@ public final class UsageStats implements Parcelable { } } } readBundleToEventMap(stats.mLastForegroundActivityEventMap, in.readBundle()); readBundleToEventMap(stats.mLastForegroundServiceEventMap, in.readBundle()); return stats; } private void readBundleToEventMap(ArrayMap<String, Integer> eventMap, Bundle bundle) { if (bundle != null) { for (String className : bundle.keySet()) { final int event = bundle.getInt(className); eventMap.put(className, event); } } } @Override public UsageStats[] newArray(int size) { return new UsageStats[size]; Loading
core/java/android/app/usage/UsageStatsManager.java +4 −1 Original line number Diff line number Diff line Loading @@ -192,7 +192,10 @@ public final class UsageStatsManager { public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE = 0x000C; /** @hide */ public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_START = 0x000D; /** @hide */ public static final int REASON_SUB_USAGE_FOREGROUND_SERVICE_START = 0x000E; /** @hide */ public static final int REASON_SUB_USAGE_FOREGROUND_SERVICE_STOP = 0x000F; /** @hide */ public static final int REASON_SUB_PREDICTED_RESTORED = 0x0001; Loading
core/proto/android/server/usagestatsservice.proto +6 −0 Original line number Diff line number Diff line Loading @@ -45,11 +45,15 @@ message IntervalStatsProto { optional string package = 1; // package_index contains the index + 1 of the package name in the string pool optional int32 package_index = 2; // Time attributes stored as an offset of the IntervalStats's beginTime. optional int64 last_time_active_ms = 3; optional int64 total_time_active_ms = 4; optional int32 last_event = 5; optional int32 app_launch_count = 6; repeated ChooserAction chooser_actions = 7; // Time attributes stored as an offset of the IntervalStats's beginTime. optional int64 last_time_service_used_ms = 8; optional int64 total_time_service_used_ms = 9; } // Stores the relevant information an IntervalStats will have about a Configuration Loading Loading @@ -86,6 +90,8 @@ message IntervalStatsProto { // stringpool contains all the package and class names used by UsageStats and Event // They will hold a number that is equal to the index + 1 of their string in the pool optional StringPool stringpool = 2; optional int32 major_version = 3; optional int32 minor_version = 4; // The following fields contain aggregated usage stats data optional CountAndTime interactive = 10; Loading