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

Commit e8789314 authored by Amith Yamasani's avatar Amith Yamasani
Browse files

Allow multiple standby buckets to be set in one IPC

SystemApi to pass a map of packagename to bucket mapping.
Reduces the number of IPC calls to be made by bucketing
ML app.

Bug: 63527785
Test: atest CtsAppUsageHostTestCases
Change-Id: I4172fd30cc310092a1f182ae26267de9148009b7
parent b8f2728a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -613,7 +613,9 @@ package android.app.usage {

  public final class UsageStatsManager {
    method public int getAppStandbyBucket(java.lang.String);
    method public java.util.Map<java.lang.String, java.lang.Integer> getAppStandbyBuckets();
    method public void setAppStandbyBucket(java.lang.String, int);
    method public void setAppStandbyBuckets(java.util.Map<java.lang.String, java.lang.Integer>);
    method public void whitelistAppTemporarily(java.lang.String, long, android.os.UserHandle);
    field public static final int STANDBY_BUCKET_EXEMPTED = 5; // 0x5
    field public static final int STANDBY_BUCKET_NEVER = 50; // 0x32
+4 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package android.app.usage;
import android.app.usage.UsageEvents;
import android.content.pm.ParceledListSlice;

import java.util.Map;

/**
 * System private API for talking with the UsageStatsManagerService.
 *
@@ -38,4 +40,6 @@ interface IUsageStatsManager {
            in String[] annotations, String action);
    int getAppStandbyBucket(String packageName, String callingPackage, int userId);
    void setAppStandbyBucket(String packageName, int bucket, int userId);
    Map getAppStandbyBuckets(String callingPackage, int userId);
    void setAppStandbyBuckets(in Map appBuckets, int userId);
}
+42 −3
Original line number Diff line number Diff line
@@ -324,11 +324,11 @@ public final class UsageStatsManager {
     * state of the app based on app usage patterns. Standby buckets determine how much an app will
     * be restricted from running background tasks such as jobs, alarms and certain PendingIntent
     * callbacks.
     * Restrictions increase progressively from {@link #STANDBY_BUCKET_ACTIVE} to
     * <p>Restrictions increase progressively from {@link #STANDBY_BUCKET_ACTIVE} to
     * {@link #STANDBY_BUCKET_RARE}, with {@link #STANDBY_BUCKET_ACTIVE} being the least
     * restrictive. The battery level of the device might also affect the restrictions.
     *
     * @return the current standby bucket of the calling app.
     * @return the current standby bucket of the calling app. One of STANDBY_BUCKET_* constants.
     */
    public @StandbyBuckets int getAppStandbyBucket() {
        try {
@@ -359,7 +359,13 @@ public final class UsageStatsManager {

    /**
     * {@hide}
     * Changes the app standby state to the provided bucket.
     * Changes an app's standby bucket to the provided value. The caller can only set the standby
     * bucket for a different app than itself.
     * @param packageName the package name of the app to set the bucket for. A SecurityException
     *                    will be thrown if the package name is that of the caller.
     * @param bucket the standby bucket to set it to, which should be one of STANDBY_BUCKET_*.
     *               Setting a standby bucket outside of the range of STANDBY_BUCKET_ACTIVE to
     *               STANDBY_BUCKET_NEVER will result in a SecurityException.
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.CHANGE_APP_IDLE_STATE)
@@ -371,6 +377,39 @@ public final class UsageStatsManager {
        }
    }

    /**
     * {@hide}
     * Returns the current standby bucket of every app that has a bucket assigned to it.
     * The caller must hold the permission android.permission.PACKAGE_USAGE_STATS. The key of the
     * returned Map is the package name and the value is the bucket assigned to the package.
     * @see #getAppStandbyBucket()
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
    public Map<String, Integer> getAppStandbyBuckets() {
        try {
            return (Map<String, Integer>) mService.getAppStandbyBuckets(
                    mContext.getOpPackageName(), mContext.getUserId());
        } catch (RemoteException e) {
        }
        return Collections.EMPTY_MAP;
    }

    /**
     * {@hide}
     * Changes the app standby bucket for multiple apps at once. The Map is keyed by the package
     * name and the value is one of STANDBY_BUCKET_*.
     * @param appBuckets a map of package name to bucket value.
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.CHANGE_APP_IDLE_STATE)
    public void setAppStandbyBuckets(Map<String, Integer> appBuckets) {
        try {
            mService.setAppStandbyBuckets(appBuckets, mContext.getUserId());
        } catch (RemoteException e) {
        }
    }

    /**
     * {@hide}
     * Temporarily whitelist the specified app for a short duration. This is to allow an app
+29 −4
Original line number Diff line number Diff line
@@ -69,7 +69,9 @@ import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static android.app.ActivityManager.RESIZE_MODE_SYSTEM;
import static android.app.ActivityManager.RESIZE_MODE_USER;
@@ -1867,10 +1869,24 @@ final class ActivityManagerShellCommand extends ShellCommand {
        String value = getNextArgRequired();
        int bucket = bucketNameToBucketValue(value);
        if (bucket < 0) return -1;
        boolean multiple = peekNextArg() != null;


        IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
                Context.USAGE_STATS_SERVICE));
        if (!multiple) {
            usm.setAppStandbyBucket(packageName, bucketNameToBucketValue(value), userId);
        } else {
            HashMap<String, Integer> buckets = new HashMap<>();
            buckets.put(packageName, bucket);
            while ((packageName = getNextArg()) != null) {
                value = getNextArgRequired();
                bucket = bucketNameToBucketValue(value);
                if (bucket < 0) continue;
                buckets.put(packageName, bucket);
            }
            usm.setAppStandbyBuckets(buckets, userId);
        }
        return 0;
    }

@@ -1886,12 +1902,21 @@ final class ActivityManagerShellCommand extends ShellCommand {
                return -1;
            }
        }
        String packageName = getNextArgRequired();
        String packageName = getNextArg();

        IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
                Context.USAGE_STATS_SERVICE));
        if (packageName != null) {
            int bucket = usm.getAppStandbyBucket(packageName, null, userId);
            pw.println(bucket);
        } else {
            Map<String, Integer> buckets = (Map<String, Integer>) usm.getAppStandbyBuckets(
                    SHELL_PACKAGE_NAME, userId);
            for (Map.Entry<String, Integer> entry: buckets.entrySet()) {
                pw.print(entry.getKey()); pw.print(": ");
                pw.println(entry.getValue());
            }
        }
        return 0;
    }

+12 −0
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * Keeps track of recent active state changes in apps.
@@ -334,6 +336,16 @@ public class AppIdleHistory {
        return appUsageHistory.currentBucket;
    }

    public Map<String, Integer> getAppStandbyBuckets(int userId, long elapsedRealtime) {
        ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
        int size = userHistory.size();
        HashMap<String, Integer> buckets = new HashMap<>(size);
        for (int i = 0; i < size; i++) {
            buckets.put(userHistory.keyAt(i), userHistory.valueAt(i).currentBucket);
        }
        return buckets;
    }

    public String getAppStandbyReason(String packageName, int userId, long elapsedRealtime) {
        ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
        AppUsageHistory appUsageHistory =
Loading