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

Commit 9be46619 authored by Kweku Adams's avatar Kweku Adams Committed by Android (Google) Code Review
Browse files

Merge "Create temp allowlist grace period for EJs."

parents 5f9e34df 55adc9fa
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server;

import android.annotation.NonNull;

public interface PowerAllowlistInternal {
    /**
     * Listener to be notified when the temporary allowlist changes.
     */
    interface TempAllowlistChangeListener {
        void onAppAdded(int uid);
        void onAppRemoved(int uid);
    }

    /**
     * Registers a listener that will be notified when the temp allowlist changes.
     */
    void registerTempAllowlistChangeListener(@NonNull TempAllowlistChangeListener listener);

    /**
     * Unregisters a registered stationary listener from being notified when the temp allowlist
     * changes.
     */
    void unregisterTempAllowlistChangeListener(@NonNull TempAllowlistChangeListener listener);
}
+80 −20
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server;

import android.Manifest;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
@@ -558,6 +559,9 @@ public class DeviceIdleController extends SystemService
    private final ArraySet<DeviceIdleInternal.StationaryListener> mStationaryListeners =
            new ArraySet<>();

    private final ArraySet<PowerAllowlistInternal.TempAllowlistChangeListener>
            mTempAllowlistChangeListeners = new ArraySet<>();

    private static final int EVENT_NULL = 0;
    private static final int EVENT_NORMAL = 1;
    private static final int EVENT_LIGHT_IDLE = 2;
