Link BatteryTrackerInfo to the metrics logging.
Add a new interface method for state trackers to implement
when AppRestrictionController asks for relevant tracker info
for logging.
This CL specifically links the info from AppBatteryTracker.
Bug: 217744262
Test: statsd_testdrive 441
Change-Id: Ie97653e804a00a240bcff80556b6e5532e4becf4
diff --git a/services/core/java/com/android/server/am/AppBatteryTracker.java b/services/core/java/com/android/server/am/AppBatteryTracker.java
index 8c42d4d..6fa13eb 100644
--- a/services/core/java/com/android/server/am/AppBatteryTracker.java
+++ b/services/core/java/com/android/server/am/AppBatteryTracker.java
@@ -269,10 +269,10 @@
AppBackgroundRestrictionsInfo.LEVEL_UNKNOWN, // RestrictionLevel
AppBackgroundRestrictionsInfo.THRESHOLD_UNKNOWN,
AppBackgroundRestrictionsInfo.UNKNOWN_TRACKER,
- null /*byte[] fgs_tracker_info*/,
- getBatteryTrackerInfoProtoLocked(uid) /*byte[] battery_tracker_info*/,
- null /*byte[] broadcast_events_tracker_info*/,
- null /*byte[] bind_service_events_tracker_info*/,
+ null, // FgsTrackerInfo
+ getTrackerInfoForStatsd(uid),
+ null, // BroadcastEventsTrackerInfo
+ null, // BindServiceEventsTrackerInfo
AppBackgroundRestrictionsInfo.REASON_UNKNOWN, // ExemptionReason
AppBackgroundRestrictionsInfo.UNKNOWN, // OptimizationLevel
AppBackgroundRestrictionsInfo.SDK_UNKNOWN, // TargetSdk
@@ -282,14 +282,14 @@
}
/**
- * Get the BatteryTrackerInfo proto of a UID.
- * @param uid
- * @return byte array of the proto.
+ * Get the BatteryTrackerInfo object of the given uid.
+ * @return byte array of the proto object.
*/
- @NonNull byte[] getBatteryTrackerInfoProtoLocked(int uid) {
+ @Override
+ byte[] getTrackerInfoForStatsd(int uid) {
final ImmutableBatteryUsage temp = mUidBatteryUsageInWindow.get(uid);
if (temp == null) {
- return new byte[0];
+ return null;
}
final BatteryUsage bgUsage = temp.calcPercentage(uid, mInjector.getPolicy());
final double allUsage = bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_UNSPECIFIED]
@@ -301,10 +301,12 @@
bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_BACKGROUND];
final double usageFgs =
bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_FOREGROUND_SERVICE];
- Slog.d(TAG, "getBatteryTrackerInfoProtoLocked uid:" + uid
- + " allUsage:" + String.format("%4.2f%%", allUsage)
- + " usageBackground:" + String.format("%4.2f%%", usageBackground)
- + " usageFgs:" + String.format("%4.2f%%", usageFgs));
+ if (DEBUG_BACKGROUND_BATTERY_TRACKER_VERBOSE) {
+ Slog.d(TAG, "getBatteryTrackerInfoProtoLocked uid:" + uid
+ + " allUsage:" + String.format("%4.2f%%", allUsage)
+ + " usageBackground:" + String.format("%4.2f%%", usageBackground)
+ + " usageFgs:" + String.format("%4.2f%%", usageFgs));
+ }
final ProtoOutputStream proto = new ProtoOutputStream();
proto.write(AppBackgroundRestrictionsInfo.BatteryTrackerInfo.BATTERY_24H,
allUsage * 10000);
diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java
index d70404f..519f7dd 100644
--- a/services/core/java/com/android/server/am/AppRestrictionController.java
+++ b/services/core/java/com/android/server/am/AppRestrictionController.java
@@ -328,6 +328,8 @@
})
@interface TrackerType {}
+ private final TrackerInfo mEmptyTrackerInfo = new TrackerInfo();
+
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -914,7 +916,7 @@
final int curBucket = mInjector.getAppStandbyInternal().getAppStandbyBucket(
packageName, UserHandle.getUserId(uid), now, false);
if (applyLevel) {
- applyRestrictionLevel(packageName, uid, curLevel, TRACKER_TYPE_UNKNOWN,
+ applyRestrictionLevel(packageName, uid, curLevel, mEmptyTrackerInfo,
curBucket, true, reason & REASON_MAIN_MASK, reason & REASON_SUB_MASK);
} else {
pkgSettings.update(curLevel,
@@ -1331,6 +1333,25 @@
}
}
+ /**
+ * A helper object which holds an app state tracker's type and its relevant info used for
+ * logging atoms to statsd.
+ */
+ private class TrackerInfo {
+ final int mType; // tracker type
+ final byte[] mInfo; // tracker info proto object for statsd
+
+ TrackerInfo() {
+ mType = TRACKER_TYPE_UNKNOWN;
+ mInfo = null;
+ }
+
+ TrackerInfo(int type, byte[] info) {
+ mType = type;
+ mInfo = info;
+ }
+ }
+
private final ConstantsObserver mConstantsObserver;
private final AppStateTracker.BackgroundRestrictedAppListener mBackgroundRestrictionListener =
@@ -1578,7 +1599,7 @@
Slog.e(TAG, "Unable to find " + info.mPackageName + "/u" + userId);
continue;
}
- final Pair<Integer, Integer> levelTypePair = calcAppRestrictionLevel(
+ final Pair<Integer, TrackerInfo> levelTypePair = calcAppRestrictionLevel(
userId, uid, info.mPackageName, info.mStandbyBucket, false, false);
if (DEBUG_BG_RESTRICTION_CONTROLLER) {
Slog.i(TAG, "Proposed restriction level of " + info.mPackageName + "/"
@@ -1602,8 +1623,8 @@
final long now = SystemClock.elapsedRealtime();
for (String pkg: packages) {
final int curBucket = appStandbyInternal.getAppStandbyBucket(pkg, userId, now, false);
- final Pair<Integer, Integer> levelTypePair = calcAppRestrictionLevel(userId, uid, pkg,
- curBucket, allowRequestBgRestricted, true);
+ final Pair<Integer, TrackerInfo> levelTypePair = calcAppRestrictionLevel(userId, uid,
+ pkg, curBucket, allowRequestBgRestricted, true);
if (DEBUG_BG_RESTRICTION_CONTROLLER) {
Slog.i(TAG, "Proposed restriction level of " + pkg + "/"
+ UserHandle.formatUid(uid) + ": "
@@ -1614,14 +1635,14 @@
}
}
- private Pair<Integer, Integer> calcAppRestrictionLevel(@UserIdInt int userId, int uid,
+ private Pair<Integer, TrackerInfo> calcAppRestrictionLevel(@UserIdInt int userId, int uid,
String packageName, @UsageStatsManager.StandbyBuckets int standbyBucket,
boolean allowRequestBgRestricted, boolean calcTrackers) {
if (mInjector.getAppHibernationInternal().isHibernatingForUser(packageName, userId)) {
- return new Pair<>(RESTRICTION_LEVEL_HIBERNATION, TRACKER_TYPE_UNKNOWN);
+ return new Pair<>(RESTRICTION_LEVEL_HIBERNATION, mEmptyTrackerInfo);
}
@RestrictionLevel int level;
- @TrackerType int trackerType = TRACKER_TYPE_UNKNOWN;
+ TrackerInfo trackerInfo = null;
switch (standbyBucket) {
case STANDBY_BUCKET_EXEMPTED:
level = RESTRICTION_LEVEL_EXEMPTED;
@@ -1637,22 +1658,22 @@
default:
if (mInjector.getAppStateTracker()
.isAppBackgroundRestricted(uid, packageName)) {
- return new Pair<>(RESTRICTION_LEVEL_BACKGROUND_RESTRICTED, trackerType);
+ return new Pair<>(RESTRICTION_LEVEL_BACKGROUND_RESTRICTED, mEmptyTrackerInfo);
}
level = mConstantsObserver.mRestrictedBucketEnabled
&& standbyBucket == STANDBY_BUCKET_RESTRICTED
? RESTRICTION_LEVEL_RESTRICTED_BUCKET
: RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
if (calcTrackers) {
- Pair<Integer, Integer> levelTypePair = calcAppRestrictionLevelFromTackers(
+ Pair<Integer, TrackerInfo> levelTypePair = calcAppRestrictionLevelFromTackers(
uid, packageName, RESTRICTION_LEVEL_MAX);
@RestrictionLevel int l = levelTypePair.first;
if (l == RESTRICTION_LEVEL_EXEMPTED) {
return new Pair<>(RESTRICTION_LEVEL_EXEMPTED, levelTypePair.second);
}
- level = Math.max(l, level);
- if (l == level) {
- trackerType = levelTypePair.second;
+ if (l > level) {
+ level = l;
+ trackerInfo = levelTypePair.second;
}
if (level == RESTRICTION_LEVEL_BACKGROUND_RESTRICTED) {
// This level can't be entered without user consent
@@ -1664,29 +1685,29 @@
levelTypePair = calcAppRestrictionLevelFromTackers(uid, packageName,
RESTRICTION_LEVEL_BACKGROUND_RESTRICTED);
level = levelTypePair.first;
- trackerType = levelTypePair.second;
+ trackerInfo = levelTypePair.second;
}
}
break;
}
- return new Pair<>(level, trackerType);
+ return new Pair<>(level, trackerInfo);
}
/**
* Ask each of the trackers for their proposed restriction levels for the given uid/package,
- * and return the most restrictive level along with the type of tracker which applied this
- * restriction level as a {@code Pair<@RestrictionLevel, @TrackerType>}.
+ * and return the most restrictive level along with the type of tracker and its relevant info
+ * which applied this restriction level as a {@code Pair<@RestrictionLevel, TrackerInfo>}.
*
* <p>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. </p>
*/
- private Pair<Integer, Integer> calcAppRestrictionLevelFromTackers(int uid, String packageName,
- @RestrictionLevel int maxLevel) {
+ private Pair<Integer, TrackerInfo> calcAppRestrictionLevelFromTackers(int uid,
+ String packageName, @RestrictionLevel int maxLevel) {
@RestrictionLevel int level = RESTRICTION_LEVEL_UNKNOWN;
@RestrictionLevel int prevLevel = level;
- @TrackerType int trackerType = TRACKER_TYPE_UNKNOWN;
+ BaseAppStateTracker resultTracker = null;
final boolean isRestrictedBucketEnabled = mConstantsObserver.mRestrictedBucketEnabled;
for (int i = mAppStateTrackers.size() - 1; i >= 0; i--) {
@RestrictionLevel int l = mAppStateTrackers.get(i).getPolicy()
@@ -1696,11 +1717,15 @@
}
level = Math.max(level, l);
if (level != prevLevel) {
- trackerType = mAppStateTrackers.get(i).getType();
+ resultTracker = mAppStateTrackers.get(i);
prevLevel = level;
}
}
- return new Pair<>(level, trackerType);
+ final TrackerInfo trackerInfo = resultTracker == null
+ ? mEmptyTrackerInfo
+ : new TrackerInfo(resultTracker.getType(),
+ resultTracker.getTrackerInfoForStatsd(uid));
+ return new Pair<>(level, trackerInfo);
}
private static @RestrictionLevel int standbyBucketToRestrictionLevel(
@@ -2017,7 +2042,7 @@
}
private void applyRestrictionLevel(String pkgName, int uid,
- @RestrictionLevel int level, @TrackerType int trackerType,
+ @RestrictionLevel int level, TrackerInfo trackerInfo,
int curBucket, boolean allowUpdateBucket, int reason, int subReason) {
int curLevel;
int prevReason;
@@ -2098,14 +2123,17 @@
reason, subReason);
}
+ if (trackerInfo == null) {
+ trackerInfo = mEmptyTrackerInfo;
+ }
FrameworkStatsLog.write(FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO, uid,
getRestrictionLevelStatsd(level),
getThresholdStatsd(reason),
- getTrackerTypeStatsd(trackerType),
- null, // FgsTrackerInfo
- null, // BatteryTrackerInfo
- null, // BroadcastEventsTrackerInfo
- null, // BindServiceEventsTrackerInfo
+ getTrackerTypeStatsd(trackerInfo.mType),
+ trackerInfo.mType == TRACKER_TYPE_FGS ? trackerInfo.mInfo : null,
+ trackerInfo.mType == TRACKER_TYPE_BATTERY ? trackerInfo.mInfo : null,
+ trackerInfo.mType == TRACKER_TYPE_BROADCAST_EVENTS ? trackerInfo.mInfo : null,
+ trackerInfo.mType == TRACKER_TYPE_BIND_SERVICE_EVENTS ? trackerInfo.mInfo : null,
getExemptionReasonStatsd(uid, level),
getOptimizationLevelStatsd(level),
getTargetSdkStatsd(pkgName),
@@ -2127,7 +2155,7 @@
// 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,
- TRACKER_TYPE_UNKNOWN, curBucket, true, REASON_MAIN_FORCED_BY_USER,
+ mEmptyTrackerInfo, 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();
@@ -2140,7 +2168,7 @@
? STANDBY_BUCKET_EXEMPTED
: (lastLevel == RESTRICTION_LEVEL_RESTRICTED_BUCKET
? STANDBY_BUCKET_RESTRICTED : STANDBY_BUCKET_RARE);
- final Pair<Integer, Integer> levelTypePair = calcAppRestrictionLevel(
+ final Pair<Integer, TrackerInfo> levelTypePair = calcAppRestrictionLevel(
UserHandle.getUserId(uid), uid, pkgName, tentativeBucket, false, true);
applyRestrictionLevel(pkgName, uid, levelTypePair.first, levelTypePair.second,
@@ -2184,7 +2212,7 @@
@UserIdInt int userId) {
final int uid = mInjector.getPackageManagerInternal().getPackageUid(
packageName, STOCK_PM_FLAGS, userId);
- final Pair<Integer, Integer> levelTypePair = calcAppRestrictionLevel(
+ final Pair<Integer, TrackerInfo> levelTypePair = calcAppRestrictionLevel(
userId, uid, packageName, bucket, false, false);
applyRestrictionLevel(packageName, uid, levelTypePair.first, levelTypePair.second,
bucket, false, REASON_MAIN_DEFAULT, REASON_SUB_DEFAULT_UNDEFINED);
diff --git a/services/core/java/com/android/server/am/BaseAppStateTracker.java b/services/core/java/com/android/server/am/BaseAppStateTracker.java
index 5afceca..8d60910 100644
--- a/services/core/java/com/android/server/am/BaseAppStateTracker.java
+++ b/services/core/java/com/android/server/am/BaseAppStateTracker.java
@@ -169,6 +169,13 @@
}
/**
+ * Return the relevant info object for the tracker for the given uid, used for statsd.
+ */
+ byte[] getTrackerInfoForStatsd(int uid) {
+ return null;
+ }
+
+ /**
* Return the policy holder of this tracker.
*/
T getPolicy() {