Loading api/system-current.txt +5 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,7 @@ package android { field public static final java.lang.String MOVE_PACKAGE = "android.permission.MOVE_PACKAGE"; field public static final java.lang.String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP"; field public static final java.lang.String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS"; field public static final java.lang.String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE"; field public static final java.lang.String OVERRIDE_WIFI_CONFIG = "android.permission.OVERRIDE_WIFI_CONFIG"; field public static final java.lang.String PACKAGE_USAGE_STATS = "android.permission.PACKAGE_USAGE_STATS"; field public static final java.lang.String PACKAGE_VERIFICATION_AGENT = "android.permission.PACKAGE_VERIFICATION_AGENT"; Loading Loading @@ -733,6 +734,10 @@ package android.app.usage { field public static final int SYSTEM_INTERACTION = 6; // 0x6 } public final class UsageStats implements android.os.Parcelable { method public int getAppLaunchCount(); } public final class UsageStatsManager { method public int getAppStandbyBucket(java.lang.String); method public java.util.Map<java.lang.String, java.lang.Integer> getAppStandbyBuckets(); Loading core/java/android/app/usage/UsageStats.java +20 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.app.usage; import android.annotation.SystemApi; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; Loading Loading @@ -58,6 +59,11 @@ public final class UsageStats implements Parcelable { */ public int mLaunchCount; /** * {@hide} */ public int mAppLaunchCount; /** * {@hide} */ Loading @@ -81,6 +87,7 @@ public final class UsageStats implements Parcelable { mLastTimeUsed = stats.mLastTimeUsed; mTotalTimeInForeground = stats.mTotalTimeInForeground; mLaunchCount = stats.mLaunchCount; mAppLaunchCount = stats.mAppLaunchCount; mLastEvent = stats.mLastEvent; mChooserCounts = stats.mChooserCounts; } Loading Loading @@ -136,6 +143,16 @@ public final class UsageStats implements Parcelable { return mTotalTimeInForeground; } /** * Returns the number of times the app was launched as an activity from outside of the app. * Excludes intra-app activity transitions. * @hide */ @SystemApi public int getAppLaunchCount() { return mAppLaunchCount; } /** * Add the statistics from the right {@link UsageStats} to the left. The package name for * both {@link UsageStats} objects must be the same. Loading @@ -161,6 +178,7 @@ public final class UsageStats implements Parcelable { mEndTimeStamp = Math.max(mEndTimeStamp, right.mEndTimeStamp); mTotalTimeInForeground += right.mTotalTimeInForeground; mLaunchCount += right.mLaunchCount; mAppLaunchCount += right.mAppLaunchCount; if (mChooserCounts == null) { mChooserCounts = right.mChooserCounts; } else if (right.mChooserCounts != null) { Loading Loading @@ -196,6 +214,7 @@ public final class UsageStats implements Parcelable { dest.writeLong(mLastTimeUsed); dest.writeLong(mTotalTimeInForeground); dest.writeInt(mLaunchCount); dest.writeInt(mAppLaunchCount); dest.writeInt(mLastEvent); Bundle allCounts = new Bundle(); if (mChooserCounts != null) { Loading Loading @@ -224,6 +243,7 @@ public final class UsageStats implements Parcelable { stats.mLastTimeUsed = in.readLong(); stats.mTotalTimeInForeground = in.readLong(); stats.mLaunchCount = in.readInt(); stats.mAppLaunchCount = in.readInt(); stats.mLastEvent = in.readInt(); Bundle allCounts = in.readBundle(); if (allCounts != null) { Loading core/java/android/app/usage/UsageStatsManager.java +18 −14 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.app.usage; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; Loading Loading @@ -518,26 +519,28 @@ public final class UsageStatsManager { /** * @hide * Register an app usage limit observer that receives a callback on the provided intent when * the sum of usages of apps in the packages array exceeds the timeLimit specified. The * the sum of usages of apps in the packages array exceeds the {@code timeLimit} specified. The * observer will automatically be unregistered when the time limit is reached and the intent * is delivered. * is delivered. Registering an {@code observerId} that was already registered will override * the previous one. * @param observerId A unique id associated with the group of apps to be monitored. There can * be multiple groups with common packages and different time limits. * @param packages The list of packages to observe for foreground activity time. Must include * at least one package. * @param packages The list of packages to observe for foreground activity time. Cannot be null * and must include at least one package. * @param timeLimit The total time the set of apps can be in the foreground before the * callbackIntent is delivered. Must be greater than 0. * @param timeUnit The unit for time specified in timeLimit. * @param timeUnit The unit for time specified in {@code timeLimit}. Cannot be null. * @param callbackIntent The PendingIntent that will be dispatched when the time limit is * exceeded by the group of apps. The delivered Intent will also contain * the extras {@link #EXTRA_OBSERVER_ID}, {@link #EXTRA_TIME_LIMIT} and * {@link #EXTRA_TIME_USED}. * @throws SecurityException if the caller doesn't have the PACKAGE_USAGE_STATS permission. * {@link #EXTRA_TIME_USED}. Cannot be null. * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission or * is not the profile owner of this user. */ @SystemApi @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void registerAppUsageObserver(int observerId, String[] packages, long timeLimit, TimeUnit timeUnit, PendingIntent callbackIntent) { @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) public void registerAppUsageObserver(int observerId, @NonNull String[] packages, long timeLimit, @NonNull TimeUnit timeUnit, @NonNull PendingIntent callbackIntent) { try { mService.registerAppUsageObserver(observerId, packages, timeUnit.toMillis(timeLimit), callbackIntent, mContext.getOpPackageName()); Loading @@ -547,14 +550,15 @@ public final class UsageStatsManager { /** * @hide * Unregister the app usage observer specified by the observerId. This will only apply to any * observer registered by this application. Unregistering an observer that was already * Unregister the app usage observer specified by the {@code observerId}. This will only apply * to any observer registered by this application. Unregistering an observer that was already * unregistered or never registered will have no effect. * @param observerId The id of the observer that was previously registered. * @throws SecurityException if the caller doesn't have the PACKAGE_USAGE_STATS permission. * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission or is * not the profile owner of this user. */ @SystemApi @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) public void unregisterAppUsageObserver(int observerId) { try { mService.unregisterAppUsageObserver(observerId, mContext.getOpPackageName()); Loading core/res/AndroidManifest.xml +5 −0 Original line number Diff line number Diff line Loading @@ -3290,6 +3290,11 @@ android:protectionLevel="signature|privileged|development|appop" /> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" /> <!-- @hide @SystemApi Allows an application to observe usage time of apps. The app can register for callbacks when apps reach a certain usage time limit, etc. --> <permission android:name="android.permission.OBSERVE_APP_USAGE" android:protectionLevel="signature|privileged" /> <!-- @hide @SystemApi Allows an application to change the app idle state of an app. <p>Not for use by third-party applications. --> <permission android:name="android.permission.CHANGE_APP_IDLE_STATE" Loading services/usage/java/com/android/server/usage/AppTimeLimitController.java +3 −18 Original line number Diff line number Diff line Loading @@ -71,16 +71,13 @@ public class AppTimeLimitController { /** The time when the current app came to the foreground */ private long currentForegroundedTime; /** The last app that was in the background */ private String lastBackgroundedPackage; /** Map from package name for quick lookup */ private ArrayMap<String, ArrayList<TimeLimitGroup>> packageMap = new ArrayMap<>(); /** Map of observerId to details of the time limit group */ private SparseArray<TimeLimitGroup> groups = new SparseArray<>(); UserData(@UserIdInt int userId) { private UserData(@UserIdInt int userId) { this.userId = userId; } } Loading Loading @@ -114,7 +111,7 @@ public class AppTimeLimitController { int userId; } class MyHandler extends Handler { private class MyHandler extends Handler { static final int MSG_CHECK_TIMEOUT = 1; static final int MSG_INFORM_LISTENER = 2; Loading Loading @@ -151,7 +148,7 @@ public class AppTimeLimitController { } /** Returns an existing UserData object for the given userId, or creates one */ UserData getOrCreateUserDataLocked(int userId) { private UserData getOrCreateUserDataLocked(int userId) { UserData userData = mUsers.get(userId); if (userData == null) { userData = new UserData(userId); Loading Loading @@ -258,12 +255,6 @@ public class AppTimeLimitController { user.currentForegroundedPackage = packageName; user.currentForegroundedTime = getUptimeMillis(); // Check if the last package that was backgrounded is the same as this one if (!TextUtils.equals(packageName, user.lastBackgroundedPackage)) { // TODO: Move this logic up to usage stats to persist there. incTotalLaunchesLocked(user, packageName); } // Check if any of the groups need to watch for this package maybeWatchForPackageLocked(user, packageName, user.currentForegroundedTime); } Loading @@ -279,7 +270,6 @@ public class AppTimeLimitController { public void moveToBackground(String packageName, String className, int userId) { synchronized (mLock) { UserData user = getOrCreateUserDataLocked(userId); user.lastBackgroundedPackage = packageName; if (!TextUtils.equals(user.currentForegroundedPackage, packageName)) { Slog.w(TAG, "Eh? Last foregrounded package = " + user.currentForegroundedPackage + " and now backgrounded = " + packageName); Loading Loading @@ -433,10 +423,6 @@ public class AppTimeLimitController { } } private void incTotalLaunchesLocked(UserData user, String packageName) { // TODO: Inform UsageStatsService and aggregate the counter per app } void dump(PrintWriter pw) { synchronized (mLock) { pw.println("\n App Time Limits"); Loading @@ -457,7 +443,6 @@ public class AppTimeLimitController { pw.println(); pw.print(" currentForegroundedPackage="); pw.println(user.currentForegroundedPackage); pw.print(" lastBackgroundedPackage="); pw.println(user.lastBackgroundedPackage); } } } Loading Loading
api/system-current.txt +5 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,7 @@ package android { field public static final java.lang.String MOVE_PACKAGE = "android.permission.MOVE_PACKAGE"; field public static final java.lang.String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP"; field public static final java.lang.String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS"; field public static final java.lang.String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE"; field public static final java.lang.String OVERRIDE_WIFI_CONFIG = "android.permission.OVERRIDE_WIFI_CONFIG"; field public static final java.lang.String PACKAGE_USAGE_STATS = "android.permission.PACKAGE_USAGE_STATS"; field public static final java.lang.String PACKAGE_VERIFICATION_AGENT = "android.permission.PACKAGE_VERIFICATION_AGENT"; Loading Loading @@ -733,6 +734,10 @@ package android.app.usage { field public static final int SYSTEM_INTERACTION = 6; // 0x6 } public final class UsageStats implements android.os.Parcelable { method public int getAppLaunchCount(); } public final class UsageStatsManager { method public int getAppStandbyBucket(java.lang.String); method public java.util.Map<java.lang.String, java.lang.Integer> getAppStandbyBuckets(); Loading
core/java/android/app/usage/UsageStats.java +20 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.app.usage; import android.annotation.SystemApi; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; Loading Loading @@ -58,6 +59,11 @@ public final class UsageStats implements Parcelable { */ public int mLaunchCount; /** * {@hide} */ public int mAppLaunchCount; /** * {@hide} */ Loading @@ -81,6 +87,7 @@ public final class UsageStats implements Parcelable { mLastTimeUsed = stats.mLastTimeUsed; mTotalTimeInForeground = stats.mTotalTimeInForeground; mLaunchCount = stats.mLaunchCount; mAppLaunchCount = stats.mAppLaunchCount; mLastEvent = stats.mLastEvent; mChooserCounts = stats.mChooserCounts; } Loading Loading @@ -136,6 +143,16 @@ public final class UsageStats implements Parcelable { return mTotalTimeInForeground; } /** * Returns the number of times the app was launched as an activity from outside of the app. * Excludes intra-app activity transitions. * @hide */ @SystemApi public int getAppLaunchCount() { return mAppLaunchCount; } /** * Add the statistics from the right {@link UsageStats} to the left. The package name for * both {@link UsageStats} objects must be the same. Loading @@ -161,6 +178,7 @@ public final class UsageStats implements Parcelable { mEndTimeStamp = Math.max(mEndTimeStamp, right.mEndTimeStamp); mTotalTimeInForeground += right.mTotalTimeInForeground; mLaunchCount += right.mLaunchCount; mAppLaunchCount += right.mAppLaunchCount; if (mChooserCounts == null) { mChooserCounts = right.mChooserCounts; } else if (right.mChooserCounts != null) { Loading Loading @@ -196,6 +214,7 @@ public final class UsageStats implements Parcelable { dest.writeLong(mLastTimeUsed); dest.writeLong(mTotalTimeInForeground); dest.writeInt(mLaunchCount); dest.writeInt(mAppLaunchCount); dest.writeInt(mLastEvent); Bundle allCounts = new Bundle(); if (mChooserCounts != null) { Loading Loading @@ -224,6 +243,7 @@ public final class UsageStats implements Parcelable { stats.mLastTimeUsed = in.readLong(); stats.mTotalTimeInForeground = in.readLong(); stats.mLaunchCount = in.readInt(); stats.mAppLaunchCount = in.readInt(); stats.mLastEvent = in.readInt(); Bundle allCounts = in.readBundle(); if (allCounts != null) { Loading
core/java/android/app/usage/UsageStatsManager.java +18 −14 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.app.usage; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; Loading Loading @@ -518,26 +519,28 @@ public final class UsageStatsManager { /** * @hide * Register an app usage limit observer that receives a callback on the provided intent when * the sum of usages of apps in the packages array exceeds the timeLimit specified. The * the sum of usages of apps in the packages array exceeds the {@code timeLimit} specified. The * observer will automatically be unregistered when the time limit is reached and the intent * is delivered. * is delivered. Registering an {@code observerId} that was already registered will override * the previous one. * @param observerId A unique id associated with the group of apps to be monitored. There can * be multiple groups with common packages and different time limits. * @param packages The list of packages to observe for foreground activity time. Must include * at least one package. * @param packages The list of packages to observe for foreground activity time. Cannot be null * and must include at least one package. * @param timeLimit The total time the set of apps can be in the foreground before the * callbackIntent is delivered. Must be greater than 0. * @param timeUnit The unit for time specified in timeLimit. * @param timeUnit The unit for time specified in {@code timeLimit}. Cannot be null. * @param callbackIntent The PendingIntent that will be dispatched when the time limit is * exceeded by the group of apps. The delivered Intent will also contain * the extras {@link #EXTRA_OBSERVER_ID}, {@link #EXTRA_TIME_LIMIT} and * {@link #EXTRA_TIME_USED}. * @throws SecurityException if the caller doesn't have the PACKAGE_USAGE_STATS permission. * {@link #EXTRA_TIME_USED}. Cannot be null. * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission or * is not the profile owner of this user. */ @SystemApi @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void registerAppUsageObserver(int observerId, String[] packages, long timeLimit, TimeUnit timeUnit, PendingIntent callbackIntent) { @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) public void registerAppUsageObserver(int observerId, @NonNull String[] packages, long timeLimit, @NonNull TimeUnit timeUnit, @NonNull PendingIntent callbackIntent) { try { mService.registerAppUsageObserver(observerId, packages, timeUnit.toMillis(timeLimit), callbackIntent, mContext.getOpPackageName()); Loading @@ -547,14 +550,15 @@ public final class UsageStatsManager { /** * @hide * Unregister the app usage observer specified by the observerId. This will only apply to any * observer registered by this application. Unregistering an observer that was already * Unregister the app usage observer specified by the {@code observerId}. This will only apply * to any observer registered by this application. Unregistering an observer that was already * unregistered or never registered will have no effect. * @param observerId The id of the observer that was previously registered. * @throws SecurityException if the caller doesn't have the PACKAGE_USAGE_STATS permission. * @throws SecurityException if the caller doesn't have the OBSERVE_APP_USAGE permission or is * not the profile owner of this user. */ @SystemApi @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) public void unregisterAppUsageObserver(int observerId) { try { mService.unregisterAppUsageObserver(observerId, mContext.getOpPackageName()); Loading
core/res/AndroidManifest.xml +5 −0 Original line number Diff line number Diff line Loading @@ -3290,6 +3290,11 @@ android:protectionLevel="signature|privileged|development|appop" /> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" /> <!-- @hide @SystemApi Allows an application to observe usage time of apps. The app can register for callbacks when apps reach a certain usage time limit, etc. --> <permission android:name="android.permission.OBSERVE_APP_USAGE" android:protectionLevel="signature|privileged" /> <!-- @hide @SystemApi Allows an application to change the app idle state of an app. <p>Not for use by third-party applications. --> <permission android:name="android.permission.CHANGE_APP_IDLE_STATE" Loading
services/usage/java/com/android/server/usage/AppTimeLimitController.java +3 −18 Original line number Diff line number Diff line Loading @@ -71,16 +71,13 @@ public class AppTimeLimitController { /** The time when the current app came to the foreground */ private long currentForegroundedTime; /** The last app that was in the background */ private String lastBackgroundedPackage; /** Map from package name for quick lookup */ private ArrayMap<String, ArrayList<TimeLimitGroup>> packageMap = new ArrayMap<>(); /** Map of observerId to details of the time limit group */ private SparseArray<TimeLimitGroup> groups = new SparseArray<>(); UserData(@UserIdInt int userId) { private UserData(@UserIdInt int userId) { this.userId = userId; } } Loading Loading @@ -114,7 +111,7 @@ public class AppTimeLimitController { int userId; } class MyHandler extends Handler { private class MyHandler extends Handler { static final int MSG_CHECK_TIMEOUT = 1; static final int MSG_INFORM_LISTENER = 2; Loading Loading @@ -151,7 +148,7 @@ public class AppTimeLimitController { } /** Returns an existing UserData object for the given userId, or creates one */ UserData getOrCreateUserDataLocked(int userId) { private UserData getOrCreateUserDataLocked(int userId) { UserData userData = mUsers.get(userId); if (userData == null) { userData = new UserData(userId); Loading Loading @@ -258,12 +255,6 @@ public class AppTimeLimitController { user.currentForegroundedPackage = packageName; user.currentForegroundedTime = getUptimeMillis(); // Check if the last package that was backgrounded is the same as this one if (!TextUtils.equals(packageName, user.lastBackgroundedPackage)) { // TODO: Move this logic up to usage stats to persist there. incTotalLaunchesLocked(user, packageName); } // Check if any of the groups need to watch for this package maybeWatchForPackageLocked(user, packageName, user.currentForegroundedTime); } Loading @@ -279,7 +270,6 @@ public class AppTimeLimitController { public void moveToBackground(String packageName, String className, int userId) { synchronized (mLock) { UserData user = getOrCreateUserDataLocked(userId); user.lastBackgroundedPackage = packageName; if (!TextUtils.equals(user.currentForegroundedPackage, packageName)) { Slog.w(TAG, "Eh? Last foregrounded package = " + user.currentForegroundedPackage + " and now backgrounded = " + packageName); Loading Loading @@ -433,10 +423,6 @@ public class AppTimeLimitController { } } private void incTotalLaunchesLocked(UserData user, String packageName) { // TODO: Inform UsageStatsService and aggregate the counter per app } void dump(PrintWriter pw) { synchronized (mLock) { pw.println("\n App Time Limits"); Loading @@ -457,7 +443,6 @@ public class AppTimeLimitController { pw.println(); pw.print(" currentForegroundedPackage="); pw.println(user.currentForegroundedPackage); pw.print(" lastBackgroundedPackage="); pw.println(user.lastBackgroundedPackage); } } } Loading