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

Commit 12752132 authored by Kweku Adams's avatar Kweku Adams
Browse files

Create standby bucket changed atom.

We'll use the data from the atom events to further optimize our quotas.

Bug: 135417506
Bug: 143495340
Bug: 149869487
Test: Use statsd_testdrive to test WakeupAlarmOccurred and
AppStandbyBucketChanged are both logged properly

Change-Id: Id05304175dea804d83f6056bf4da2e049496d87d
parent 21e618d9
Loading
Loading
Loading
Loading
+34 −20
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED_BY_USER;
import static android.app.usage.UsageStatsManager.REASON_MAIN_MASK;
import static android.app.usage.UsageStatsManager.REASON_MAIN_PREDICTED;
import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE;
import static android.app.usage.UsageStatsManager.REASON_SUB_MASK;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_USER_INTERACTION;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_NEVER;
@@ -43,6 +44,7 @@ import android.util.Xml;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.CollectionUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;

import libcore.io.IoUtils;
@@ -244,9 +246,9 @@ public class AppIdleHistory {
     * @param elapsedRealtime mark as used time if non-zero
     * @param timeout set the timeout of the specified bucket, if non-zero. Can only be used
     *                with bucket values of ACTIVE and WORKING_SET.
     * @return
     * @return {@code appUsageHistory}
     */
    public AppUsageHistory reportUsage(AppUsageHistory appUsageHistory, String packageName,
    AppUsageHistory reportUsage(AppUsageHistory appUsageHistory, String packageName, int userId,
            int newBucket, int usageReason, long elapsedRealtime, long timeout) {
        int bucketingReason = REASON_MAIN_USAGE | usageReason;
        final boolean isUserUsage = isUserUsage(bucketingReason);
@@ -284,11 +286,7 @@ public class AppIdleHistory {

        if (appUsageHistory.currentBucket > newBucket) {
            appUsageHistory.currentBucket = newBucket;
            if (DEBUG) {
                Slog.d(TAG, "Moved " + packageName + " to bucket=" + appUsageHistory
                        .currentBucket
                        + ", reason=0x0" + Integer.toHexString(appUsageHistory.bucketingReason));
            }
            logAppStandbyBucketChanged(packageName, userId, newBucket, bucketingReason);
        }
        appUsageHistory.bucketingReason = bucketingReason;

@@ -313,7 +311,8 @@ public class AppIdleHistory {
            int usageReason, long nowElapsed, long timeout) {
        ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
        AppUsageHistory history = getPackageHistory(userHistory, packageName, nowElapsed, true);
        return reportUsage(history, packageName, newBucket, usageReason, nowElapsed, timeout);
        return reportUsage(history, packageName, userId, newBucket, usageReason, nowElapsed,
                timeout);
    }

    private ArrayMap<String, AppUsageHistory> getUserHistory(int userId) {
@@ -372,6 +371,7 @@ public class AppIdleHistory {
        ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
        AppUsageHistory appUsageHistory =
                getPackageHistory(userHistory, packageName, elapsedRealtime, true);
        final boolean changed = appUsageHistory.currentBucket != bucket;
        appUsageHistory.currentBucket = bucket;
        appUsageHistory.bucketingReason = reason;

@@ -385,9 +385,8 @@ public class AppIdleHistory {
            appUsageHistory.bucketActiveTimeoutTime = elapsed;
            appUsageHistory.bucketWorkingSetTimeoutTime = elapsed;
        }
        if (DEBUG) {
            Slog.d(TAG, "Moved " + packageName + " to bucket=" + appUsageHistory.currentBucket
                    + ", reason=0x0" + Integer.toHexString(appUsageHistory.bucketingReason));
        if (changed) {
            logAppStandbyBucketChanged(packageName, userId, bucket, reason);
        }
    }

@@ -485,18 +484,19 @@ public class AppIdleHistory {

    /* Returns the new standby bucket the app is assigned to */
    public int setIdle(String packageName, int userId, boolean idle, long elapsedRealtime) {
        ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
        AppUsageHistory appUsageHistory = getPackageHistory(userHistory, packageName,
                elapsedRealtime, true);
        final int newBucket;
        final int reason;
        if (idle) {
            appUsageHistory.currentBucket = STANDBY_BUCKET_RARE;
            appUsageHistory.bucketingReason = REASON_MAIN_FORCED_BY_USER;
            newBucket = STANDBY_BUCKET_RARE;
            reason = REASON_MAIN_FORCED_BY_USER;
        } else {
            appUsageHistory.currentBucket = STANDBY_BUCKET_ACTIVE;
            newBucket = STANDBY_BUCKET_ACTIVE;
            // This is to pretend that the app was just used, don't freeze the state anymore.
            appUsageHistory.bucketingReason = REASON_MAIN_USAGE | REASON_SUB_USAGE_USER_INTERACTION;
            reason = REASON_MAIN_USAGE | REASON_SUB_USAGE_USER_INTERACTION;
        }
        return appUsageHistory.currentBucket;
        setAppStandbyBucket(packageName, userId, elapsedRealtime, newBucket, reason, false);

        return newBucket;
    }

    public void clearUsage(String packageName, int userId) {
@@ -551,13 +551,27 @@ public class AppIdleHistory {
        return 0;
    }

    /**
     * Log a standby bucket change to statsd, and also logcat if debug logging is enabled.
     */
    private void logAppStandbyBucketChanged(String packageName, int userId, int bucket,
            int reason) {
        FrameworkStatsLog.write(
                FrameworkStatsLog.APP_STANDBY_BUCKET_CHANGED,
                packageName, userId, bucket,
                (reason & REASON_MAIN_MASK), (reason & REASON_SUB_MASK));
        if (DEBUG) {
            Slog.d(TAG, "Moved " + packageName + " to bucket=" + bucket
                    + ", reason=0x0" + Integer.toHexString(reason));
        }
    }

    @VisibleForTesting
    File getUserFile(int userId) {
        return new File(new File(new File(mStorageDir, "users"),
                Integer.toString(userId)), APP_IDLE_FILENAME);
    }


    /**
     * Check if App Idle File exists on disk
     * @param userId
+4 −4
Original line number Diff line number Diff line
@@ -831,24 +831,24 @@ public class AppStandbyController implements AppStandbyInternal {
        if (eventType == UsageEvents.Event.NOTIFICATION_SEEN
                || eventType == UsageEvents.Event.SLICE_PINNED) {
            // Mild usage elevates to WORKING_SET but doesn't change usage time.
            mAppIdleHistory.reportUsage(appHistory, pkg,
            mAppIdleHistory.reportUsage(appHistory, pkg, userId,
                    STANDBY_BUCKET_WORKING_SET, subReason,
                    0, elapsedRealtime + mNotificationSeenTimeoutMillis);
            nextCheckDelay = mNotificationSeenTimeoutMillis;
        } else if (eventType == UsageEvents.Event.SYSTEM_INTERACTION) {
            mAppIdleHistory.reportUsage(appHistory, pkg,
            mAppIdleHistory.reportUsage(appHistory, pkg, userId,
                    STANDBY_BUCKET_ACTIVE, subReason,
                    0, elapsedRealtime + mSystemInteractionTimeoutMillis);
            nextCheckDelay = mSystemInteractionTimeoutMillis;
        } else if (eventType == UsageEvents.Event.FOREGROUND_SERVICE_START) {
            // Only elevate bucket if this is the first usage of the app
            if (prevBucket != STANDBY_BUCKET_NEVER) return;
            mAppIdleHistory.reportUsage(appHistory, pkg,
            mAppIdleHistory.reportUsage(appHistory, pkg, userId,
                    STANDBY_BUCKET_ACTIVE, subReason,
                    0, elapsedRealtime + mInitialForegroundServiceStartTimeoutMillis);
            nextCheckDelay = mInitialForegroundServiceStartTimeoutMillis;
        } else {
            mAppIdleHistory.reportUsage(appHistory, pkg,
            mAppIdleHistory.reportUsage(appHistory, pkg, userId,
                    STANDBY_BUCKET_ACTIVE, subReason,
                    elapsedRealtime, elapsedRealtime + mStrongUsageTimeoutMillis);
            nextCheckDelay = mStrongUsageTimeoutMillis;
+44 −11
Original line number Diff line number Diff line
@@ -396,6 +396,7 @@ message Atom {
        ForegroundServiceAppOpSessionEnded foreground_service_app_op_session_ended =
            256  [(module) = "framework"];
        DisplayJankReported display_jank_reported = 257;
        AppStandbyBucketChanged app_standby_bucket_changed = 258 [(module) = "framework"];
        SdkExtensionStatus sdk_extension_status = 354;
    }

@@ -1227,18 +1228,8 @@ message WakeupAlarmOccurred {
    // Name of source package (for historical reasons, since BatteryStats tracked it).
    optional string package_name = 3;

    // These enum values match the STANDBY_BUCKET_XXX constants defined in UsageStatsManager.java.
    enum Bucket {
        UNKNOWN = 0;
        EXEMPTED = 5;
        ACTIVE = 10;
        WORKING_SET = 20;
        FREQUENT = 30;
        RARE = 40;
        NEVER = 50;
    }
    // The App Standby bucket of the app that scheduled the alarm at the time the alarm fired.
    optional Bucket app_standby_bucket = 4;
    optional AppStandbyBucketChanged.Bucket app_standby_bucket = 4;
}

/**
@@ -8724,3 +8715,45 @@ message GnssStats {
    // Total number of L5 sv status messages reports, where sv is used in fix since boot
    optional int64 l5_sv_status_reports_used_in_fix = 14;
}

/**
 * Logs when an app is moved to a different standby bucket.
 *
 * Logged from:
 *   frameworks/base/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
 */
message AppStandbyBucketChanged {
    optional string package_name = 1;

    // Should be 0, 10, 11, 12, etc. where 0 is the owner. See UserHandle for more documentation.
    optional int32 user_id = 2;

    // These enum values match the constants defined in UsageStatsManager.java.
    enum Bucket {
        BUCKET_UNKNOWN = 0;
        BUCKET_EXEMPTED = 5;
        BUCKET_ACTIVE = 10;
        BUCKET_WORKING_SET = 20;
        BUCKET_FREQUENT = 30;
        BUCKET_RARE = 40;
        BUCKET_RESTRICTED = 45;
        BUCKET_NEVER = 50;
    }
    optional Bucket bucket = 3;

    enum MainReason {
        MAIN_UNKNOWN = 0;
        MAIN_DEFAULT = 0x0100;
        MAIN_TIMEOUT = 0x0200;
        MAIN_USAGE = 0x0300;
        MAIN_FORCED_BY_USER = 0x0400;
        MAIN_PREDICTED = 0x0500;
        MAIN_FORCED_BY_SYSTEM = 0x0600;
    }
    optional MainReason main_reason = 4;

    // A more detailed reason for the standby bucket change. The sub reason name is dependent on
    // the main reason. Values are one of the REASON_SUB_XXX constants defined in
    // UsageStatsManager.java.
    optional int32 sub_reason = 5;
}