Loading core/java/android/app/usage/IUsageStatsManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ interface IUsageStatsManager { in PendingIntent sessionEndCallbackIntent, String callingPackage); void unregisterUsageSessionObserver(int sessionObserverId, String callingPackage); void registerAppUsageLimitObserver(int observerId, in String[] packages, long timeLimitMs, long timeRemainingMs, in PendingIntent callback, String callingPackage); long timeUsedMs, in PendingIntent callback, String callingPackage); void unregisterAppUsageLimitObserver(int observerId, String callingPackage); void reportUsageStart(in IBinder activity, String token, String callingPackage); void reportPastUsageStart(in IBinder activity, String token, long timeAgoMs, Loading core/java/android/app/usage/UsageStatsManager.java +10 −9 Original line number Diff line number Diff line Loading @@ -747,7 +747,7 @@ public final class UsageStatsManager { */ @Deprecated @UnsupportedAppUsage // STOPSHIP b/126917290: remove this method once ag/6591106 is merged and it's not being used. // STOPSHIP b/126917290: remove this method once b/126926550 is fixed. public void registerAppUsageLimitObserver(int observerId, @NonNull String[] observedEntities, long timeLimit, @NonNull TimeUnit timeUnit, @Nullable PendingIntent callbackIntent) { final Duration timeLimitDuration = Duration.ofMillis(timeUnit.toMillis(timeLimit)); Loading Loading @@ -782,16 +782,17 @@ public final class UsageStatsManager { * null and must include at least one package or token. * @param timeLimit The total time the set of apps can be in the foreground before the * {@code callbackIntent} is delivered. Must be at least one minute. * @param timeRemaining The remaining time the set of apps can be in the foreground before the * {@code callbackIntent} is delivered. Must be greater than * {@code timeLimit}. Note: a limit of 0 can be set to indicate that the * user has already exhausted the limit for a group, in which case, * the given {@code callbackIntent} will be ignored. * @param timeUsed The time that has already been used by the set of apps in * {@code observedEntities}. Note: a time used equal to or greater than * {@code timeLimit} can be set to indicate that the user has already exhausted * the limit for a group, in which case, the given {@code callbackIntent} will * be ignored. * @param callbackIntent The PendingIntent that will be dispatched when the usage 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}. Cannot be {@code null} unless the observer is * being registered with a {@code timeRemaining} of 0. * being registered with a {@code timeUsed} equal to or greater than * {@code timeLimit}. * @throws SecurityException if the caller doesn't have both SUSPEND_APPS and OBSERVE_APP_USAGE * permissions. * @hide Loading @@ -801,11 +802,11 @@ public final class UsageStatsManager { android.Manifest.permission.SUSPEND_APPS, android.Manifest.permission.OBSERVE_APP_USAGE}) public void registerAppUsageLimitObserver(int observerId, @NonNull String[] observedEntities, @NonNull Duration timeLimit, @NonNull Duration timeRemaining, @NonNull Duration timeLimit, @NonNull Duration timeUsed, @Nullable PendingIntent callbackIntent) { try { mService.registerAppUsageLimitObserver(observerId, observedEntities, timeLimit.toMillis(), timeRemaining.toMillis(), callbackIntent, timeLimit.toMillis(), timeUsed.toMillis(), callbackIntent, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); Loading services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java +39 −39 Original line number Diff line number Diff line Loading @@ -175,9 +175,9 @@ public class AppTimeLimitControllerTests { /** Verify app usage limit observer is added */ @Test public void testAppUsageLimitObserver_AddObserver() { addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1)); addAppUsageLimitObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, 0); assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID2)); assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1)); } Loading @@ -203,7 +203,7 @@ public class AppTimeLimitControllerTests { /** Verify app usage limit observer is removed */ @Test public void testAppUsageLimitObserver_RemoveObserver() { addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1)); mController.removeAppUsageLimitObserver(UID, OBS_ID1, USER_ID); assertFalse("Observer wasn't removed", hasAppUsageLimitObserver(UID, OBS_ID1)); Loading Loading @@ -290,9 +290,9 @@ public class AppTimeLimitControllerTests { /** Re-adding an observer should result in only one copy */ @Test public void testAppUsageLimitObserver_ObserverReAdd() { addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1)); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_10_MIN, TIME_10_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_10_MIN, 0); assertTrue("Observer wasn't added", getAppUsageLimitObserver(UID, OBS_ID1).getTimeLimitMs() == TIME_10_MIN); mController.removeAppUsageLimitObserver(UID, OBS_ID1, USER_ID); Loading @@ -304,7 +304,7 @@ public class AppTimeLimitControllerTests { public void testAllObservers_ExclusiveObserverIds() { addAppUsageObserver(OBS_ID1, GROUP1, TIME_10_MIN); addUsageSessionObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_1_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_10_MIN, TIME_10_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_10_MIN, 0); assertTrue("Observer wasn't added", hasAppUsageObserver(UID, OBS_ID1)); assertTrue("Observer wasn't added", hasUsageSessionObserver(UID, OBS_ID1)); assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1)); Loading Loading @@ -396,7 +396,7 @@ public class AppTimeLimitControllerTests { @Test public void testAppUsageLimitObserver_Accumulation() throws Exception { setTime(0L); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); startUsage(PKG_SOC1); // Add 10 mins setTime(TIME_10_MIN); Loading Loading @@ -456,7 +456,7 @@ public class AppTimeLimitControllerTests { @Test public void testAppUsageLimitObserver_TimeoutOtherApp() throws Exception { setTime(0L); addAppUsageLimitObserver(OBS_ID1, GROUP1, 4_000L, 4_000L); addAppUsageLimitObserver(OBS_ID1, GROUP1, 4_000L, 0); startUsage(PKG_SOC2); assertFalse(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS)); setTime(6_000L); Loading Loading @@ -498,7 +498,7 @@ public class AppTimeLimitControllerTests { @Test public void testAppUsageLimitObserver_Timeout() throws Exception { setTime(0L); addAppUsageLimitObserver(OBS_ID1, GROUP1, 4_000L, 4_000L); addAppUsageLimitObserver(OBS_ID1, GROUP1, 4_000L, 0); startUsage(PKG_SOC1); setTime(6_000L); assertTrue(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS)); Loading Loading @@ -551,7 +551,7 @@ public class AppTimeLimitControllerTests { setTime(TIME_10_MIN); startUsage(PKG_GAME1); setTime(TIME_30_MIN); addAppUsageLimitObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, 0); setTime(TIME_30_MIN + TIME_10_MIN); stopUsage(PKG_GAME1); assertFalse(mLimitReachedLatch.await(1_000L, TimeUnit.MILLISECONDS)); Loading Loading @@ -612,7 +612,7 @@ public class AppTimeLimitControllerTests { startUsage(PKG_SOC1); setTime(TIME_10_MIN); // 10 second time limit addAppUsageLimitObserver(OBS_ID1, GROUP_SOC, 10_000L, 10_000L); addAppUsageLimitObserver(OBS_ID1, GROUP_SOC, 10_000L, 0); setTime(TIME_10_MIN + 5_000L); // Shouldn't call back in 6 seconds assertFalse(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS)); Loading Loading @@ -692,23 +692,23 @@ public class AppTimeLimitControllerTests { public void testAppUsageLimitObserver_MaxObserverLimit() throws Exception { boolean receivedException = false; int ANOTHER_UID = UID + 1; addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID2, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID3, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID4, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID5, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID6, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID7, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID8, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID9, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID10, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID2, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID3, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID4, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID5, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID6, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID7, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID8, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID9, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID10, GROUP1, TIME_30_MIN, 0); // Readding an observer should not cause an IllegalStateException addAppUsageLimitObserver(OBS_ID5, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID5, GROUP1, TIME_30_MIN, 0); // Adding an observer for a different uid shouldn't cause an IllegalStateException mController.addAppUsageLimitObserver( ANOTHER_UID, OBS_ID11, GROUP1, TIME_30_MIN, TIME_30_MIN, null, USER_ID); ANOTHER_UID, OBS_ID11, GROUP1, TIME_30_MIN, 0, null, USER_ID); try { addAppUsageLimitObserver(OBS_ID11, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID11, GROUP1, TIME_30_MIN, 0); } catch (IllegalStateException ise) { receivedException = true; } Loading Loading @@ -748,9 +748,9 @@ public class AppTimeLimitControllerTests { public void testAppUsageLimitObserver_MinimumTimeLimit() throws Exception { boolean receivedException = false; // adding an observer with a one minute time limit should not cause an exception addAppUsageLimitObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT, MIN_TIME_LIMIT); addAppUsageLimitObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT, 0); try { addAppUsageLimitObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT - 1, MIN_TIME_LIMIT - 1); addAppUsageLimitObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT - 1, 0); } catch (IllegalArgumentException iae) { receivedException = true; } Loading Loading @@ -807,7 +807,7 @@ public class AppTimeLimitControllerTests { @Test public void testAppUsageLimitObserver_ConcurrentUsage() throws Exception { setTime(0L); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); AppTimeLimitController.UsageGroup group = getAppUsageLimitObserver(UID, OBS_ID1); startUsage(PKG_SOC1); // Add 10 mins Loading Loading @@ -967,7 +967,7 @@ public class AppTimeLimitControllerTests { /** Verify app usage limit observer added correctly reports its total usage limit */ @Test public void testAppUsageLimitObserver_GetTotalUsageLimit() { addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); AppTimeLimitController.AppUsageLimitGroup group = getAppUsageLimitObserver(UID, OBS_ID1); assertNotNull("Observer wasn't added", group); assertEquals("Observer didn't correctly report total usage limit", Loading @@ -978,7 +978,7 @@ public class AppTimeLimitControllerTests { @Test public void testAppUsageLimitObserver_GetUsageRemaining() { setTime(0L); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); startUsage(PKG_SOC1); setTime(TIME_10_MIN); stopUsage(PKG_SOC1); Loading @@ -993,8 +993,8 @@ public class AppTimeLimitControllerTests { */ @Test public void testAppUsageLimitObserver_GetAppUsageLimit() { addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, TIME_10_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, 0); UsageStatsManagerInternal.AppUsageLimitData group = getAppUsageLimit(PKG_SOC1); assertEquals("Observer with the smallest usage limit remaining wasn't returned", TIME_10_MIN, group.getTotalUsageLimit()); Loading @@ -1006,8 +1006,8 @@ public class AppTimeLimitControllerTests { @Test public void testAppUsageLimitObserver_GetAppUsageLimitUsed() { setTime(0L); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, TIME_10_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, 0); startUsage(PKG_GAME1); setTime(TIME_10_MIN * 2 + TIME_1_MIN); stopUsage(PKG_GAME1); Loading @@ -1024,8 +1024,8 @@ public class AppTimeLimitControllerTests { @Test public void testAppUsageLimitObserver_GetAppUsageLimitAllUsed() { setTime(0L); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, TIME_10_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, 0); startUsage(PKG_SOC1); setTime(TIME_10_MIN); stopUsage(PKG_SOC1); Loading @@ -1046,10 +1046,10 @@ public class AppTimeLimitControllerTests { } } /** Verify that a limit of 0 is allowed for the special case of re-registering an observer. */ /** Verify that timeUsed can be the same as timeLimit (for re-registering observers). */ @Test public void testAppUsageLimitObserver_ZeroTimeRemainingIsAllowed() { addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_1_MIN, 0); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_1_MIN, TIME_1_MIN); AppTimeLimitController.AppUsageLimitGroup group = getAppUsageLimitObserver(UID, OBS_ID1); assertNotNull("Observer wasn't added", group); assertEquals("Usage remaining was not 0.", 0, group.getUsageRemaining()); Loading Loading @@ -1078,8 +1078,8 @@ public class AppTimeLimitControllerTests { } private void addAppUsageLimitObserver(int observerId, String[] packages, long timeLimit, long timeRemaining) { mController.addAppUsageLimitObserver(UID, observerId, packages, timeLimit, timeRemaining, long timeUsed) { mController.addAppUsageLimitObserver(UID, observerId, packages, timeLimit, timeUsed, null, USER_ID); } Loading services/usage/java/com/android/server/usage/AppTimeLimitController.java +4 −4 Original line number Diff line number Diff line Loading @@ -511,10 +511,10 @@ public class AppTimeLimitController { class AppUsageLimitGroup extends UsageGroup { public AppUsageLimitGroup(UserData user, ObserverAppData observerApp, int observerId, String[] observed, long timeLimitMs, long timeRemainingMs, String[] observed, long timeLimitMs, long timeUsedMs, PendingIntent limitReachedCallback) { super(user, observerApp, observerId, observed, timeLimitMs, limitReachedCallback); mUsageTimeMs = timeLimitMs - timeRemainingMs; mUsageTimeMs = timeUsedMs; } @Override Loading Loading @@ -841,7 +841,7 @@ public class AppTimeLimitController { * Existing app usage limit observer with the same observerId will be removed. */ public void addAppUsageLimitObserver(int requestingUid, int observerId, String[] observed, long timeLimit, long timeRemaining, PendingIntent callbackIntent, long timeLimit, long timeUsed, PendingIntent callbackIntent, @UserIdInt int userId) { if (timeLimit < getMinTimeLimit()) { throw new IllegalArgumentException("Time limit must be >= " + getMinTimeLimit()); Loading @@ -861,7 +861,7 @@ public class AppTimeLimitController { "Too many app usage observers added by uid " + requestingUid); } group = new AppUsageLimitGroup(user, observerApp, observerId, observed, timeLimit, timeRemaining, timeRemaining == 0L ? null : callbackIntent); timeUsed, timeUsed >= timeLimit ? null : callbackIntent); observerApp.appUsageLimitGroups.append(observerId, group); if (DEBUG) { Loading services/usage/java/com/android/server/usage/UsageStatsService.java +5 −9 Original line number Diff line number Diff line Loading @@ -1399,7 +1399,7 @@ public class UsageStatsService extends SystemService implements @Override public void registerAppUsageLimitObserver(int observerId, String[] packages, long timeLimitMs, long timeRemainingMs, PendingIntent callbackIntent, long timeLimitMs, long timeUsedMs, PendingIntent callbackIntent, String callingPackage) { if (!hasPermissions(callingPackage, Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE)) { Loading @@ -1410,11 +1410,7 @@ public class UsageStatsService extends SystemService implements if (packages == null || packages.length == 0) { throw new IllegalArgumentException("Must specify at least one package"); } if (timeRemainingMs > timeLimitMs) { throw new IllegalArgumentException( "Remaining time can't be greater than total time."); } if (callbackIntent == null && timeRemainingMs != 0L) { if (callbackIntent == null && timeUsedMs < timeLimitMs) { throw new NullPointerException("callbackIntent can't be null"); } final int callingUid = Binder.getCallingUid(); Loading @@ -1422,7 +1418,7 @@ public class UsageStatsService extends SystemService implements final long token = Binder.clearCallingIdentity(); try { UsageStatsService.this.registerAppUsageLimitObserver(callingUid, observerId, packages, timeLimitMs, timeRemainingMs, callbackIntent, userId); packages, timeLimitMs, timeUsedMs, callbackIntent, userId); } finally { Binder.restoreCallingIdentity(token); } Loading Loading @@ -1550,9 +1546,9 @@ public class UsageStatsService extends SystemService implements } void registerAppUsageLimitObserver(int callingUid, int observerId, String[] packages, long timeLimitMs, long timeRemainingMs, PendingIntent callbackIntent, int userId) { long timeLimitMs, long timeUsedMs, PendingIntent callbackIntent, int userId) { mAppTimeLimit.addAppUsageLimitObserver(callingUid, observerId, packages, timeLimitMs, timeRemainingMs, callbackIntent, userId); timeLimitMs, timeUsedMs, callbackIntent, userId); } void unregisterAppUsageLimitObserver(int callingUid, int observerId, int userId) { Loading Loading
core/java/android/app/usage/IUsageStatsManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ interface IUsageStatsManager { in PendingIntent sessionEndCallbackIntent, String callingPackage); void unregisterUsageSessionObserver(int sessionObserverId, String callingPackage); void registerAppUsageLimitObserver(int observerId, in String[] packages, long timeLimitMs, long timeRemainingMs, in PendingIntent callback, String callingPackage); long timeUsedMs, in PendingIntent callback, String callingPackage); void unregisterAppUsageLimitObserver(int observerId, String callingPackage); void reportUsageStart(in IBinder activity, String token, String callingPackage); void reportPastUsageStart(in IBinder activity, String token, long timeAgoMs, Loading
core/java/android/app/usage/UsageStatsManager.java +10 −9 Original line number Diff line number Diff line Loading @@ -747,7 +747,7 @@ public final class UsageStatsManager { */ @Deprecated @UnsupportedAppUsage // STOPSHIP b/126917290: remove this method once ag/6591106 is merged and it's not being used. // STOPSHIP b/126917290: remove this method once b/126926550 is fixed. public void registerAppUsageLimitObserver(int observerId, @NonNull String[] observedEntities, long timeLimit, @NonNull TimeUnit timeUnit, @Nullable PendingIntent callbackIntent) { final Duration timeLimitDuration = Duration.ofMillis(timeUnit.toMillis(timeLimit)); Loading Loading @@ -782,16 +782,17 @@ public final class UsageStatsManager { * null and must include at least one package or token. * @param timeLimit The total time the set of apps can be in the foreground before the * {@code callbackIntent} is delivered. Must be at least one minute. * @param timeRemaining The remaining time the set of apps can be in the foreground before the * {@code callbackIntent} is delivered. Must be greater than * {@code timeLimit}. Note: a limit of 0 can be set to indicate that the * user has already exhausted the limit for a group, in which case, * the given {@code callbackIntent} will be ignored. * @param timeUsed The time that has already been used by the set of apps in * {@code observedEntities}. Note: a time used equal to or greater than * {@code timeLimit} can be set to indicate that the user has already exhausted * the limit for a group, in which case, the given {@code callbackIntent} will * be ignored. * @param callbackIntent The PendingIntent that will be dispatched when the usage 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}. Cannot be {@code null} unless the observer is * being registered with a {@code timeRemaining} of 0. * being registered with a {@code timeUsed} equal to or greater than * {@code timeLimit}. * @throws SecurityException if the caller doesn't have both SUSPEND_APPS and OBSERVE_APP_USAGE * permissions. * @hide Loading @@ -801,11 +802,11 @@ public final class UsageStatsManager { android.Manifest.permission.SUSPEND_APPS, android.Manifest.permission.OBSERVE_APP_USAGE}) public void registerAppUsageLimitObserver(int observerId, @NonNull String[] observedEntities, @NonNull Duration timeLimit, @NonNull Duration timeRemaining, @NonNull Duration timeLimit, @NonNull Duration timeUsed, @Nullable PendingIntent callbackIntent) { try { mService.registerAppUsageLimitObserver(observerId, observedEntities, timeLimit.toMillis(), timeRemaining.toMillis(), callbackIntent, timeLimit.toMillis(), timeUsed.toMillis(), callbackIntent, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); Loading
services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java +39 −39 Original line number Diff line number Diff line Loading @@ -175,9 +175,9 @@ public class AppTimeLimitControllerTests { /** Verify app usage limit observer is added */ @Test public void testAppUsageLimitObserver_AddObserver() { addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1)); addAppUsageLimitObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, 0); assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID2)); assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1)); } Loading @@ -203,7 +203,7 @@ public class AppTimeLimitControllerTests { /** Verify app usage limit observer is removed */ @Test public void testAppUsageLimitObserver_RemoveObserver() { addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1)); mController.removeAppUsageLimitObserver(UID, OBS_ID1, USER_ID); assertFalse("Observer wasn't removed", hasAppUsageLimitObserver(UID, OBS_ID1)); Loading Loading @@ -290,9 +290,9 @@ public class AppTimeLimitControllerTests { /** Re-adding an observer should result in only one copy */ @Test public void testAppUsageLimitObserver_ObserverReAdd() { addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1)); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_10_MIN, TIME_10_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_10_MIN, 0); assertTrue("Observer wasn't added", getAppUsageLimitObserver(UID, OBS_ID1).getTimeLimitMs() == TIME_10_MIN); mController.removeAppUsageLimitObserver(UID, OBS_ID1, USER_ID); Loading @@ -304,7 +304,7 @@ public class AppTimeLimitControllerTests { public void testAllObservers_ExclusiveObserverIds() { addAppUsageObserver(OBS_ID1, GROUP1, TIME_10_MIN); addUsageSessionObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_1_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_10_MIN, TIME_10_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_10_MIN, 0); assertTrue("Observer wasn't added", hasAppUsageObserver(UID, OBS_ID1)); assertTrue("Observer wasn't added", hasUsageSessionObserver(UID, OBS_ID1)); assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1)); Loading Loading @@ -396,7 +396,7 @@ public class AppTimeLimitControllerTests { @Test public void testAppUsageLimitObserver_Accumulation() throws Exception { setTime(0L); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); startUsage(PKG_SOC1); // Add 10 mins setTime(TIME_10_MIN); Loading Loading @@ -456,7 +456,7 @@ public class AppTimeLimitControllerTests { @Test public void testAppUsageLimitObserver_TimeoutOtherApp() throws Exception { setTime(0L); addAppUsageLimitObserver(OBS_ID1, GROUP1, 4_000L, 4_000L); addAppUsageLimitObserver(OBS_ID1, GROUP1, 4_000L, 0); startUsage(PKG_SOC2); assertFalse(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS)); setTime(6_000L); Loading Loading @@ -498,7 +498,7 @@ public class AppTimeLimitControllerTests { @Test public void testAppUsageLimitObserver_Timeout() throws Exception { setTime(0L); addAppUsageLimitObserver(OBS_ID1, GROUP1, 4_000L, 4_000L); addAppUsageLimitObserver(OBS_ID1, GROUP1, 4_000L, 0); startUsage(PKG_SOC1); setTime(6_000L); assertTrue(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS)); Loading Loading @@ -551,7 +551,7 @@ public class AppTimeLimitControllerTests { setTime(TIME_10_MIN); startUsage(PKG_GAME1); setTime(TIME_30_MIN); addAppUsageLimitObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, 0); setTime(TIME_30_MIN + TIME_10_MIN); stopUsage(PKG_GAME1); assertFalse(mLimitReachedLatch.await(1_000L, TimeUnit.MILLISECONDS)); Loading Loading @@ -612,7 +612,7 @@ public class AppTimeLimitControllerTests { startUsage(PKG_SOC1); setTime(TIME_10_MIN); // 10 second time limit addAppUsageLimitObserver(OBS_ID1, GROUP_SOC, 10_000L, 10_000L); addAppUsageLimitObserver(OBS_ID1, GROUP_SOC, 10_000L, 0); setTime(TIME_10_MIN + 5_000L); // Shouldn't call back in 6 seconds assertFalse(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS)); Loading Loading @@ -692,23 +692,23 @@ public class AppTimeLimitControllerTests { public void testAppUsageLimitObserver_MaxObserverLimit() throws Exception { boolean receivedException = false; int ANOTHER_UID = UID + 1; addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID2, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID3, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID4, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID5, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID6, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID7, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID8, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID9, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID10, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID2, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID3, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID4, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID5, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID6, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID7, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID8, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID9, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID10, GROUP1, TIME_30_MIN, 0); // Readding an observer should not cause an IllegalStateException addAppUsageLimitObserver(OBS_ID5, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID5, GROUP1, TIME_30_MIN, 0); // Adding an observer for a different uid shouldn't cause an IllegalStateException mController.addAppUsageLimitObserver( ANOTHER_UID, OBS_ID11, GROUP1, TIME_30_MIN, TIME_30_MIN, null, USER_ID); ANOTHER_UID, OBS_ID11, GROUP1, TIME_30_MIN, 0, null, USER_ID); try { addAppUsageLimitObserver(OBS_ID11, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID11, GROUP1, TIME_30_MIN, 0); } catch (IllegalStateException ise) { receivedException = true; } Loading Loading @@ -748,9 +748,9 @@ public class AppTimeLimitControllerTests { public void testAppUsageLimitObserver_MinimumTimeLimit() throws Exception { boolean receivedException = false; // adding an observer with a one minute time limit should not cause an exception addAppUsageLimitObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT, MIN_TIME_LIMIT); addAppUsageLimitObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT, 0); try { addAppUsageLimitObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT - 1, MIN_TIME_LIMIT - 1); addAppUsageLimitObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT - 1, 0); } catch (IllegalArgumentException iae) { receivedException = true; } Loading Loading @@ -807,7 +807,7 @@ public class AppTimeLimitControllerTests { @Test public void testAppUsageLimitObserver_ConcurrentUsage() throws Exception { setTime(0L); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); AppTimeLimitController.UsageGroup group = getAppUsageLimitObserver(UID, OBS_ID1); startUsage(PKG_SOC1); // Add 10 mins Loading Loading @@ -967,7 +967,7 @@ public class AppTimeLimitControllerTests { /** Verify app usage limit observer added correctly reports its total usage limit */ @Test public void testAppUsageLimitObserver_GetTotalUsageLimit() { addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); AppTimeLimitController.AppUsageLimitGroup group = getAppUsageLimitObserver(UID, OBS_ID1); assertNotNull("Observer wasn't added", group); assertEquals("Observer didn't correctly report total usage limit", Loading @@ -978,7 +978,7 @@ public class AppTimeLimitControllerTests { @Test public void testAppUsageLimitObserver_GetUsageRemaining() { setTime(0L); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); startUsage(PKG_SOC1); setTime(TIME_10_MIN); stopUsage(PKG_SOC1); Loading @@ -993,8 +993,8 @@ public class AppTimeLimitControllerTests { */ @Test public void testAppUsageLimitObserver_GetAppUsageLimit() { addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, TIME_10_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, 0); UsageStatsManagerInternal.AppUsageLimitData group = getAppUsageLimit(PKG_SOC1); assertEquals("Observer with the smallest usage limit remaining wasn't returned", TIME_10_MIN, group.getTotalUsageLimit()); Loading @@ -1006,8 +1006,8 @@ public class AppTimeLimitControllerTests { @Test public void testAppUsageLimitObserver_GetAppUsageLimitUsed() { setTime(0L); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, TIME_10_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, 0); startUsage(PKG_GAME1); setTime(TIME_10_MIN * 2 + TIME_1_MIN); stopUsage(PKG_GAME1); Loading @@ -1024,8 +1024,8 @@ public class AppTimeLimitControllerTests { @Test public void testAppUsageLimitObserver_GetAppUsageLimitAllUsed() { setTime(0L); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN); addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, TIME_10_MIN); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, 0); startUsage(PKG_SOC1); setTime(TIME_10_MIN); stopUsage(PKG_SOC1); Loading @@ -1046,10 +1046,10 @@ public class AppTimeLimitControllerTests { } } /** Verify that a limit of 0 is allowed for the special case of re-registering an observer. */ /** Verify that timeUsed can be the same as timeLimit (for re-registering observers). */ @Test public void testAppUsageLimitObserver_ZeroTimeRemainingIsAllowed() { addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_1_MIN, 0); addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_1_MIN, TIME_1_MIN); AppTimeLimitController.AppUsageLimitGroup group = getAppUsageLimitObserver(UID, OBS_ID1); assertNotNull("Observer wasn't added", group); assertEquals("Usage remaining was not 0.", 0, group.getUsageRemaining()); Loading Loading @@ -1078,8 +1078,8 @@ public class AppTimeLimitControllerTests { } private void addAppUsageLimitObserver(int observerId, String[] packages, long timeLimit, long timeRemaining) { mController.addAppUsageLimitObserver(UID, observerId, packages, timeLimit, timeRemaining, long timeUsed) { mController.addAppUsageLimitObserver(UID, observerId, packages, timeLimit, timeUsed, null, USER_ID); } Loading
services/usage/java/com/android/server/usage/AppTimeLimitController.java +4 −4 Original line number Diff line number Diff line Loading @@ -511,10 +511,10 @@ public class AppTimeLimitController { class AppUsageLimitGroup extends UsageGroup { public AppUsageLimitGroup(UserData user, ObserverAppData observerApp, int observerId, String[] observed, long timeLimitMs, long timeRemainingMs, String[] observed, long timeLimitMs, long timeUsedMs, PendingIntent limitReachedCallback) { super(user, observerApp, observerId, observed, timeLimitMs, limitReachedCallback); mUsageTimeMs = timeLimitMs - timeRemainingMs; mUsageTimeMs = timeUsedMs; } @Override Loading Loading @@ -841,7 +841,7 @@ public class AppTimeLimitController { * Existing app usage limit observer with the same observerId will be removed. */ public void addAppUsageLimitObserver(int requestingUid, int observerId, String[] observed, long timeLimit, long timeRemaining, PendingIntent callbackIntent, long timeLimit, long timeUsed, PendingIntent callbackIntent, @UserIdInt int userId) { if (timeLimit < getMinTimeLimit()) { throw new IllegalArgumentException("Time limit must be >= " + getMinTimeLimit()); Loading @@ -861,7 +861,7 @@ public class AppTimeLimitController { "Too many app usage observers added by uid " + requestingUid); } group = new AppUsageLimitGroup(user, observerApp, observerId, observed, timeLimit, timeRemaining, timeRemaining == 0L ? null : callbackIntent); timeUsed, timeUsed >= timeLimit ? null : callbackIntent); observerApp.appUsageLimitGroups.append(observerId, group); if (DEBUG) { Loading
services/usage/java/com/android/server/usage/UsageStatsService.java +5 −9 Original line number Diff line number Diff line Loading @@ -1399,7 +1399,7 @@ public class UsageStatsService extends SystemService implements @Override public void registerAppUsageLimitObserver(int observerId, String[] packages, long timeLimitMs, long timeRemainingMs, PendingIntent callbackIntent, long timeLimitMs, long timeUsedMs, PendingIntent callbackIntent, String callingPackage) { if (!hasPermissions(callingPackage, Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE)) { Loading @@ -1410,11 +1410,7 @@ public class UsageStatsService extends SystemService implements if (packages == null || packages.length == 0) { throw new IllegalArgumentException("Must specify at least one package"); } if (timeRemainingMs > timeLimitMs) { throw new IllegalArgumentException( "Remaining time can't be greater than total time."); } if (callbackIntent == null && timeRemainingMs != 0L) { if (callbackIntent == null && timeUsedMs < timeLimitMs) { throw new NullPointerException("callbackIntent can't be null"); } final int callingUid = Binder.getCallingUid(); Loading @@ -1422,7 +1418,7 @@ public class UsageStatsService extends SystemService implements final long token = Binder.clearCallingIdentity(); try { UsageStatsService.this.registerAppUsageLimitObserver(callingUid, observerId, packages, timeLimitMs, timeRemainingMs, callbackIntent, userId); packages, timeLimitMs, timeUsedMs, callbackIntent, userId); } finally { Binder.restoreCallingIdentity(token); } Loading Loading @@ -1550,9 +1546,9 @@ public class UsageStatsService extends SystemService implements } void registerAppUsageLimitObserver(int callingUid, int observerId, String[] packages, long timeLimitMs, long timeRemainingMs, PendingIntent callbackIntent, int userId) { long timeLimitMs, long timeUsedMs, PendingIntent callbackIntent, int userId) { mAppTimeLimit.addAppUsageLimitObserver(callingUid, observerId, packages, timeLimitMs, timeRemainingMs, callbackIntent, userId); timeLimitMs, timeUsedMs, callbackIntent, userId); } void unregisterAppUsageLimitObserver(int callingUid, int observerId, int userId) { Loading