@@ -741,6 +745,20 @@ public class DeviceIdleController extends SystemService
        }
    }

    private void registerTempAllowlistChangeListener(
            @NonNull PowerAllowlistInternal.TempAllowlistChangeListener listener) {
        synchronized (this) {
            mTempAllowlistChangeListeners.add(listener);
        }
    }

    private void unregisterTempAllowlistChangeListener(
            @NonNull PowerAllowlistInternal.TempAllowlistChangeListener listener) {
        synchronized (this) {
            mTempAllowlistChangeListeners.remove(listener);
        }
    }

    @VisibleForTesting
    final class MotionListener extends TriggerEventListener
            implements SensorEventListener {
@@ -1508,12 +1526,13 @@ public class DeviceIdleController extends SystemService
    @VisibleForTesting
    static final int MSG_REPORT_STATIONARY_STATUS = 7;
    private static final int MSG_FINISH_IDLE_OP = 8;
    private static final int MSG_REPORT_TEMP_APP_WHITELIST_CHANGED = 9;
    private static final int MSG_REPORT_TEMP_APP_WHITELIST_CHANGED_TO_NPMS = 9;
    private static final int MSG_SEND_CONSTRAINT_MONITORING = 10;
    @VisibleForTesting
    static final int MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR = 11;
    @VisibleForTesting
    static final int MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR = 12;
    private static final int MSG_REPORT_TEMP_APP_WHITELIST_CHANGED = 13;

    final class MyHandler extends Handler {
        MyHandler(Looper looper) {
@@ -1606,14 +1625,31 @@ public class DeviceIdleController extends SystemService
                } break;
                case MSG_TEMP_APP_WHITELIST_TIMEOUT: {
                    // TODO: What is keeping the device awake at this point? Does it need to be?
                    int appId = msg.arg1;
                    checkTempAppWhitelistTimeout(appId);
                    int uid = msg.arg1;
                    checkTempAppWhitelistTimeout(uid);
                } break;
                case MSG_FINISH_IDLE_OP: {
                    // mActiveIdleWakeLock is held at this point
                    decActiveIdleOps();
                } break;
                case MSG_REPORT_TEMP_APP_WHITELIST_CHANGED: {
                    final int uid = msg.arg1;
                    final boolean added = (msg.arg2 == 1);
                    PowerAllowlistInternal.TempAllowlistChangeListener[] listeners;
                    synchronized (DeviceIdleController.this) {
                        listeners = mTempAllowlistChangeListeners.toArray(
                                new PowerAllowlistInternal.TempAllowlistChangeListener[
                                        mTempAllowlistChangeListeners.size()]);
                    }
                    for (PowerAllowlistInternal.TempAllowlistChangeListener listener : listeners) {
                        if (added) {
                            listener.onAppAdded(uid);
                        } else {
                            listener.onAppRemoved(uid);
                        }
                    }
                } break;
                case MSG_REPORT_TEMP_APP_WHITELIST_CHANGED_TO_NPMS: {
                    final int appId = msg.arg1;
                    final boolean added = (msg.arg2 == 1);
                    mNetworkPolicyManagerInternal.onTempPowerSaveWhitelistChange(appId, added);
@@ -1960,6 +1996,21 @@ public class DeviceIdleController extends SystemService
        }
    }

    private class LocalPowerAllowlistService implements PowerAllowlistInternal {

        @Override
        public void registerTempAllowlistChangeListener(
                @NonNull TempAllowlistChangeListener listener) {
            DeviceIdleController.this.registerTempAllowlistChangeListener(listener);
        }

        @Override
        public void unregisterTempAllowlistChangeListener(
                @NonNull TempAllowlistChangeListener listener) {
            DeviceIdleController.this.unregisterTempAllowlistChangeListener(listener);
        }
    }

    static class Injector {
        private final Context mContext;
        private ConnectivityManager mConnectivityManager;
@@ -2164,6 +2215,7 @@ public class DeviceIdleController extends SystemService
        publishBinderService(Context.DEVICE_IDLE_CONTROLLER, mBinderService);
        mLocalService = new LocalService();
        publishLocalService(DeviceIdleInternal.class, mLocalService);
        publishLocalService(PowerAllowlistInternal.class, new LocalPowerAllowlistService());
    }

    @Override
@@ -2708,15 +2760,18 @@ public class DeviceIdleController extends SystemService
                            reason, uid);
                } catch (RemoteException e) {
                }
                postTempActiveTimeoutMessage(appId, duration);
                postTempActiveTimeoutMessage(uid, duration);
                updateTempWhitelistAppIdsLocked(appId, true);
                if (sync) {
                    informWhitelistChanged = true;
                } else {
                    mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED, appId, 1)
                    // NPMS needs to update its state synchronously in certain situations so we
                    // can't have it use the TempAllowlistChangeListener path right now.
                    // TODO: see if there's a way to simplify/consolidate
                    mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED_TO_NPMS, appId, 1)
                            .sendToTarget();
                }
                reportTempWhitelistChangedLocked();
                reportTempWhitelistChangedLocked(uid, true);
            }
        }
        if (informWhitelistChanged) {
@@ -2737,7 +2792,8 @@ public class DeviceIdleController extends SystemService
        }
    }

    private void removePowerSaveTempWhitelistAppDirectInternal(int appId) {
    private void removePowerSaveTempWhitelistAppDirectInternal(int uid) {
        final int appId = UserHandle.getAppId(uid);
        synchronized (this) {
            final int idx = mTempWhitelistAppIdEndTimes.indexOfKey(appId);
            if (idx < 0) {
@@ -2746,22 +2802,23 @@ public class DeviceIdleController extends SystemService
            }
            final String reason = mTempWhitelistAppIdEndTimes.valueAt(idx).second;
            mTempWhitelistAppIdEndTimes.removeAt(idx);
            onAppRemovedFromTempWhitelistLocked(appId, reason);
            onAppRemovedFromTempWhitelistLocked(uid, reason);
        }
    }

    private void postTempActiveTimeoutMessage(int appId, long delay) {
    private void postTempActiveTimeoutMessage(int uid, long delay) {
        if (DEBUG) {
            Slog.d(TAG, "postTempActiveTimeoutMessage: appId=" + appId + ", delay=" + delay);
            Slog.d(TAG, "postTempActiveTimeoutMessage: uid=" + uid + ", delay=" + delay);
        }
        mHandler.sendMessageDelayed(
                mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, appId, 0), delay);
                mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, uid, 0), delay);
    }

    void checkTempAppWhitelistTimeout(int appId) {
    void checkTempAppWhitelistTimeout(int uid) {
        final long timeNow = SystemClock.elapsedRealtime();
        final int appId = UserHandle.getAppId(uid);
        if (DEBUG) {
            Slog.d(TAG, "checkTempAppWhitelistTimeout: appId=" + appId + ", timeNow=" + timeNow);
            Slog.d(TAG, "checkTempAppWhitelistTimeout: uid=" + uid + ", timeNow=" + timeNow);
        }
        synchronized (this) {
            Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId);
@@ -2771,26 +2828,27 @@ public class DeviceIdleController extends SystemService
            }
            if (timeNow >= entry.first.value) {
                mTempWhitelistAppIdEndTimes.delete(appId);
                onAppRemovedFromTempWhitelistLocked(appId, entry.second);
                onAppRemovedFromTempWhitelistLocked(uid, entry.second);
            } else {
                // Need more time
                if (DEBUG) {
                    Slog.d(TAG, "Time to remove AppId " + appId + ": " + entry.first.value);
                }
                postTempActiveTimeoutMessage(appId, entry.first.value - timeNow);
                postTempActiveTimeoutMessage(uid, entry.first.value - timeNow);
            }
        }
    }

    @GuardedBy("this")
    private void onAppRemovedFromTempWhitelistLocked(int appId, String reason) {
    private void onAppRemovedFromTempWhitelistLocked(int uid, String reason) {
        final int appId = UserHandle.getAppId(uid);
        if (DEBUG) {
            Slog.d(TAG, "Removing appId " + appId + " from temp whitelist");
            Slog.d(TAG, "Removing uid " + uid + " from temp whitelist");
        }
        updateTempWhitelistAppIdsLocked(appId, false);
        mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED, appId, 0)
        mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED_TO_NPMS, appId, 0)
                .sendToTarget();
        reportTempWhitelistChangedLocked();
        reportTempWhitelistChangedLocked(uid, false);
        try {
            mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH,
                    reason, appId);
