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

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

Move setAppStandby logic inside AppStandbyController.

Since we've moved AppStandbyController inside the JobScheduler mainline
module boundary, we need to move the logic of setAppStandby over so that
it's consistent for callers and easy to do the right thing.

Bug: 137763703
Bug: 145551233
Test: atest AppIdleHistoryTests
Test: atest AppStandbyControllerTests
Test: atest UsageStatsTest
Change-Id: Ie2ccb0508c3a3887ab3debc47e78427477d2d77b
parent 2a4b15a3
Loading
Loading
Loading
Loading
+13 −2
Original line number Original line Diff line number Diff line
package com.android.server.usage;
package com.android.server.usage;


import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.annotation.UserIdInt;
import android.app.usage.AppStandbyInfo;
import android.app.usage.AppStandbyInfo;
import android.app.usage.UsageEvents;
import android.app.usage.UsageEvents;
@@ -99,8 +100,18 @@ public interface AppStandbyInternal {


    List<AppStandbyInfo> getAppStandbyBuckets(int userId);
    List<AppStandbyInfo> getAppStandbyBuckets(int userId);


    void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
    /**
            int reason, long elapsedRealtime, boolean resetTimeout);
     * Changes an app's standby bucket to the provided value. The caller can only set the standby
     * bucket for a different app than itself.
     */
    void setAppStandbyBucket(@NonNull String packageName, int bucket, int userId, int callingUid,
            int callingPid);

    /**
     * Changes the app standby bucket for multiple apps at once.
     */
    void setAppStandbyBuckets(@NonNull List<AppStandbyInfo> appBuckets, int userId, int callingUid,
            int callingPid);


    void addActiveDeviceAdmin(String adminPkg, int userId);
    void addActiveDeviceAdmin(String adminPkg, int userId);


+53 −5
Original line number Original line Diff line number Diff line
@@ -47,6 +47,7 @@ import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET;


import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;


import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.AppGlobals;
@@ -101,7 +102,6 @@ import com.android.internal.util.ConcurrentUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
import com.android.server.LocalServices;
import com.android.server.usage.AppIdleHistory.AppUsageHistory;
import com.android.server.usage.AppIdleHistory.AppUsageHistory;
import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;


import java.io.File;
import java.io.File;
import java.io.PrintWriter;
import java.io.PrintWriter;
@@ -109,6 +109,7 @@ import java.time.Duration;
import java.time.format.DateTimeParseException;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.List;
import java.util.Set;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CountDownLatch;
@@ -1014,14 +1015,57 @@ public class AppStandbyController implements AppStandbyInternal {
        }
        }
    }
    }


    @Override
    public void setAppStandbyBucket(@NonNull String packageName, int bucket, int userId,
            int callingUid, int callingPid) {
        setAppStandbyBuckets(
                Collections.singletonList(new AppStandbyInfo(packageName, bucket)),
                userId, callingUid, callingPid);
    }

    @Override
    public void setAppStandbyBuckets(@NonNull List<AppStandbyInfo> appBuckets, int userId,
            int callingUid, int callingPid) {
        userId = ActivityManager.handleIncomingUser(
                callingPid, callingUid, userId, false, true, "setAppStandbyBucket", null);
        final boolean shellCaller = callingUid == Process.ROOT_UID
                || callingUid == Process.SHELL_UID;
        final boolean systemCaller = UserHandle.isCore(callingUid);
        final int reason = systemCaller ? REASON_MAIN_FORCED : REASON_MAIN_PREDICTED;
        final int packageFlags = PackageManager.MATCH_ANY_USER
                | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                | PackageManager.MATCH_DIRECT_BOOT_AWARE;
        final int numApps = appBuckets.size();
        final long elapsedRealtime = mInjector.elapsedRealtime();
        for (int i = 0; i < numApps; ++i) {
            final AppStandbyInfo bucketInfo = appBuckets.get(i);
            final String packageName = bucketInfo.mPackageName;
            final int bucket = bucketInfo.mStandbyBucket;
            if (bucket < STANDBY_BUCKET_ACTIVE || bucket > STANDBY_BUCKET_NEVER) {
                throw new IllegalArgumentException("Cannot set the standby bucket to " + bucket);
            }
            final int packageUid = mInjector.getPackageManagerInternal()
                    .getPackageUid(packageName, packageFlags, userId);
            // Caller cannot set their own standby state
            if (packageUid == callingUid) {
                throw new IllegalArgumentException("Cannot set your own standby bucket");
            }
            if (packageUid < 0) {
                throw new IllegalArgumentException(
                        "Cannot set standby bucket for non existent package (" + packageName + ")");
            }
            setAppStandbyBucket(packageName, userId, bucket, reason, elapsedRealtime, shellCaller);
        }
    }

    @VisibleForTesting
    @VisibleForTesting
    void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
    void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
            int reason, long elapsedRealtime) {
            int reason) {
        setAppStandbyBucket(packageName, userId, newBucket, reason, elapsedRealtime, false);
        setAppStandbyBucket(
                packageName, userId, newBucket, reason, mInjector.elapsedRealtime(), false);
    }
    }


    @Override
    private void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
    public void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
            int reason, long elapsedRealtime, boolean resetTimeout) {
            int reason, long elapsedRealtime, boolean resetTimeout) {
        synchronized (mAppIdleLock) {
        synchronized (mAppIdleLock) {
            // If the package is not installed, don't allow the bucket to be set.
            // If the package is not installed, don't allow the bucket to be set.
@@ -1444,6 +1488,10 @@ public class AppStandbyController implements AppStandbyInternal {
            mBatteryStats.noteEvent(event, packageName, uid);
            mBatteryStats.noteEvent(event, packageName, uid);
        }
        }


        PackageManagerInternal getPackageManagerInternal() {
            return mPackageManagerInternal;
        }

        boolean isPackageEphemeral(int userId, String packageName) {
        boolean isPackageEphemeral(int userId, String packageName) {
            return mPackageManagerInternal.isPackageEphemeral(userId, packageName);
            return mPackageManagerInternal.isPackageEphemeral(userId, packageName);
        }
        }
+27 −21
Original line number Original line Diff line number Diff line
@@ -365,8 +365,9 @@ public class AppStandbyControllerTests {
    public void testSetAppStandbyBucket() throws Exception {
    public void testSetAppStandbyBucket() throws Exception {
        // For a known package, standby bucket should be set properly
        // For a known package, standby bucket should be set properly
        reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
        reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
        mInjector.mElapsedRealtime = HOUR_MS;
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
                REASON_MAIN_TIMEOUT, HOUR_MS);
                REASON_MAIN_TIMEOUT);
        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));


        // For an unknown package, standby bucket should not be set, hence NEVER is returned
        // For an unknown package, standby bucket should not be set, hence NEVER is returned
@@ -374,7 +375,7 @@ public class AppStandbyControllerTests {
        mController.clearAppIdleForPackage(PACKAGE_UNKNOWN, USER_ID);
        mController.clearAppIdleForPackage(PACKAGE_UNKNOWN, USER_ID);
        isPackageInstalled = false; // Mock package is not installed
        isPackageInstalled = false; // Mock package is not installed
        mController.setAppStandbyBucket(PACKAGE_UNKNOWN, USER_ID, STANDBY_BUCKET_ACTIVE,
        mController.setAppStandbyBucket(PACKAGE_UNKNOWN, USER_ID, STANDBY_BUCKET_ACTIVE,
                REASON_MAIN_TIMEOUT, HOUR_MS);
                REASON_MAIN_TIMEOUT);
        isPackageInstalled = true; // Reset mocked variable for other tests
        isPackageInstalled = true; // Reset mocked variable for other tests
        assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController, PACKAGE_UNKNOWN));
        assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController, PACKAGE_UNKNOWN));
    }
    }
