Loading apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java +8 −0 Original line number Original line Diff line number Diff line Loading @@ -2,6 +2,7 @@ package com.android.server.usage; import android.annotation.CurrentTimeMillisLong; import android.annotation.CurrentTimeMillisLong; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.annotation.UserIdInt; import android.app.ActivityManager.ProcessState; import android.app.ActivityManager.ProcessState; import android.app.usage.AppStandbyInfo; import android.app.usage.AppStandbyInfo; Loading Loading @@ -237,4 +238,11 @@ public interface AppStandbyInternal { */ */ @ProcessState @ProcessState int getBroadcastResponseFgThresholdState(); int getBroadcastResponseFgThresholdState(); /** * Return the last known value corresponding to the {@code key} from * {@link android.provider.DeviceConfig#NAMESPACE_APP_STANDBY} in AppStandbyController. */ @Nullable String getAppStandbyConstant(@NonNull String key); } } apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +18 −0 Original line number Original line Diff line number Diff line Loading @@ -100,6 +100,7 @@ import android.os.UserHandle; import android.provider.DeviceConfig; import android.provider.DeviceConfig; import android.provider.Settings.Global; import android.provider.Settings.Global; import android.telephony.TelephonyManager; import android.telephony.TelephonyManager; import android.util.ArrayMap; import android.util.ArraySet; import android.util.ArraySet; import android.util.IndentingPrintWriter; import android.util.IndentingPrintWriter; import android.util.Slog; import android.util.Slog; Loading Loading @@ -130,6 +131,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Arrays; import java.util.Collections; import java.util.Collections; import java.util.List; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch; Loading Loading @@ -374,6 +376,15 @@ public class AppStandbyController volatile int mBroadcastResponseFgThresholdState = volatile int mBroadcastResponseFgThresholdState = ConstantsObserver.DEFAULT_BROADCAST_RESPONSE_FG_THRESHOLD_STATE; ConstantsObserver.DEFAULT_BROADCAST_RESPONSE_FG_THRESHOLD_STATE; /** * Map of last known values of keys in {@link DeviceConfig#NAMESPACE_APP_STANDBY}. * * Note: We are intentionally not guarding this by any lock since this is only updated on * a handler thread and when querying, if we do end up seeing slightly older values, it is fine * since the values are only used in tests and doesn't need to be queried in any other cases. */ private final Map<String, String> mAppStandbyProperties = new ArrayMap<>(); /** /** * Whether we should allow apps into the * Whether we should allow apps into the * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} bucket or not. * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} bucket or not. Loading Loading @@ -1836,6 +1847,12 @@ public class AppStandbyController return mBroadcastResponseFgThresholdState; return mBroadcastResponseFgThresholdState; } } @Override @Nullable public String getAppStandbyConstant(@NonNull String key) { return mAppStandbyProperties.get(key); } @Override @Override public void flushToDisk() { public void flushToDisk() { synchronized (mAppIdleLock) { synchronized (mAppIdleLock) { Loading Loading @@ -2774,6 +2791,7 @@ public class AppStandbyController } } break; break; } } mAppStandbyProperties.put(name, properties.getString(name, null)); } } } } } } Loading core/java/android/app/usage/IUsageStatsManager.aidl +2 −0 Original line number Original line Diff line number Diff line Loading @@ -82,4 +82,6 @@ interface IUsageStatsManager { int userId); int userId); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)") @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)") void clearBroadcastEvents(String callingPackage, int userId); void clearBroadcastEvents(String callingPackage, int userId); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG)") String getAppStandbyConstant(String key); } } core/java/android/app/usage/UsageStatsManager.java +12 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.app.usage; package android.app.usage; import android.Manifest; import android.annotation.CurrentTimeMillisLong; import android.annotation.CurrentTimeMillisLong; import android.annotation.IntDef; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.IntRange; Loading Loading @@ -1505,4 +1506,15 @@ public final class UsageStatsManager { throw re.rethrowFromSystemServer(); throw re.rethrowFromSystemServer(); } } } } /** @hide */ @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) @Nullable public String getAppStandbyConstant(@NonNull String key) { try { return mService.getAppStandbyConstant(key); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } } } services/usage/java/com/android/server/usage/UsageStatsService.java +15 −5 Original line number Original line Diff line number Diff line Loading @@ -2015,7 +2015,7 @@ public class UsageStatsService extends SystemService implements == PackageManager.PERMISSION_GRANTED; == PackageManager.PERMISSION_GRANTED; } } private boolean hasPermissions(String callingPackage, String... permissions) { private boolean hasPermissions(String... permissions) { final int callingUid = Binder.getCallingUid(); final int callingUid = Binder.getCallingUid(); if (callingUid == Process.SYSTEM_UID) { if (callingUid == Process.SYSTEM_UID) { // Caller is the system, so proceed. // Caller is the system, so proceed. Loading Loading @@ -2578,7 +2578,7 @@ public class UsageStatsService extends SystemService implements String callingPackage) { String callingPackage) { final int callingUid = Binder.getCallingUid(); final int callingUid = Binder.getCallingUid(); final DevicePolicyManagerInternal dpmInternal = getDpmInternal(); final DevicePolicyManagerInternal dpmInternal = getDpmInternal(); if (!hasPermissions(callingPackage, if (!hasPermissions( Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE) Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE) && (dpmInternal == null || !dpmInternal.isActiveSupervisionApp(callingUid))) { && (dpmInternal == null || !dpmInternal.isActiveSupervisionApp(callingUid))) { throw new SecurityException("Caller must be the active supervision app or " throw new SecurityException("Caller must be the active supervision app or " Loading @@ -2605,7 +2605,7 @@ public class UsageStatsService extends SystemService implements public void unregisterAppUsageLimitObserver(int observerId, String callingPackage) { public void unregisterAppUsageLimitObserver(int observerId, String callingPackage) { final int callingUid = Binder.getCallingUid(); final int callingUid = Binder.getCallingUid(); final DevicePolicyManagerInternal dpmInternal = getDpmInternal(); final DevicePolicyManagerInternal dpmInternal = getDpmInternal(); if (!hasPermissions(callingPackage, if (!hasPermissions( Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE) Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE) && (dpmInternal == null || !dpmInternal.isActiveSupervisionApp(callingUid))) { && (dpmInternal == null || !dpmInternal.isActiveSupervisionApp(callingUid))) { throw new SecurityException("Caller must be the active supervision app or " throw new SecurityException("Caller must be the active supervision app or " Loading Loading @@ -2703,8 +2703,7 @@ public class UsageStatsService extends SystemService implements @Override @Override public long getLastTimeAnyComponentUsed(String packageName, String callingPackage) { public long getLastTimeAnyComponentUsed(String packageName, String callingPackage) { if (!hasPermissions( if (!hasPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS)) { callingPackage, android.Manifest.permission.INTERACT_ACROSS_USERS)) { throw new SecurityException("Caller doesn't have INTERACT_ACROSS_USERS permission"); throw new SecurityException("Caller doesn't have INTERACT_ACROSS_USERS permission"); } } if (!hasPermission(callingPackage)) { if (!hasPermission(callingPackage)) { Loading Loading @@ -2787,6 +2786,17 @@ public class UsageStatsService extends SystemService implements "clearBroadcastResponseStats" /* name */, callingPackage); "clearBroadcastResponseStats" /* name */, callingPackage); mResponseStatsTracker.clearBroadcastEvents(callingUid, userId); mResponseStatsTracker.clearBroadcastEvents(callingUid, userId); } } @Override @Nullable public String getAppStandbyConstant(@NonNull String key) { Objects.requireNonNull(key); if (!hasPermissions(Manifest.permission.READ_DEVICE_CONFIG)) { throw new SecurityException("Caller doesn't have READ_DEVICE_CONFIG permission"); } return mAppStandby.getAppStandbyConstant(key); } } } void registerAppUsageObserver(int callingUid, int observerId, String[] packages, void registerAppUsageObserver(int callingUid, int observerId, String[] packages, Loading Loading
apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java +8 −0 Original line number Original line Diff line number Diff line Loading @@ -2,6 +2,7 @@ package com.android.server.usage; import android.annotation.CurrentTimeMillisLong; import android.annotation.CurrentTimeMillisLong; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.annotation.UserIdInt; import android.app.ActivityManager.ProcessState; import android.app.ActivityManager.ProcessState; import android.app.usage.AppStandbyInfo; import android.app.usage.AppStandbyInfo; Loading Loading @@ -237,4 +238,11 @@ public interface AppStandbyInternal { */ */ @ProcessState @ProcessState int getBroadcastResponseFgThresholdState(); int getBroadcastResponseFgThresholdState(); /** * Return the last known value corresponding to the {@code key} from * {@link android.provider.DeviceConfig#NAMESPACE_APP_STANDBY} in AppStandbyController. */ @Nullable String getAppStandbyConstant(@NonNull String key); } }
apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +18 −0 Original line number Original line Diff line number Diff line Loading @@ -100,6 +100,7 @@ import android.os.UserHandle; import android.provider.DeviceConfig; import android.provider.DeviceConfig; import android.provider.Settings.Global; import android.provider.Settings.Global; import android.telephony.TelephonyManager; import android.telephony.TelephonyManager; import android.util.ArrayMap; import android.util.ArraySet; import android.util.ArraySet; import android.util.IndentingPrintWriter; import android.util.IndentingPrintWriter; import android.util.Slog; import android.util.Slog; Loading Loading @@ -130,6 +131,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Arrays; import java.util.Collections; import java.util.Collections; import java.util.List; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch; Loading Loading @@ -374,6 +376,15 @@ public class AppStandbyController volatile int mBroadcastResponseFgThresholdState = volatile int mBroadcastResponseFgThresholdState = ConstantsObserver.DEFAULT_BROADCAST_RESPONSE_FG_THRESHOLD_STATE; ConstantsObserver.DEFAULT_BROADCAST_RESPONSE_FG_THRESHOLD_STATE; /** * Map of last known values of keys in {@link DeviceConfig#NAMESPACE_APP_STANDBY}. * * Note: We are intentionally not guarding this by any lock since this is only updated on * a handler thread and when querying, if we do end up seeing slightly older values, it is fine * since the values are only used in tests and doesn't need to be queried in any other cases. */ private final Map<String, String> mAppStandbyProperties = new ArrayMap<>(); /** /** * Whether we should allow apps into the * Whether we should allow apps into the * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} bucket or not. * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} bucket or not. Loading Loading @@ -1836,6 +1847,12 @@ public class AppStandbyController return mBroadcastResponseFgThresholdState; return mBroadcastResponseFgThresholdState; } } @Override @Nullable public String getAppStandbyConstant(@NonNull String key) { return mAppStandbyProperties.get(key); } @Override @Override public void flushToDisk() { public void flushToDisk() { synchronized (mAppIdleLock) { synchronized (mAppIdleLock) { Loading Loading @@ -2774,6 +2791,7 @@ public class AppStandbyController } } break; break; } } mAppStandbyProperties.put(name, properties.getString(name, null)); } } } } } } Loading
core/java/android/app/usage/IUsageStatsManager.aidl +2 −0 Original line number Original line Diff line number Diff line Loading @@ -82,4 +82,6 @@ interface IUsageStatsManager { int userId); int userId); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)") @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)") void clearBroadcastEvents(String callingPackage, int userId); void clearBroadcastEvents(String callingPackage, int userId); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG)") String getAppStandbyConstant(String key); } }
core/java/android/app/usage/UsageStatsManager.java +12 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.app.usage; package android.app.usage; import android.Manifest; import android.annotation.CurrentTimeMillisLong; import android.annotation.CurrentTimeMillisLong; import android.annotation.IntDef; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.IntRange; Loading Loading @@ -1505,4 +1506,15 @@ public final class UsageStatsManager { throw re.rethrowFromSystemServer(); throw re.rethrowFromSystemServer(); } } } } /** @hide */ @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) @Nullable public String getAppStandbyConstant(@NonNull String key) { try { return mService.getAppStandbyConstant(key); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } } }
services/usage/java/com/android/server/usage/UsageStatsService.java +15 −5 Original line number Original line Diff line number Diff line Loading @@ -2015,7 +2015,7 @@ public class UsageStatsService extends SystemService implements == PackageManager.PERMISSION_GRANTED; == PackageManager.PERMISSION_GRANTED; } } private boolean hasPermissions(String callingPackage, String... permissions) { private boolean hasPermissions(String... permissions) { final int callingUid = Binder.getCallingUid(); final int callingUid = Binder.getCallingUid(); if (callingUid == Process.SYSTEM_UID) { if (callingUid == Process.SYSTEM_UID) { // Caller is the system, so proceed. // Caller is the system, so proceed. Loading Loading @@ -2578,7 +2578,7 @@ public class UsageStatsService extends SystemService implements String callingPackage) { String callingPackage) { final int callingUid = Binder.getCallingUid(); final int callingUid = Binder.getCallingUid(); final DevicePolicyManagerInternal dpmInternal = getDpmInternal(); final DevicePolicyManagerInternal dpmInternal = getDpmInternal(); if (!hasPermissions(callingPackage, if (!hasPermissions( Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE) Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE) && (dpmInternal == null || !dpmInternal.isActiveSupervisionApp(callingUid))) { && (dpmInternal == null || !dpmInternal.isActiveSupervisionApp(callingUid))) { throw new SecurityException("Caller must be the active supervision app or " throw new SecurityException("Caller must be the active supervision app or " Loading @@ -2605,7 +2605,7 @@ public class UsageStatsService extends SystemService implements public void unregisterAppUsageLimitObserver(int observerId, String callingPackage) { public void unregisterAppUsageLimitObserver(int observerId, String callingPackage) { final int callingUid = Binder.getCallingUid(); final int callingUid = Binder.getCallingUid(); final DevicePolicyManagerInternal dpmInternal = getDpmInternal(); final DevicePolicyManagerInternal dpmInternal = getDpmInternal(); if (!hasPermissions(callingPackage, if (!hasPermissions( Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE) Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE) && (dpmInternal == null || !dpmInternal.isActiveSupervisionApp(callingUid))) { && (dpmInternal == null || !dpmInternal.isActiveSupervisionApp(callingUid))) { throw new SecurityException("Caller must be the active supervision app or " throw new SecurityException("Caller must be the active supervision app or " Loading Loading @@ -2703,8 +2703,7 @@ public class UsageStatsService extends SystemService implements @Override @Override public long getLastTimeAnyComponentUsed(String packageName, String callingPackage) { public long getLastTimeAnyComponentUsed(String packageName, String callingPackage) { if (!hasPermissions( if (!hasPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS)) { callingPackage, android.Manifest.permission.INTERACT_ACROSS_USERS)) { throw new SecurityException("Caller doesn't have INTERACT_ACROSS_USERS permission"); throw new SecurityException("Caller doesn't have INTERACT_ACROSS_USERS permission"); } } if (!hasPermission(callingPackage)) { if (!hasPermission(callingPackage)) { Loading Loading @@ -2787,6 +2786,17 @@ public class UsageStatsService extends SystemService implements "clearBroadcastResponseStats" /* name */, callingPackage); "clearBroadcastResponseStats" /* name */, callingPackage); mResponseStatsTracker.clearBroadcastEvents(callingUid, userId); mResponseStatsTracker.clearBroadcastEvents(callingUid, userId); } } @Override @Nullable public String getAppStandbyConstant(@NonNull String key) { Objects.requireNonNull(key); if (!hasPermissions(Manifest.permission.READ_DEVICE_CONFIG)) { throw new SecurityException("Caller doesn't have READ_DEVICE_CONFIG permission"); } return mAppStandby.getAppStandbyConstant(key); } } } void registerAppUsageObserver(int callingUid, int observerId, String[] packages, void registerAppUsageObserver(int callingUid, int observerId, String[] packages, Loading