@@ -3843,7 +3901,9 @@ public class DeviceIdleController extends SystemService
        getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
    }

    private void reportTempWhitelistChangedLocked() {
    private void reportTempWhitelistChangedLocked(final int uid, final boolean added) {
        mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED, uid, added ? 1 : 0)
                .sendToTarget();
        Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
        getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
+146 −25
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseArrayMap;
import android.util.SparseBooleanArray;
import android.util.SparseLongArray;
import android.util.SparseSetArray;
import android.util.proto.ProtoOutputStream;

@@ -68,6 +69,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.server.JobSchedulerBackgroundThread;
import com.android.server.LocalServices;
import com.android.server.PowerAllowlistInternal;
import com.android.server.job.ConstantsProto;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.JobServiceContext;
@@ -343,6 +345,15 @@ public final class QuotaController extends StateController {
     */
    private final ArraySet<JobStatus> mTopStartedJobs = new ArraySet<>();

    /** Current set of UIDs on the temp allowlist. */
    private final SparseBooleanArray mTempAllowlistCache = new SparseBooleanArray();

    /**
     * Mapping of app IDs to the when their temp allowlist grace period ends (in the elapsed
     * realtime timebase).
     */
    private final SparseLongArray mTempAllowlistGraceCache = new SparseLongArray();

    private final ActivityManagerInternal mActivityManagerInternal;
    private final AlarmManager mAlarmManager;
    private final ChargingTracker mChargeTracker;
@@ -538,6 +549,9 @@ public final class QuotaController extends StateController {
     */
    private long mEJRewardNotificationSeenMs = QcConstants.DEFAULT_EJ_REWARD_NOTIFICATION_SEEN_MS;

    private long mEJTempAllowlistGracePeriodMs =
            QcConstants.DEFAULT_EJ_TEMP_ALLOWLIST_GRACE_PERIOD_MS;

    /** The package verifier app. */
    @Nullable
    private String mPackageVerifier;
@@ -562,6 +576,9 @@ public final class QuotaController extends StateController {
     * userId will the first arg.
     */
    private static final int MSG_PROCESS_USAGE_EVENT = 5;
    /** A UID's free quota grace period has ended. */
    @VisibleForTesting
    static final int MSG_END_GRACE_PERIOD = 6;

    public QuotaController(@NonNull JobSchedulerService service,
            @NonNull BackgroundJobsController backgroundJobsController,
@@ -586,6 +603,9 @@ public final class QuotaController extends StateController {
        UsageStatsManagerInternal usmi = LocalServices.getService(UsageStatsManagerInternal.class);
        usmi.registerListener(new UsageEventTracker());

        PowerAllowlistInternal pai = LocalServices.getService(PowerAllowlistInternal.class);
        pai.registerTempAllowlistChangeListener(new TempAllowlistTracker());

        try {
            ActivityManager.getService().registerUidObserver(mUidObserver,
                    ActivityManager.UID_OBSERVER_PROCSTATE,
@@ -693,6 +713,8 @@ public final class QuotaController extends StateController {
        clearAppStatsLocked(UserHandle.getUserId(uid), packageName);
        mForegroundUids.delete(uid);
        mUidToPackageCache.remove(uid);
        mTempAllowlistCache.delete(uid);
        mTempAllowlistGraceCache.delete(uid);
    }

    @Override
@@ -1988,10 +2010,15 @@ public final class QuotaController extends StateController {
        }

        private boolean shouldTrackLocked() {
            final long nowElapsed = sElapsedRealtimeClock.millis();
            final int standbyBucket = JobSchedulerService.standbyBucketForPackage(mPkg.packageName,
                    mPkg.userId, sElapsedRealtimeClock.millis());
                    mPkg.userId, nowElapsed);
            final long tempAllowlistGracePeriodEndElapsed = mTempAllowlistGraceCache.get(mUid);
            final boolean hasTempAllowlistExemption = !mRegularJobTimer
                    && (mTempAllowlistCache.get(mUid)
                    || nowElapsed < tempAllowlistGracePeriodEndElapsed);
            return (standbyBucket == RESTRICTED_INDEX || !mChargeTracker.isCharging())
                    && !mForegroundUids.get(mUid);
                    && !mForegroundUids.get(mUid) && !hasTempAllowlistExemption;
        }

        void onStateChangedLocked(long nowElapsed, boolean isQuotaFree) {
@@ -2265,6 +2292,38 @@ public final class QuotaController extends StateController {
        }
    }

    final class TempAllowlistTracker implements PowerAllowlistInternal.TempAllowlistChangeListener {

        @Override
        public void onAppAdded(int uid) {
            final long nowElapsed = sElapsedRealtimeClock.millis();
            mTempAllowlistCache.put(uid, true);
            final ArraySet<String> packages = getPackagesForUid(uid);
            if (packages != null) {
                final int userId = UserHandle.getUserId(uid);
                for (int i = packages.size() - 1; i >= 0; --i) {
                    Timer t = mEJPkgTimers.get(userId, packages.valueAt(i));
                    if (t != null) {
                        t.onStateChangedLocked(nowElapsed, true);
                    }
                }
                if (maybeUpdateConstraintForUidLocked(uid)) {
                    mStateChangedListener.onControllerStateChanged();
                }
            }
        }

        @Override
        public void onAppRemoved(int uid) {
            final long nowElapsed = sElapsedRealtimeClock.millis();
            final long endElapsed = nowElapsed + mEJTempAllowlistGracePeriodMs;
            mTempAllowlistCache.delete(uid);
            mTempAllowlistGraceCache.put(uid, endElapsed);
            Message msg = mHandler.obtainMessage(MSG_END_GRACE_PERIOD, uid, 0);
            mHandler.sendMessageDelayed(msg, mEJTempAllowlistGracePeriodMs);
        }
    }

    private final class DeleteTimingSessionsFunctor implements Consumer<List<TimingSession>> {
        private final Predicate<TimingSession> mTooOld = new Predicate<TimingSession>() {
            public boolean test(TimingSession ts) {
@@ -2291,6 +2350,26 @@ public final class QuotaController extends StateController {
        // getRemainingEJExecutionTimeLocked().
    }

    @Nullable
    private ArraySet<String> getPackagesForUid(final int uid) {
        ArraySet<String> packages = mUidToPackageCache.get(uid);
        if (packages == null) {
            try {
                String[] pkgs = AppGlobals.getPackageManager()
                        .getPackagesForUid(uid);
                if (pkgs != null) {
                    for (String pkg : pkgs) {
                        mUidToPackageCache.add(uid, pkg);
                    }
                    packages = mUidToPackageCache.get(uid);
                }
            } catch (RemoteException e) {
                // Shouldn't happen.
            }
        }
        return packages;
    }

    private class QcHandler extends Handler {
        private boolean mIsProcessing;

@@ -2396,21 +2475,7 @@ public final class QuotaController extends StateController {
                            // Update Timers first.
                            if (mPkgTimers.indexOfKey(userId) >= 0
                                    || mEJPkgTimers.indexOfKey(userId) >= 0) {
                                ArraySet<String> packages = mUidToPackageCache.get(uid);
                                if (packages == null) {
                                    try {
                                        String[] pkgs = AppGlobals.getPackageManager()
                                                .getPackagesForUid(uid);
                                        if (pkgs != null) {
                                            for (String pkg : pkgs) {
                                                mUidToPackageCache.add(uid, pkg);
                                            }
                                            packages = mUidToPackageCache.get(uid);
                                        }
                                    } catch (RemoteException e) {
                                        Slog.wtf(TAG, "Failed to get package list", e);
                                    }
                                }
                                final ArraySet<String> packages = getPackagesForUid(uid);
                                if (packages != null) {
                                    for (int i = packages.size() - 1; i >= 0; --i) {
                                        Timer t = mEJPkgTimers.get(userId, packages.valueAt(i));
@@ -2464,6 +2529,37 @@ public final class QuotaController extends StateController {
                                break;
                        }

                        break;
                    }
                    case MSG_END_GRACE_PERIOD: {
                        final int uid = msg.arg1;
                        synchronized (mLock) {
                            if (mTempAllowlistCache.get(uid)) {
                                // App added back to the temp allowlist during the grace period.
                                if (DEBUG) {
                                    Slog.d(TAG, uid + " is still allowed");
                                }
                                break;
                            }
                            if (DEBUG) {
                                Slog.d(TAG, uid + " is now out of grace period");
                            }
                            final ArraySet<String> packages = getPackagesForUid(uid);
                            if (packages != null) {
                                final int userId = UserHandle.getUserId(uid);
                                final long nowElapsed = sElapsedRealtimeClock.millis();
                                for (int i = packages.size() - 1; i >= 0; --i) {
                                    Timer t = mEJPkgTimers.get(userId, packages.valueAt(i));
                                    if (t != null) {
                                        t.onStateChangedLocked(nowElapsed, false);
                                    }
                                }
                                if (maybeUpdateConstraintForUidLocked(uid)) {
                                    mStateChangedListener.onControllerStateChanged();
                                }
                            }
                        }

                        break;
                    }
                }
@@ -2784,6 +2880,9 @@ public final class QuotaController extends StateController {
        @VisibleForTesting
        static final String KEY_EJ_REWARD_NOTIFICATION_SEEN_MS =
                QC_CONSTANT_PREFIX + "ej_reward_notification_seen_ms";
        @VisibleForTesting
        static final String KEY_EJ_TEMP_ALLOWLIST_GRACE_PERIOD_MS =
                QC_CONSTANT_PREFIX + "ej_temp_allowlist_grace_period_ms";

        private static final long DEFAULT_ALLOWED_TIME_PER_PERIOD_MS =
                10 * 60 * 1000L; // 10 minutes
@@ -2836,6 +2935,7 @@ public final class QuotaController extends StateController {
        private static final long DEFAULT_EJ_REWARD_TOP_APP_MS = 10 * SECOND_IN_MILLIS;
        private static final long DEFAULT_EJ_REWARD_INTERACTION_MS = 15 * SECOND_IN_MILLIS;
        private static final long DEFAULT_EJ_REWARD_NOTIFICATION_SEEN_MS = 0;
        private static final long DEFAULT_EJ_TEMP_ALLOWLIST_GRACE_PERIOD_MS = 3 * MINUTE_IN_MILLIS;

        /** How much time each app will have to run jobs within their standby bucket window. */
        public long ALLOWED_TIME_PER_PERIOD_MS = DEFAULT_ALLOWED_TIME_PER_PERIOD_MS;
@@ -3063,6 +3163,12 @@ public final class QuotaController extends StateController {
         */
        public long EJ_REWARD_NOTIFICATION_SEEN_MS = DEFAULT_EJ_REWARD_NOTIFICATION_SEEN_MS;

        /**
         * How much additional grace period to add to the end of an app's temp allowlist
         * duration.
         */
        public long EJ_TEMP_ALLOWLIST_GRACE_PERIOD_MS = DEFAULT_EJ_TEMP_ALLOWLIST_GRACE_PERIOD_MS;

        public void processConstantLocked(@NonNull DeviceConfig.Properties properties,
                @NonNull String key) {
            switch (key) {
@@ -3245,22 +3351,25 @@ public final class QuotaController extends StateController {
                            properties.getLong(key, DEFAULT_EJ_REWARD_INTERACTION_MS);
                    // Limit interaction reward to be in the range [5 seconds, 15 minutes] per
                    // event.
                    long newInteractionReward = Math.min(15 * MINUTE_IN_MILLIS,
                    mEJRewardInteractionMs = Math.min(15 * MINUTE_IN_MILLIS,
                            Math.max(5 * SECOND_IN_MILLIS, EJ_REWARD_INTERACTION_MS));
                    if (mEJRewardInteractionMs != newInteractionReward) {
                        mEJRewardInteractionMs = newInteractionReward;
                    }
                    break;
                case KEY_EJ_REWARD_NOTIFICATION_SEEN_MS:
                    // We don't need to re-evaluate execution stats or constraint status for this.
                    EJ_REWARD_NOTIFICATION_SEEN_MS =
                            properties.getLong(key, DEFAULT_EJ_REWARD_NOTIFICATION_SEEN_MS);
                    // Limit notification seen reward to be in the range [0, 5] minutes per event.
                    long newNotiSeenReward = Math.min(5 * MINUTE_IN_MILLIS,
                    mEJRewardNotificationSeenMs = Math.min(5 * MINUTE_IN_MILLIS,
                            Math.max(0, EJ_REWARD_NOTIFICATION_SEEN_MS));
                    if (mEJRewardNotificationSeenMs != newNotiSeenReward) {
                        mEJRewardNotificationSeenMs = newNotiSeenReward;
                    }
                    break;
                case KEY_EJ_TEMP_ALLOWLIST_GRACE_PERIOD_MS:
                    // We don't need to re-evaluate execution stats or constraint status for this.
                    EJ_TEMP_ALLOWLIST_GRACE_PERIOD_MS =
                            properties.getLong(key, DEFAULT_EJ_TEMP_ALLOWLIST_GRACE_PERIOD_MS);
                    // Limit grace period to be in the range [0 minutes, 1 hour].
                    mEJTempAllowlistGracePeriodMs = Math.min(HOUR_IN_MILLIS,
                            Math.max(0, EJ_TEMP_ALLOWLIST_GRACE_PERIOD_MS));
                    break;
            }
        }

@@ -3522,6 +3631,8 @@ public final class QuotaController extends StateController {
            pw.print(KEY_EJ_REWARD_TOP_APP_MS, EJ_REWARD_TOP_APP_MS).println();
            pw.print(KEY_EJ_REWARD_INTERACTION_MS, EJ_REWARD_INTERACTION_MS).println();
            pw.print(KEY_EJ_REWARD_NOTIFICATION_SEEN_MS, EJ_REWARD_NOTIFICATION_SEEN_MS).println();
            pw.print(KEY_EJ_TEMP_ALLOWLIST_GRACE_PERIOD_MS,
                    EJ_TEMP_ALLOWLIST_GRACE_PERIOD_MS).println();

            pw.decreaseIndent();
        }
@@ -3668,6 +3779,10 @@ public final class QuotaController extends StateController {
        return mEJRewardTopAppMs;
    }

    @VisibleForTesting
    long getEJTempAllowlistGracePeriodMs() {
        return mEJTempAllowlistGracePeriodMs;
    }

    @VisibleForTesting
    @Nullable
@@ -3757,6 +3872,12 @@ public final class QuotaController extends StateController {
        pw.decreaseIndent();
        pw.println();

        pw.print("Cached temp allowlist: ");
        pw.println(mTempAllowlistCache.toString());
        pw.print("Cached temp allowlist grace period: ");
        pw.println(mTempAllowlistGraceCache.toString());

        pw.println();
        mTrackedJobs.forEach((jobs) -> {
            for (int j = 0; j < jobs.size(); j++) {
                final JobStatus js = jobs.valueAt(j);
+1 −0

File changed.

Preview size limit exceeded, changes collapsed.

+3 −0

File changed.

Preview size limit exceeded, changes collapsed.

Loading