@@ -468,12 +469,13 @@ public class AppStandbyControllerTests {
    @Test
    @Test
    public void testPredictionTimedout() throws Exception {
    public void testPredictionTimedout() throws Exception {
        // Set it to timeout or usage, so that prediction can override it
        // Set it to timeout or usage, so that prediction can override it
        mInjector.mElapsedRealtime = HOUR_MS;
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE,
                REASON_MAIN_TIMEOUT, HOUR_MS);
                REASON_MAIN_TIMEOUT);
        assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1));
        assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1));


        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
                REASON_MAIN_PREDICTED, HOUR_MS);
                REASON_MAIN_PREDICTED);
        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));


        // Fast forward 12 hours
        // Fast forward 12 hours
@@ -497,29 +499,31 @@ public class AppStandbyControllerTests {
    @Test
    @Test
    public void testOverrides() throws Exception {
    public void testOverrides() throws Exception {
        // Can force to NEVER
        // Can force to NEVER
        mInjector.mElapsedRealtime = HOUR_MS;
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
                REASON_MAIN_FORCED, 1 * HOUR_MS);
                REASON_MAIN_FORCED);
        assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController, PACKAGE_1));
        assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController, PACKAGE_1));


        // Prediction can't override FORCED reason
        // Prediction can't override FORCED reason
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
                REASON_MAIN_FORCED, 1 * HOUR_MS);
                REASON_MAIN_FORCED);
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_WORKING_SET,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_WORKING_SET,
                REASON_MAIN_PREDICTED, 1 * HOUR_MS);
                REASON_MAIN_PREDICTED);
        assertEquals(STANDBY_BUCKET_FREQUENT, getStandbyBucket(mController, PACKAGE_1));
        assertEquals(STANDBY_BUCKET_FREQUENT, getStandbyBucket(mController, PACKAGE_1));


        // Prediction can't override NEVER
        // Prediction can't override NEVER
        mInjector.mElapsedRealtime = 2 * HOUR_MS;
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
                REASON_MAIN_DEFAULT, 2 * HOUR_MS);
                REASON_MAIN_DEFAULT);
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
                REASON_MAIN_PREDICTED, 2 * HOUR_MS);
                REASON_MAIN_PREDICTED);
        assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController, PACKAGE_1));
        assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController, PACKAGE_1));


        // Prediction can't set to NEVER
        // Prediction can't set to NEVER
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
                REASON_MAIN_USAGE, 2 * HOUR_MS);
                REASON_MAIN_USAGE);
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
                REASON_MAIN_PREDICTED, 2 * HOUR_MS);
                REASON_MAIN_PREDICTED);
        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
    }
    }


