Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd746977 authored by Varun Shah's avatar Varun Shah
Browse files

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
parent 3afb3e19
Loading
Loading
Loading
Loading
+15 −13
Original line number Diff line number Diff line
@@ -269,10 +269,10 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
                        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 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
    }

    /**
     * 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 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
                bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_BACKGROUND];
        final double usageFgs =
                bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_FOREGROUND_SERVICE];
        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);
+58 −30
Original line number Diff line number Diff line
@@ -328,6 +328,8 @@ public final class AppRestrictionController {
    })
    @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 @@ public final class AppRestrictionController {
                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 @@ public final class AppRestrictionController {
        }
    }

    /**
     * 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 @@ public final class AppRestrictionController {
                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 @@ public final class AppRestrictionController {
        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 @@ public final class AppRestrictionController {
        }
    }

    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 @@ public final class AppRestrictionController {
            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 @@ public final class AppRestrictionController {
                        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 @@ public final class AppRestrictionController {
            }
            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 @@ public final class AppRestrictionController {
    }

    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 @@ public final class AppRestrictionController {
                    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 @@ 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,
                    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 @@ public final class AppRestrictionController {
                    ? 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 @@ public final class AppRestrictionController {
            @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);
+7 −0
Original line number Diff line number Diff line
@@ -168,6 +168,13 @@ public abstract class BaseAppStateTracker<T extends BaseAppStatePolicy> {
        return AppRestrictionController.TRACKER_TYPE_UNKNOWN;
    }

    /**
     * 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.
     */