diff --git a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java index c4795f55fc8a..53a388913118 100644 --- a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java +++ b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java @@ -32,6 +32,8 @@ import android.annotation.SystemService; import android.annotation.UserHandleAware; import android.content.Context; +import com.android.internal.util.FrameworkStatsLog; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Collections; @@ -451,6 +453,62 @@ public class PowerExemptionManager { @Retention(RetentionPolicy.SOURCE) public @interface ReasonCode {} + private static final int EXEMPTION_REASON_SYSTEM_UID = FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_SYSTEM_UID; + private static final int EXEMPTION_REASON_ALLOWLISTED_PACKAGE = FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_ALLOWLISTED_PACKAGE; + private static final int EXEMPTION_REASON_COMPANION_DEVICE_MANAGER = FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_COMPANION_DEVICE_MANAGER; + private static final int EXEMPTION_REASON_DEVICE_DEMO_MODE = FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_DEVICE_DEMO_MODE; + private static final int EXEMPTION_REASON_DEVICE_OWNER = FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_DEVICE_OWNER; + private static final int EXEMPTION_REASON_PROFILE_OWNER = FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_PROFILE_OWNER; + private static final int EXEMPTION_REASON_PROC_STATE_PERSISTENT = FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_PROC_STATE_PERSISTENT; + private static final int EXEMPTION_REASON_PROC_STATE_PERSISTENT_UI = FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_PROC_STATE_PERSISTENT_UI; + private static final int EXEMPTION_REASON_OP_ACTIVATE_VPN = FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_OP_ACTIVATE_VPN; + private static final int EXEMPTION_REASON_OP_ACTIVATE_PLATFORM_VPN = FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_OP_ACTIVATE_PLATFORM_VPN; + private static final int EXEMPTION_REASON_SYSTEM_MODULE = FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_SYSTEM_MODULE; + private static final int EXEMPTION_REASON_CARRIER_PRIVILEGED_APP = FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_CARRIER_PRIVILEGED_APP; + private static final int EXEMPTION_REASON_SYSTEM_ALLOW_LISTED = FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_SYSTEM_ALLOW_LISTED; + private static final int EXEMPTION_REASON_ROLE_DIALER = FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_ROLE_DIALER; + private static final int EXEMPTION_REASON_ROLE_EMERGENCY = FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_ROLE_EMERGENCY; + private static final int EXEMPTION_REASON_DENIED = FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_DENIED; + /** + * List of exemption reason codes used for statsd logging in AppBackgroundRestrictionsInfo atom. + * @hide + */ + @IntDef(prefix = { "EXEMPTION_REASON_" }, value = { + EXEMPTION_REASON_SYSTEM_UID, + EXEMPTION_REASON_ALLOWLISTED_PACKAGE, + EXEMPTION_REASON_COMPANION_DEVICE_MANAGER, + EXEMPTION_REASON_DEVICE_DEMO_MODE, + EXEMPTION_REASON_DEVICE_OWNER, + EXEMPTION_REASON_PROFILE_OWNER, + EXEMPTION_REASON_PROC_STATE_PERSISTENT, + EXEMPTION_REASON_PROC_STATE_PERSISTENT_UI, + EXEMPTION_REASON_OP_ACTIVATE_VPN, + EXEMPTION_REASON_OP_ACTIVATE_PLATFORM_VPN, + EXEMPTION_REASON_SYSTEM_MODULE, + EXEMPTION_REASON_CARRIER_PRIVILEGED_APP, + EXEMPTION_REASON_SYSTEM_ALLOW_LISTED, + EXEMPTION_REASON_ROLE_DIALER, + EXEMPTION_REASON_ROLE_EMERGENCY, + EXEMPTION_REASON_DENIED, + }) + public @interface ExemptionReason {} + /** * @hide */ @@ -617,6 +675,47 @@ public class PowerExemptionManager { } } + /** + * @hide + * @return the reason code mapped to statsd for the AppBackgroundRestrictionsInfo atom. + */ + public static @ExemptionReason int getExemptionReasonForStatsd(@ReasonCode int reasonCode) { + switch (reasonCode) { + case REASON_SYSTEM_UID: + return EXEMPTION_REASON_SYSTEM_UID; + case REASON_ALLOWLISTED_PACKAGE: + return EXEMPTION_REASON_ALLOWLISTED_PACKAGE; + case REASON_COMPANION_DEVICE_MANAGER: + return EXEMPTION_REASON_COMPANION_DEVICE_MANAGER; + case REASON_DEVICE_DEMO_MODE: + return EXEMPTION_REASON_DEVICE_DEMO_MODE; + case REASON_DEVICE_OWNER: + return EXEMPTION_REASON_DEVICE_OWNER; + case REASON_PROFILE_OWNER: + return EXEMPTION_REASON_PROFILE_OWNER; + case REASON_PROC_STATE_PERSISTENT: + return EXEMPTION_REASON_PROC_STATE_PERSISTENT; + case REASON_PROC_STATE_PERSISTENT_UI: + return EXEMPTION_REASON_PROC_STATE_PERSISTENT_UI; + case REASON_OP_ACTIVATE_VPN: + return EXEMPTION_REASON_OP_ACTIVATE_VPN; + case REASON_OP_ACTIVATE_PLATFORM_VPN: + return EXEMPTION_REASON_OP_ACTIVATE_PLATFORM_VPN; + case REASON_SYSTEM_MODULE: + return EXEMPTION_REASON_SYSTEM_MODULE; + case REASON_CARRIER_PRIVILEGED_APP: + return EXEMPTION_REASON_CARRIER_PRIVILEGED_APP; + case REASON_SYSTEM_ALLOW_LISTED: + return EXEMPTION_REASON_SYSTEM_ALLOW_LISTED; + case REASON_ROLE_DIALER: + return EXEMPTION_REASON_ROLE_DIALER; + case REASON_ROLE_EMERGENCY: + return EXEMPTION_REASON_ROLE_EMERGENCY; + default: + return EXEMPTION_REASON_DENIED; + } + } + /** * Return string name of the integer reason code. * @hide diff --git a/services/core/java/com/android/server/am/AppBatteryExemptionTracker.java b/services/core/java/com/android/server/am/AppBatteryExemptionTracker.java index 6f11b0001c7a..b07d9a6b258c 100644 --- a/services/core/java/com/android/server/am/AppBatteryExemptionTracker.java +++ b/services/core/java/com/android/server/am/AppBatteryExemptionTracker.java @@ -39,6 +39,7 @@ import com.android.server.am.AppBatteryExemptionTracker.UidBatteryStates; import com.android.server.am.AppBatteryTracker.AppBatteryPolicy; import com.android.server.am.AppBatteryTracker.BatteryUsage; import com.android.server.am.AppBatteryTracker.ImmutableBatteryUsage; +import com.android.server.am.AppRestrictionController.TrackerType; import com.android.server.am.BaseAppStateTimeEvents.BaseTimeEvent; import com.android.server.am.BaseAppStateTracker.Injector; import com.android.server.am.BaseAppStateTracker.StateListener; @@ -84,6 +85,11 @@ final class AppBatteryExemptionTracker mInjector.setPolicy(new AppBatteryExemptionPolicy(mInjector, this)); } + @Override + @TrackerType int getType() { + return AppRestrictionController.TRACKER_TYPE_BATTERY_EXEMPTION; + } + @Override void onSystemReady() { super.onSystemReady(); diff --git a/services/core/java/com/android/server/am/AppBatteryTracker.java b/services/core/java/com/android/server/am/AppBatteryTracker.java index 3de5e1a98bdf..8f98fbaaffe8 100644 --- a/services/core/java/com/android/server/am/AppBatteryTracker.java +++ b/services/core/java/com/android/server/am/AppBatteryTracker.java @@ -73,6 +73,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.server.am.AppBatteryTracker.AppBatteryPolicy; +import com.android.server.am.AppRestrictionController.TrackerType; import com.android.server.am.AppRestrictionController.UidBatteryUsageProvider; import com.android.server.pm.UserManagerInternal; @@ -194,6 +195,11 @@ final class AppBatteryTracker extends BaseAppStateTracker mInjector.setPolicy(new AppBatteryPolicy(mInjector, this)); } + @Override + @TrackerType int getType() { + return AppRestrictionController.TRACKER_TYPE_BATTERY; + } + @Override void onSystemReady() { super.onSystemReady(); diff --git a/services/core/java/com/android/server/am/AppBindServiceEventsTracker.java b/services/core/java/com/android/server/am/AppBindServiceEventsTracker.java index 9e3cae63278c..9bed077785f5 100644 --- a/services/core/java/com/android/server/am/AppBindServiceEventsTracker.java +++ b/services/core/java/com/android/server/am/AppBindServiceEventsTracker.java @@ -26,6 +26,7 @@ import android.app.ActivityManagerInternal.BindServiceEventListener; import android.content.Context; import com.android.server.am.AppBindServiceEventsTracker.AppBindServiceEventsPolicy; +import com.android.server.am.AppRestrictionController.TrackerType; import com.android.server.am.BaseAppStateTimeSlotEventsTracker.SimpleAppStateTimeslotEvents; import com.android.server.am.BaseAppStateTracker.Injector; @@ -58,6 +59,11 @@ final class AppBindServiceEventsTracker extends BaseAppStateTimeSlotEventsTracke } } + @Override + @TrackerType int getType() { + return AppRestrictionController.TRACKER_TYPE_BIND_SERVICE_EVENTS; + } + @Override void onSystemReady() { super.onSystemReady(); diff --git a/services/core/java/com/android/server/am/AppBroadcastEventsTracker.java b/services/core/java/com/android/server/am/AppBroadcastEventsTracker.java index cafae40613a2..a9155a115389 100644 --- a/services/core/java/com/android/server/am/AppBroadcastEventsTracker.java +++ b/services/core/java/com/android/server/am/AppBroadcastEventsTracker.java @@ -26,6 +26,7 @@ import android.app.ActivityManagerInternal.BroadcastEventListener; import android.content.Context; import com.android.server.am.AppBroadcastEventsTracker.AppBroadcastEventsPolicy; +import com.android.server.am.AppRestrictionController.TrackerType; import com.android.server.am.BaseAppStateTimeSlotEventsTracker.SimpleAppStateTimeslotEvents; import com.android.server.am.BaseAppStateTracker.Injector; @@ -57,6 +58,11 @@ final class AppBroadcastEventsTracker extends BaseAppStateTimeSlotEventsTracker } } + @Override + @TrackerType int getType() { + return AppRestrictionController.TRACKER_TYPE_BROADCAST_EVENTS; + } + @Override void onSystemReady() { super.onSystemReady(); diff --git a/services/core/java/com/android/server/am/AppFGSTracker.java b/services/core/java/com/android/server/am/AppFGSTracker.java index 246725e03ba6..f8378c3a8a4e 100644 --- a/services/core/java/com/android/server/am/AppFGSTracker.java +++ b/services/core/java/com/android/server/am/AppFGSTracker.java @@ -54,6 +54,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.server.am.AppFGSTracker.AppFGSPolicy; import com.android.server.am.AppFGSTracker.PackageDurations; +import com.android.server.am.AppRestrictionController.TrackerType; import com.android.server.am.BaseAppStateEventsTracker.BaseAppStateEventsPolicy; import com.android.server.am.BaseAppStateTimeEvents.BaseTimeEvent; import com.android.server.am.BaseAppStateTracker.Injector; @@ -175,6 +176,11 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker levelTypePair = calcAppRestrictionLevel( userId, uid, info.mPackageName, info.mStandbyBucket, false, false); if (DEBUG_BG_RESTRICTION_CONTROLLER) { Slog.i(TAG, "Proposed restriction level of " + info.mPackageName + "/" + UserHandle.formatUid(uid) + ": " - + ActivityManager.restrictionLevelToName(level) + + ActivityManager.restrictionLevelToName(levelTypePair.first) + " " + info.mStandbyBucket); } - applyRestrictionLevel(info.mPackageName, uid, level, + applyRestrictionLevel(info.mPackageName, uid, levelTypePair.first, levelTypePair.second, info.mStandbyBucket, true, reason, subReason); } } @@ -1533,24 +1559,26 @@ public final class AppRestrictionController { final long now = SystemClock.elapsedRealtime(); for (String pkg: packages) { final int curBucket = appStandbyInternal.getAppStandbyBucket(pkg, userId, now, false); - final @RestrictionLevel int level = calcAppRestrictionLevel(userId, uid, pkg, + final Pair levelTypePair = calcAppRestrictionLevel(userId, uid, pkg, curBucket, allowRequestBgRestricted, true); if (DEBUG_BG_RESTRICTION_CONTROLLER) { Slog.i(TAG, "Proposed restriction level of " + pkg + "/" + UserHandle.formatUid(uid) + ": " - + ActivityManager.restrictionLevelToName(level)); + + ActivityManager.restrictionLevelToName(levelTypePair.first)); } - applyRestrictionLevel(pkg, uid, level, curBucket, true, reason, subReason); + applyRestrictionLevel(pkg, uid, levelTypePair.first, levelTypePair.second, + curBucket, true, reason, subReason); } } - private @RestrictionLevel int calcAppRestrictionLevel(@UserIdInt int userId, int uid, + private Pair calcAppRestrictionLevel(@UserIdInt int userId, int uid, String packageName, @UsageStatsManager.StandbyBuckets int standbyBucket, boolean allowRequestBgRestricted, boolean calcTrackers) { if (mInjector.getAppHibernationInternal().isHibernatingForUser(packageName, userId)) { - return RESTRICTION_LEVEL_HIBERNATION; + return new Pair<>(RESTRICTION_LEVEL_HIBERNATION, TRACKER_TYPE_UNKNOWN); } @RestrictionLevel int level; + @TrackerType int trackerType = TRACKER_TYPE_UNKNOWN; switch (standbyBucket) { case STANDBY_BUCKET_EXEMPTED: level = RESTRICTION_LEVEL_EXEMPTED; @@ -1566,19 +1594,23 @@ public final class AppRestrictionController { default: if (mInjector.getAppStateTracker() .isAppBackgroundRestricted(uid, packageName)) { - return RESTRICTION_LEVEL_BACKGROUND_RESTRICTED; + return new Pair<>(RESTRICTION_LEVEL_BACKGROUND_RESTRICTED, trackerType); } level = mConstantsObserver.mRestrictedBucketEnabled && standbyBucket == STANDBY_BUCKET_RESTRICTED ? RESTRICTION_LEVEL_RESTRICTED_BUCKET : RESTRICTION_LEVEL_ADAPTIVE_BUCKET; if (calcTrackers) { - @RestrictionLevel int l = calcAppRestrictionLevelFromTackers(uid, packageName, - RESTRICTION_LEVEL_MAX); + Pair levelTypePair = calcAppRestrictionLevelFromTackers( + uid, packageName, RESTRICTION_LEVEL_MAX); + @RestrictionLevel int l = levelTypePair.first; if (l == RESTRICTION_LEVEL_EXEMPTED) { - return RESTRICTION_LEVEL_EXEMPTED; + return new Pair<>(RESTRICTION_LEVEL_EXEMPTED, levelTypePair.second); } level = Math.max(l, level); + if (l == level) { + trackerType = levelTypePair.second; + } if (level == RESTRICTION_LEVEL_BACKGROUND_RESTRICTED) { // This level can't be entered without user consent if (allowRequestBgRestricted) { @@ -1586,27 +1618,32 @@ public final class AppRestrictionController { uid, 0, packageName).sendToTarget(); } // Lower the level. - level = calcAppRestrictionLevelFromTackers(uid, packageName, + levelTypePair = calcAppRestrictionLevelFromTackers(uid, packageName, RESTRICTION_LEVEL_BACKGROUND_RESTRICTED); + level = levelTypePair.first; + trackerType = levelTypePair.second; } } break; } - return level; + return new Pair<>(level, trackerType); } /** * Ask each of the trackers for their proposed restriction levels for the given uid/package, - * and return the most restrictive level. + * and return the most restrictive level along with the type of tracker which applied this + * restriction level as a {@code Pair<@RestrictionLevel, @TrackerType>}. * *

Note, it's different from the {@link #getRestrictionLevel} where it returns the least * restrictive level. We're returning the most restrictive level here because each tracker * monitors certain dimensions of the app, the abusive behaviors could be detected in one or * more of these dimensions, but not necessarily all of them.

*/ - private @RestrictionLevel int calcAppRestrictionLevelFromTackers(int uid, String packageName, + private Pair calcAppRestrictionLevelFromTackers(int uid, String packageName, @RestrictionLevel int maxLevel) { @RestrictionLevel int level = RESTRICTION_LEVEL_UNKNOWN; + @RestrictionLevel int prevLevel = level; + @TrackerType int trackerType = TRACKER_TYPE_UNKNOWN; final boolean isRestrictedBucketEnabled = mConstantsObserver.mRestrictedBucketEnabled; for (int i = mAppStateTrackers.size() - 1; i >= 0; i--) { @RestrictionLevel int l = mAppStateTrackers.get(i).getPolicy() @@ -1615,8 +1652,12 @@ public final class AppRestrictionController { l = RESTRICTION_LEVEL_ADAPTIVE_BUCKET; } level = Math.max(level, l); + if (level != prevLevel) { + trackerType = mAppStateTrackers.get(i).getType(); + prevLevel = level; + } } - return level; + return new Pair<>(level, trackerType); } private static @RestrictionLevel int standbyBucketToRestrictionLevel( @@ -1829,7 +1870,126 @@ public final class AppRestrictionController { } } - private void applyRestrictionLevel(String pkgName, int uid, @RestrictionLevel int level, + private int getRestrictionLevelStatsd(@RestrictionLevel int level) { + switch (level) { + case RESTRICTION_LEVEL_UNKNOWN: + return FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_UNKNOWN; + case RESTRICTION_LEVEL_UNRESTRICTED: + return FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_UNRESTRICTED; + case RESTRICTION_LEVEL_EXEMPTED: + return FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_EXEMPTED; + case RESTRICTION_LEVEL_ADAPTIVE_BUCKET: + return FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_ADAPTIVE_BUCKET; + case RESTRICTION_LEVEL_RESTRICTED_BUCKET: + return FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_RESTRICTED_BUCKET; + case RESTRICTION_LEVEL_BACKGROUND_RESTRICTED: + return FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_BACKGROUND_RESTRICTED; + case RESTRICTION_LEVEL_HIBERNATION: + return FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_HIBERNATION; + default: + return FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_UNKNOWN; + } + } + + private int getThresholdStatsd(int reason) { + switch (reason) { + case REASON_MAIN_FORCED_BY_SYSTEM: + return FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__THRESHOLD__THRESHOLD_RESTRICTED; + case REASON_MAIN_FORCED_BY_USER: + return FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__THRESHOLD__THRESHOLD_USER; + default: + return FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__THRESHOLD__THRESHOLD_UNKNOWN; + } + } + + private int getTrackerTypeStatsd(@TrackerType int type) { + switch (type) { + case TRACKER_TYPE_BATTERY: + return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__BATTERY_TRACKER; + case TRACKER_TYPE_BATTERY_EXEMPTION: + return FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__BATTERY_EXEMPTION_TRACKER; + case TRACKER_TYPE_FGS: + return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__FGS_TRACKER; + case TRACKER_TYPE_MEDIA_SESSION: + return FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__MEDIA_SESSION_TRACKER; + case TRACKER_TYPE_PERMISSION: + return FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__PERMISSION_TRACKER; + case TRACKER_TYPE_BROADCAST_EVENTS: + return FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__BROADCAST_EVENTS_TRACKER; + case TRACKER_TYPE_BIND_SERVICE_EVENTS: + return FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__BIND_SERVICE_EVENTS_TRACKER; + default: + return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__UNKNOWN_TRACKER; + } + } + + private @ExemptionReason int getExemptionReasonStatsd(int uid, @RestrictionLevel int level) { + if (level != RESTRICTION_LEVEL_EXEMPTED) { + return FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_DENIED; + } + + @ReasonCode final int reasonCode = getBackgroundRestrictionExemptionReason(uid); + return getExemptionReasonForStatsd(reasonCode); + } + + private int getOptimizationLevelStatsd(@RestrictionLevel int level) { + switch (level) { + case RESTRICTION_LEVEL_UNKNOWN: + return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__OPT_LEVEL__UNKNOWN; + case RESTRICTION_LEVEL_UNRESTRICTED: + return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__OPT_LEVEL__NOT_OPTIMIZED; + case RESTRICTION_LEVEL_ADAPTIVE_BUCKET: + return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__OPT_LEVEL__OPTIMIZED; + case RESTRICTION_LEVEL_BACKGROUND_RESTRICTED: + return FrameworkStatsLog + .APP_BACKGROUND_RESTRICTIONS_INFO__OPT_LEVEL__BACKGROUND_RESTRICTED; + default: + return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__OPT_LEVEL__UNKNOWN; + } + } + + @SuppressWarnings("AndroidFrameworkCompatChange") + private int getTargetSdkStatsd(String packageName) { + final PackageManager pm = mInjector.getPackageManager(); + if (pm == null) { + return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_UNKNOWN; + } + try { + final PackageInfo pkg = pm.getPackageInfo(packageName, 0 /* flags */); + final int targetSdk = pkg.applicationInfo.targetSdkVersion; + if (targetSdk < Build.VERSION_CODES.S) { + return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_PRE_S; + } else if (targetSdk < Build.VERSION_CODES.TIRAMISU) { + return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_S; + } else if (targetSdk == Build.VERSION_CODES.TIRAMISU) { + return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_T; + } else { + return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_UNKNOWN; + } + } catch (PackageManager.NameNotFoundException ignored) { + } + return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_UNKNOWN; + } + + private void applyRestrictionLevel(String pkgName, int uid, + @RestrictionLevel int level, @TrackerType int trackerType, int curBucket, boolean allowUpdateBucket, int reason, int subReason) { int curLevel; int prevReason; @@ -1909,6 +2069,19 @@ public final class AppRestrictionController { prevReason & REASON_MAIN_MASK, prevReason & REASON_SUB_MASK, reason, subReason); } + + FrameworkStatsLog.write(FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO, uid, + getRestrictionLevelStatsd(level), + getThresholdStatsd(reason), + getTrackerTypeStatsd(trackerType), + null, // FgsTrackerInfo + null, // BatteryTrackerInfo + null, // BroadcastEventsTrackerInfo + null, // BindServiceEventsTrackerInfo + getExemptionReasonStatsd(uid, level), + getOptimizationLevelStatsd(level), + getTargetSdkStatsd(pkgName), + ActivityManager.isLowRamDeviceStatic()); } private void handleBackgroundRestrictionChanged(int uid, String pkgName, boolean restricted) { @@ -1926,7 +2099,7 @@ public final class AppRestrictionController { // The app could fall into the background restricted with user consent only, // so set the reason to it. applyRestrictionLevel(pkgName, uid, RESTRICTION_LEVEL_BACKGROUND_RESTRICTED, - curBucket, true, REASON_MAIN_FORCED_BY_USER, + TRACKER_TYPE_UNKNOWN, curBucket, true, REASON_MAIN_FORCED_BY_USER, REASON_SUB_FORCED_USER_FLAG_INTERACTION); mBgHandler.obtainMessage(BgHandler.MSG_CANCEL_REQUEST_BG_RESTRICTED, uid, 0, pkgName) .sendToTarget(); @@ -1939,11 +2112,11 @@ public final class AppRestrictionController { ? STANDBY_BUCKET_EXEMPTED : (lastLevel == RESTRICTION_LEVEL_RESTRICTED_BUCKET ? STANDBY_BUCKET_RESTRICTED : STANDBY_BUCKET_RARE); - final @RestrictionLevel int level = calcAppRestrictionLevel( + final Pair levelTypePair = calcAppRestrictionLevel( UserHandle.getUserId(uid), uid, pkgName, tentativeBucket, false, true); - applyRestrictionLevel(pkgName, uid, level, curBucket, true, - REASON_MAIN_USAGE, REASON_SUB_USAGE_USER_INTERACTION); + applyRestrictionLevel(pkgName, uid, levelTypePair.first, levelTypePair.second, + curBucket, true, REASON_MAIN_USAGE, REASON_SUB_USAGE_USER_INTERACTION); } } @@ -1983,10 +2156,10 @@ public final class AppRestrictionController { @UserIdInt int userId) { final int uid = mInjector.getPackageManagerInternal().getPackageUid( packageName, STOCK_PM_FLAGS, userId); - final @RestrictionLevel int level = calcAppRestrictionLevel( + final Pair levelTypePair = calcAppRestrictionLevel( userId, uid, packageName, bucket, false, false); - applyRestrictionLevel(packageName, uid, level, bucket, false, - REASON_MAIN_DEFAULT, REASON_SUB_DEFAULT_UNDEFINED); + applyRestrictionLevel(packageName, uid, levelTypePair.first, levelTypePair.second, + bucket, false, REASON_MAIN_DEFAULT, REASON_SUB_DEFAULT_UNDEFINED); } void handleRequestBgRestricted(String packageName, int uid) { diff --git a/services/core/java/com/android/server/am/BaseAppStateTracker.java b/services/core/java/com/android/server/am/BaseAppStateTracker.java index cb21a4bf8f22..5afcecaa069e 100644 --- a/services/core/java/com/android/server/am/BaseAppStateTracker.java +++ b/services/core/java/com/android/server/am/BaseAppStateTracker.java @@ -40,6 +40,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.app.IAppOpsService; import com.android.server.DeviceIdleInternal; import com.android.server.LocalServices; +import com.android.server.am.AppRestrictionController.TrackerType; import com.android.server.notification.NotificationManagerInternal; import com.android.server.pm.UserManagerInternal; import com.android.server.pm.permission.PermissionManagerServiceInternal; @@ -160,6 +161,13 @@ public abstract class BaseAppStateTracker { } } + /** + * Return the type of tracker (as defined by AppRestrictionController.TrackerType) + */ + @TrackerType int getType() { + return AppRestrictionController.TRACKER_TYPE_UNKNOWN; + } + /** * Return the policy holder of this tracker. */