@@ -530,7 +534,7 @@ public class AppStandbyControllerTests {


        mInjector.mElapsedRealtime = 2000;
        mInjector.mElapsedRealtime = 2000;
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
                REASON_MAIN_PREDICTED, mInjector.mElapsedRealtime);
                REASON_MAIN_PREDICTED);
        assertBucket(STANDBY_BUCKET_ACTIVE);
        assertBucket(STANDBY_BUCKET_ACTIVE);


        // bucketing works after timeout
        // bucketing works after timeout
@@ -554,15 +558,17 @@ public class AppStandbyControllerTests {
        assertBucket(STANDBY_BUCKET_ACTIVE);
        assertBucket(STANDBY_BUCKET_ACTIVE);


        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_WORKING_SET,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_WORKING_SET,
                REASON_MAIN_PREDICTED, 1000);
                REASON_MAIN_PREDICTED);
        assertBucket(STANDBY_BUCKET_ACTIVE);
        assertBucket(STANDBY_BUCKET_ACTIVE);


        mInjector.mElapsedRealtime = 2000 + mController.mStrongUsageTimeoutMillis;
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
                REASON_MAIN_PREDICTED, 2000 + mController.mStrongUsageTimeoutMillis);
                REASON_MAIN_PREDICTED);
        assertBucket(STANDBY_BUCKET_WORKING_SET);
        assertBucket(STANDBY_BUCKET_WORKING_SET);


        mInjector.mElapsedRealtime = 2000 + mController.mNotificationSeenTimeoutMillis;
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
                REASON_MAIN_PREDICTED, 2000 + mController.mNotificationSeenTimeoutMillis);
                REASON_MAIN_PREDICTED);
        assertBucket(STANDBY_BUCKET_FREQUENT);
        assertBucket(STANDBY_BUCKET_FREQUENT);
    }
    }


@@ -582,18 +588,18 @@ public class AppStandbyControllerTests {
        // Still in ACTIVE after first USER_INTERACTION times out
        // Still in ACTIVE after first USER_INTERACTION times out
        mInjector.mElapsedRealtime = mController.mStrongUsageTimeoutMillis + 1000;
        mInjector.mElapsedRealtime = mController.mStrongUsageTimeoutMillis + 1000;
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
                REASON_MAIN_PREDICTED, mInjector.mElapsedRealtime);
                REASON_MAIN_PREDICTED);
        assertBucket(STANDBY_BUCKET_ACTIVE);
        assertBucket(STANDBY_BUCKET_ACTIVE);


        // Both timed out, so NOTIFICATION_SEEN timeout should be effective
        // Both timed out, so NOTIFICATION_SEEN timeout should be effective
        mInjector.mElapsedRealtime = mController.mStrongUsageTimeoutMillis * 2 + 2000;
        mInjector.mElapsedRealtime = mController.mStrongUsageTimeoutMillis * 2 + 2000;
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
                REASON_MAIN_PREDICTED, mInjector.mElapsedRealtime);
                REASON_MAIN_PREDICTED);
        assertBucket(STANDBY_BUCKET_WORKING_SET);
        assertBucket(STANDBY_BUCKET_WORKING_SET);


        mInjector.mElapsedRealtime = mController.mNotificationSeenTimeoutMillis + 2000;
        mInjector.mElapsedRealtime = mController.mNotificationSeenTimeoutMillis + 2000;
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE,
                REASON_MAIN_PREDICTED, mInjector.mElapsedRealtime);
                REASON_MAIN_PREDICTED);
        assertBucket(STANDBY_BUCKET_RARE);
        assertBucket(STANDBY_BUCKET_RARE);
    }
    }


@@ -625,7 +631,7 @@ public class AppStandbyControllerTests {
        mInjector.mElapsedRealtime = 1 * RARE_THRESHOLD + 100;
        mInjector.mElapsedRealtime = 1 * RARE_THRESHOLD + 100;
        // Make sure app is in NEVER bucket
        // Make sure app is in NEVER bucket
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
                REASON_MAIN_FORCED, mInjector.mElapsedRealtime);
                REASON_MAIN_FORCED);
        mController.checkIdleStates(USER_ID);
        mController.checkIdleStates(USER_ID);
        assertBucket(STANDBY_BUCKET_NEVER);
        assertBucket(STANDBY_BUCKET_NEVER);


@@ -670,7 +676,7 @@ public class AppStandbyControllerTests {
        // Predict to ACTIVE
        // Predict to ACTIVE
        mInjector.mElapsedRealtime += 1000;
        mInjector.mElapsedRealtime += 1000;
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
                REASON_MAIN_PREDICTED, mInjector.mElapsedRealtime);
                REASON_MAIN_PREDICTED);
        assertBucket(STANDBY_BUCKET_ACTIVE);
        assertBucket(STANDBY_BUCKET_ACTIVE);


        // CheckIdleStates should not change the prediction
        // CheckIdleStates should not change the prediction
@@ -687,7 +693,7 @@ public class AppStandbyControllerTests {
        // Predict to FREQUENT
        // Predict to FREQUENT
        mInjector.mElapsedRealtime = RARE_THRESHOLD;
        mInjector.mElapsedRealtime = RARE_THRESHOLD;
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
                REASON_MAIN_PREDICTED, mInjector.mElapsedRealtime);
                REASON_MAIN_PREDICTED);
        assertBucket(STANDBY_BUCKET_FREQUENT);
        assertBucket(STANDBY_BUCKET_FREQUENT);


        // Add a short timeout event
        // Add a short timeout event
+7 −61
Original line number Original line Diff line number Diff line
@@ -1568,44 +1568,16 @@ public class UsageStatsService extends SystemService implements
        }
        }


        @Override
        @Override
        public void setAppStandbyBucket(String packageName,
        public void setAppStandbyBucket(String packageName, int bucket, int userId) {
                int bucket, int userId) {
            getContext().enforceCallingPermission(Manifest.permission.CHANGE_APP_IDLE_STATE,
            getContext().enforceCallingPermission(Manifest.permission.CHANGE_APP_IDLE_STATE,
                    "No permission to change app standby state");
                    "No permission to change app standby state");


            if (bucket < UsageStatsManager.STANDBY_BUCKET_ACTIVE
                    || bucket > UsageStatsManager.STANDBY_BUCKET_NEVER) {
                throw new IllegalArgumentException("Cannot set the standby bucket to " + bucket);
            }
            final int callingUid = Binder.getCallingUid();
            final int callingUid = Binder.getCallingUid();
            try {
            final int callingPid = Binder.getCallingPid();
                userId = ActivityManager.getService().handleIncomingUser(
                        Binder.getCallingPid(), callingUid, userId, false, true,
                        "setAppStandbyBucket", null);
            } catch (RemoteException re) {
                throw re.rethrowFromSystemServer();
            }
            final boolean shellCaller = callingUid == 0 || callingUid == Process.SHELL_UID;
            final boolean systemCaller = UserHandle.isCore(callingUid);
            final int reason = systemCaller
                    ? UsageStatsManager.REASON_MAIN_FORCED
                    : UsageStatsManager.REASON_MAIN_PREDICTED;
            final long token = Binder.clearCallingIdentity();
            final long token = Binder.clearCallingIdentity();
            try {
            try {
                final int packageUid = mPackageManagerInternal.getPackageUid(packageName,
                mAppStandby.setAppStandbyBucket(packageName, bucket, userId,
                        PackageManager.MATCH_ANY_USER | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                        callingUid, callingPid);
                        | PackageManager.MATCH_DIRECT_BOOT_AWARE, userId);
                // Caller cannot set their own standby state
                if (packageUid == callingUid) {
                    throw new IllegalArgumentException("Cannot set your own standby bucket");
                }
                if (packageUid < 0) {
                    throw new IllegalArgumentException(
                            "Cannot set standby bucket for non existent package (" + packageName
                                    + ")");
                }
                mAppStandby.setAppStandbyBucket(packageName, userId, bucket, reason,
                        SystemClock.elapsedRealtime(), shellCaller);
            } finally {
            } finally {
                Binder.restoreCallingIdentity(token);
                Binder.restoreCallingIdentity(token);
            }
            }
@@ -1643,37 +1615,11 @@ public class UsageStatsService extends SystemService implements
                    "No permission to change app standby state");
                    "No permission to change app standby state");


            final int callingUid = Binder.getCallingUid();
            final int callingUid = Binder.getCallingUid();
            try {
            final int callingPid = Binder.getCallingPid();
                userId = ActivityManager.getService().handleIncomingUser(
                        Binder.getCallingPid(), callingUid, userId, false, true,
                        "setAppStandbyBucket", null);
            } catch (RemoteException re) {
                throw re.rethrowFromSystemServer();
            }
            final boolean shellCaller = callingUid == 0 || callingUid == Process.SHELL_UID;
            final int reason = shellCaller
                    ? UsageStatsManager.REASON_MAIN_FORCED
                    : UsageStatsManager.REASON_MAIN_PREDICTED;
            final long token = Binder.clearCallingIdentity();
            final long token = Binder.clearCallingIdentity();
            try {
            try {
                final long elapsedRealtime = SystemClock.elapsedRealtime();
                mAppStandby.setAppStandbyBuckets(appBuckets.getList(), userId,
                List<AppStandbyInfo> bucketList = appBuckets.getList();
                        callingUid, callingPid);
                for (AppStandbyInfo bucketInfo : bucketList) {
                    final String packageName = bucketInfo.mPackageName;
                    final int bucket = bucketInfo.mStandbyBucket;
                    if (bucket < UsageStatsManager.STANDBY_BUCKET_ACTIVE
                            || bucket > UsageStatsManager.STANDBY_BUCKET_NEVER) {
                        throw new IllegalArgumentException(
                                "Cannot set the standby bucket to " + bucket);
                    }
                    // Caller cannot set their own standby state
                    if (mPackageManagerInternal.getPackageUid(packageName,
                            PackageManager.MATCH_ANY_USER, userId) == callingUid) {
                        throw new IllegalArgumentException("Cannot set your own standby bucket");
                    }
                    mAppStandby.setAppStandbyBucket(packageName, userId, bucket, reason,
                            elapsedRealtime, shellCaller);
                }
            } finally {
            } finally {
                Binder.restoreCallingIdentity(token);
                Binder.restoreCallingIdentity(token);
            }
            }