/**
 * Copyright (C) 2017 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.usage;

import static android.app.usage.UsageStatsManager.REASON_MAIN_DEFAULT;
import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED_BY_SYSTEM;
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_TIMEOUT;
import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE;
import static android.app.usage.UsageStatsManager.REASON_SUB_DEFAULT_APP_UPDATE;
import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY;
import static android.app.usage.UsageStatsManager.REASON_SUB_MASK;
import static android.app.usage.UsageStatsManager.REASON_SUB_PREDICTED_RESTORED;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_ACTIVE_TIMEOUT;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_START;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_FOREGROUND_SERVICE_START;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_BACKGROUND;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_FOREGROUND;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_NOTIFICATION_SEEN;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SLICE_PINNED;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SLICE_PINNED_PRIV;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SYNC_ADAPTER;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SYSTEM_INTERACTION;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SYSTEM_UPDATE;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_UNEXEMPTED_SYNC_SCHEDULED;
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_EXEMPTED;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_NEVER;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RESTRICTED;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET;

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

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.usage.AppStandbyInfo;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManager.StandbyBuckets;
import android.app.usage.UsageStatsManager.SystemForcedReasons;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.CrossProfileAppsInternal;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
import android.database.ContentObserver;
import android.hardware.display.DisplayManager;
import android.net.NetworkScoreManager;
import android.os.BatteryManager;
import android.os.BatteryStats;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.IDeviceIdleController;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings.Global;
import android.telephony.TelephonyManager;
import android.util.ArraySet;
import android.util.KeyValueListParser;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.util.TimeUtils;
import android.view.Display;
import android.widget.Toast;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ConcurrentUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.usage.AppIdleHistory.AppUsageHistory;

import java.io.File;
import java.io.PrintWriter;
import java.time.Duration;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;

/**
 * Manages the standby state of an app, listening to various events.
 *
 * Unit test:
   atest com.android.server.usage.AppStandbyControllerTests
 */
public class AppStandbyController implements AppStandbyInternal {

    private static final String TAG = "AppStandbyController";
    // Do not submit with true.
    static final boolean DEBUG = false;

    static final boolean COMPRESS_TIME = false;
    private static final long ONE_MINUTE = 60 * 1000;
    private static final long ONE_HOUR = ONE_MINUTE * 60;
    private static final long ONE_DAY = ONE_HOUR * 24;

    /**
     * The minimum amount of time the screen must have been on before an app can time out from its
     * current bucket to the next bucket.
     */
    private static final long[] SCREEN_TIME_THRESHOLDS = {
            0,
            0,
            COMPRESS_TIME ? 2 * ONE_MINUTE : 1 * ONE_HOUR,
            COMPRESS_TIME ? 4 * ONE_MINUTE : 2 * ONE_HOUR,
            COMPRESS_TIME ? 8 * ONE_MINUTE : 6 * ONE_HOUR
    };

    /** The minimum allowed values for each index in {@link #SCREEN_TIME_THRESHOLDS}. */
    private static final long[] MINIMUM_SCREEN_TIME_THRESHOLDS = COMPRESS_TIME
            ? new long[SCREEN_TIME_THRESHOLDS.length]
            : new long[]{
                    0,
                    0,
                    0,
                    30 * ONE_MINUTE,
                    ONE_HOUR
            };

    /**
     * The minimum amount of elapsed time that must have passed before an app can time out from its
     * current bucket to the next bucket.
     */
    private static final long[] ELAPSED_TIME_THRESHOLDS = {
            0,
            COMPRESS_TIME ?  1 * ONE_MINUTE : 12 * ONE_HOUR,
            COMPRESS_TIME ?  4 * ONE_MINUTE : 24 * ONE_HOUR,
            COMPRESS_TIME ? 16 * ONE_MINUTE : 48 * ONE_HOUR,
            COMPRESS_TIME ? 32 * ONE_MINUTE : 30 * ONE_DAY
    };

    /** The minimum allowed values for each index in {@link #ELAPSED_TIME_THRESHOLDS}. */
    private static final long[] MINIMUM_ELAPSED_TIME_THRESHOLDS = COMPRESS_TIME
            ? new long[ELAPSED_TIME_THRESHOLDS.length]
            : new long[]{
                    0,
                    ONE_HOUR,
                    ONE_HOUR,
                    2 * ONE_HOUR,
                    4 * ONE_DAY
            };

    private static final int[] THRESHOLD_BUCKETS = {
            STANDBY_BUCKET_ACTIVE,
            STANDBY_BUCKET_WORKING_SET,
            STANDBY_BUCKET_FREQUENT,
            STANDBY_BUCKET_RARE,
            STANDBY_BUCKET_RESTRICTED
    };

    /** Default expiration time for bucket prediction. After this, use thresholds to downgrade. */
    private static final long DEFAULT_PREDICTION_TIMEOUT = 12 * ONE_HOUR;

    /**
     * Indicates the maximum wait time for admin data to be available;
     */
    private static final long WAIT_FOR_ADMIN_DATA_TIMEOUT_MS = 10_000;

    private static final int HEADLESS_APP_CHECK_FLAGS =
            PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                    | PackageManager.GET_ACTIVITIES | PackageManager.MATCH_DISABLED_COMPONENTS;

    // To name the lock for stack traces
    static class Lock {}

    /** Lock to protect the app's standby state. Required for calls into AppIdleHistory */
    private final Object mAppIdleLock = new Lock();

    /** Keeps the history and state for each app. */
    @GuardedBy("mAppIdleLock")
    private AppIdleHistory mAppIdleHistory;

    @GuardedBy("mPackageAccessListeners")
    private final ArrayList<AppIdleStateChangeListener> mPackageAccessListeners = new ArrayList<>();

    /** Whether we've queried the list of carrier privileged apps. */
    @GuardedBy("mAppIdleLock")
    private boolean mHaveCarrierPrivilegedApps;

    /** List of carrier-privileged apps that should be excluded from standby */
    @GuardedBy("mAppIdleLock")
    private List<String> mCarrierPrivilegedApps;

    @GuardedBy("mActiveAdminApps")
    private final SparseArray<Set<String>> mActiveAdminApps = new SparseArray<>();

    /**
     * Set of system apps that are headless (don't have any declared activities, enabled or
     * disabled). Presence in this map indicates that the app is a headless system app.
     */
    @GuardedBy("mHeadlessSystemApps")
    private final ArraySet<String> mHeadlessSystemApps = new ArraySet<>();

    private final CountDownLatch mAdminDataAvailableLatch = new CountDownLatch(1);

    // Messages for the handler
    static final int MSG_INFORM_LISTENERS = 3;
    static final int MSG_FORCE_IDLE_STATE = 4;
    static final int MSG_CHECK_IDLE_STATES = 5;
    static final int MSG_REPORT_CONTENT_PROVIDER_USAGE = 8;
    static final int MSG_PAROLE_STATE_CHANGED = 9;
    static final int MSG_ONE_TIME_CHECK_IDLE_STATES = 10;
    /** Check the state of one app: arg1 = userId, arg2 = uid, obj = (String) packageName */
    static final int MSG_CHECK_PACKAGE_IDLE_STATE = 11;
    static final int MSG_REPORT_SYNC_SCHEDULED = 12;
    static final int MSG_REPORT_EXEMPTED_SYNC_START = 13;

    long mCheckIdleIntervalMillis;
    /**
     * The minimum amount of time the screen must have been on before an app can time out from its
     * current bucket to the next bucket.
     */
    long[] mAppStandbyScreenThresholds = SCREEN_TIME_THRESHOLDS;
    /**
     * The minimum amount of elapsed time that must have passed before an app can time out from its
     * current bucket to the next bucket.
     */
    long[] mAppStandbyElapsedThresholds = ELAPSED_TIME_THRESHOLDS;
    /** Minimum time a strong usage event should keep the bucket elevated. */
    long mStrongUsageTimeoutMillis;
    /** Minimum time a notification seen event should keep the bucket elevated. */
    long mNotificationSeenTimeoutMillis;
    /** Minimum time a system update event should keep the buckets elevated. */
    long mSystemUpdateUsageTimeoutMillis;
    /** Maximum time to wait for a prediction before using simple timeouts to downgrade buckets. */
    long mPredictionTimeoutMillis;
    /** Maximum time a sync adapter associated with a CP should keep the buckets elevated. */
    long mSyncAdapterTimeoutMillis;
    /**
     * Maximum time an exempted sync should keep the buckets elevated, when sync is scheduled in
     * non-doze
     */
    long mExemptedSyncScheduledNonDozeTimeoutMillis;
    /**
     * Maximum time an exempted sync should keep the buckets elevated, when sync is scheduled in
     * doze
     */
    long mExemptedSyncScheduledDozeTimeoutMillis;
    /**
     * Maximum time an exempted sync should keep the buckets elevated, when sync is started.
     */
    long mExemptedSyncStartTimeoutMillis;
    /**
     * Maximum time an unexempted sync should keep the buckets elevated, when sync is scheduled
     */
    long mUnexemptedSyncScheduledTimeoutMillis;
    /** Maximum time a system interaction should keep the buckets elevated. */
    long mSystemInteractionTimeoutMillis;
    /**
     * Maximum time a foreground service start should keep the buckets elevated if the service
     * start is the first usage of the app
     */
    long mInitialForegroundServiceStartTimeoutMillis;
    /**
     * User usage that would elevate an app's standby bucket will also elevate the standby bucket of
     * cross profile connected apps. Explicit standby bucket setting via
     * {@link #setAppStandbyBucket(String, int, int, int, int)} will not be propagated.
     */
    boolean mLinkCrossProfileApps;
    /**
     * Whether we should allow apps into the
     * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} bucket or not.
     * If false, any attempts to put an app into the bucket will put the app into the
     * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RARE} bucket instead.
     */
    private boolean mAllowRestrictedBucket;

    private volatile boolean mAppIdleEnabled;
    private boolean mIsCharging;
    private boolean mSystemServicesReady = false;
    // There was a system update, defaults need to be initialized after services are ready
    private boolean mPendingInitializeDefaults;

    private volatile boolean mPendingOneTimeCheckIdleStates;

    private final AppStandbyHandler mHandler;
    private final Context mContext;

    private AppWidgetManager mAppWidgetManager;
    private PackageManager mPackageManager;
    Injector mInjector;

    static final ArrayList<StandbyUpdateRecord> sStandbyUpdatePool = new ArrayList<>(4);

    public static class StandbyUpdateRecord {
        // Identity of the app whose standby state has changed
        String packageName;
        int userId;

        // What the standby bucket the app is now in
        int bucket;

        // Whether the bucket change is because the user has started interacting with the app
        boolean isUserInteraction;

        // Reason for bucket change
        int reason;

        StandbyUpdateRecord(String pkgName, int userId, int bucket, int reason,
                boolean isInteraction) {
            this.packageName = pkgName;
            this.userId = userId;
            this.bucket = bucket;
            this.reason = reason;
            this.isUserInteraction = isInteraction;
        }

        public static StandbyUpdateRecord obtain(String pkgName, int userId,
                int bucket, int reason, boolean isInteraction) {
            synchronized (sStandbyUpdatePool) {
                final int size = sStandbyUpdatePool.size();
                if (size < 1) {
                    return new StandbyUpdateRecord(pkgName, userId, bucket, reason, isInteraction);
                }
                StandbyUpdateRecord r = sStandbyUpdatePool.remove(size - 1);
                r.packageName = pkgName;
                r.userId = userId;
                r.bucket = bucket;
                r.reason = reason;
                r.isUserInteraction = isInteraction;
                return r;
            }
        }

        public void recycle() {
            synchronized (sStandbyUpdatePool) {
                sStandbyUpdatePool.add(this);
            }
        }
    }

    public AppStandbyController(Context context, Looper looper) {
        this(new Injector(context, looper));
    }

    AppStandbyController(Injector injector) {
        mInjector = injector;
        mContext = mInjector.getContext();
        mHandler = new AppStandbyHandler(mInjector.getLooper());
        mPackageManager = mContext.getPackageManager();

        DeviceStateReceiver deviceStateReceiver = new DeviceStateReceiver();
        IntentFilter deviceStates = new IntentFilter(BatteryManager.ACTION_CHARGING);
        deviceStates.addAction(BatteryManager.ACTION_DISCHARGING);
        deviceStates.addAction(PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
        mContext.registerReceiver(deviceStateReceiver, deviceStates);

        synchronized (mAppIdleLock) {
            mAppIdleHistory = new AppIdleHistory(mInjector.getDataSystemDirectory(),
                    mInjector.elapsedRealtime());
        }

        IntentFilter packageFilter = new IntentFilter();
        packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
        packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
        packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
        packageFilter.addDataScheme("package");

        mContext.registerReceiverAsUser(new PackageReceiver(), UserHandle.ALL, packageFilter,
                null, mHandler);
    }

    @VisibleForTesting
    void setAppIdleEnabled(boolean enabled) {
        synchronized (mAppIdleLock) {
            if (mAppIdleEnabled != enabled) {
                final boolean oldParoleState = isInParole();
                mAppIdleEnabled = enabled;
                if (isInParole() != oldParoleState) {
                    postParoleStateChanged();
                }
            }
        }

    }

    @Override
    public boolean isAppIdleEnabled() {
        return mAppIdleEnabled;
    }

    @Override
    public void onBootPhase(int phase) {
        mInjector.onBootPhase(phase);
        if (phase == PHASE_SYSTEM_SERVICES_READY) {
            Slog.d(TAG, "Setting app idle enabled state");
            // Observe changes to the threshold
            SettingsObserver settingsObserver = new SettingsObserver(mHandler);
            settingsObserver.registerObserver();
            settingsObserver.updateSettings();

            mAppWidgetManager = mContext.getSystemService(AppWidgetManager.class);

            mInjector.registerDisplayListener(mDisplayListener, mHandler);
            synchronized (mAppIdleLock) {
                mAppIdleHistory.updateDisplay(isDisplayOn(), mInjector.elapsedRealtime());
            }

            mSystemServicesReady = true;

            // Offload to handler thread to avoid boot time impact.
            mHandler.post(mInjector::updatePowerWhitelistCache);

            boolean userFileExists;
            synchronized (mAppIdleLock) {
                userFileExists = mAppIdleHistory.userFileExists(UserHandle.USER_SYSTEM);
            }

            // Offload to handler thread to avoid boottime impact.
            mHandler.post(this::loadHeadlessSystemAppCache);

            if (mPendingInitializeDefaults || !userFileExists) {
                initializeDefaultsForSystemApps(UserHandle.USER_SYSTEM);
            }

            if (mPendingOneTimeCheckIdleStates) {
                postOneTimeCheckIdleStates();
            }
        } else if (phase == PHASE_BOOT_COMPLETED) {
            setChargingState(mInjector.isCharging());
        }
    }

    private void reportContentProviderUsage(String authority, String providerPkgName, int userId) {
        if (!mAppIdleEnabled) return;

        // Get sync adapters for the authority
        String[] packages = ContentResolver.getSyncAdapterPackagesForAuthorityAsUser(
                authority, userId);
        final long elapsedRealtime = mInjector.elapsedRealtime();
        for (String packageName: packages) {
            // Only force the sync adapters to active if the provider is not in the same package and
            // the sync adapter is a system package.
            try {
                PackageInfo pi = mPackageManager.getPackageInfoAsUser(
                        packageName, PackageManager.MATCH_SYSTEM_ONLY, userId);
                if (pi == null || pi.applicationInfo == null) {
                    continue;
                }
                if (!packageName.equals(providerPkgName)) {
                    final List<UserHandle> linkedProfiles = getCrossProfileTargets(packageName,
                            userId);
                    synchronized (mAppIdleLock) {
                        reportNoninteractiveUsageCrossUserLocked(packageName, userId,
                                STANDBY_BUCKET_ACTIVE, REASON_SUB_USAGE_SYNC_ADAPTER,
                                elapsedRealtime, mSyncAdapterTimeoutMillis, linkedProfiles);
                    }
                }
            } catch (PackageManager.NameNotFoundException e) {
                // Shouldn't happen
            }
        }
    }

    private void reportExemptedSyncScheduled(String packageName, int userId) {
        if (!mAppIdleEnabled) return;

        final int bucketToPromote;
        final int usageReason;
        final long durationMillis;

        if (!mInjector.isDeviceIdleMode()) {
            // Not dozing.
            bucketToPromote = STANDBY_BUCKET_ACTIVE;
            usageReason = REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE;
            durationMillis = mExemptedSyncScheduledNonDozeTimeoutMillis;
        } else {
            // Dozing.
            bucketToPromote = STANDBY_BUCKET_WORKING_SET;
            usageReason = REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE;
            durationMillis = mExemptedSyncScheduledDozeTimeoutMillis;
        }

        final long elapsedRealtime = mInjector.elapsedRealtime();
        final List<UserHandle> linkedProfiles = getCrossProfileTargets(packageName, userId);
        synchronized (mAppIdleLock) {
            reportNoninteractiveUsageCrossUserLocked(packageName, userId, bucketToPromote,
                    usageReason, elapsedRealtime, durationMillis, linkedProfiles);
        }
    }

    private void reportUnexemptedSyncScheduled(String packageName, int userId) {
        if (!mAppIdleEnabled) return;

        final long elapsedRealtime = mInjector.elapsedRealtime();
        synchronized (mAppIdleLock) {
            final int currentBucket =
                    mAppIdleHistory.getAppStandbyBucket(packageName, userId, elapsedRealtime);
            if (currentBucket == STANDBY_BUCKET_NEVER) {
                final List<UserHandle> linkedProfiles = getCrossProfileTargets(packageName, userId);
                // Bring the app out of the never bucket
                reportNoninteractiveUsageCrossUserLocked(packageName, userId,
                        STANDBY_BUCKET_WORKING_SET, REASON_SUB_USAGE_UNEXEMPTED_SYNC_SCHEDULED,
                        elapsedRealtime, mUnexemptedSyncScheduledTimeoutMillis, linkedProfiles);
            }
        }
    }

    private void reportExemptedSyncStart(String packageName, int userId) {
        if (!mAppIdleEnabled) return;

        final long elapsedRealtime = mInjector.elapsedRealtime();
        final List<UserHandle> linkedProfiles = getCrossProfileTargets(packageName, userId);
        synchronized (mAppIdleLock) {
            reportNoninteractiveUsageCrossUserLocked(packageName, userId, STANDBY_BUCKET_ACTIVE,
                    REASON_SUB_USAGE_EXEMPTED_SYNC_START, elapsedRealtime,
                    mExemptedSyncStartTimeoutMillis, linkedProfiles);
        }
    }

    /**
     * Helper method to report indirect user usage of an app and handle reporting the usage
     * against cross profile connected apps. <br>
     * Use {@link #reportNoninteractiveUsageLocked(String, int, int, int, long, long)} if
     * cross profile connected apps do not need to be handled.
     */
    private void reportNoninteractiveUsageCrossUserLocked(String packageName, int userId,
            int bucket, int subReason, long elapsedRealtime, long nextCheckDelay,
            List<UserHandle> otherProfiles) {
        reportNoninteractiveUsageLocked(packageName, userId, bucket, subReason, elapsedRealtime,
                nextCheckDelay);
        final int size = otherProfiles.size();
        for (int profileIndex = 0; profileIndex < size; profileIndex++) {
            final int otherUserId = otherProfiles.get(profileIndex).getIdentifier();
            reportNoninteractiveUsageLocked(packageName, otherUserId, bucket, subReason,
                    elapsedRealtime, nextCheckDelay);
        }
    }

    /**
     * Helper method to report indirect user usage of an app. <br>
     * Use
     * {@link #reportNoninteractiveUsageCrossUserLocked(String, int, int, int, long, long, List)}
     * if cross profile connected apps need to be handled.
     */
    private void reportNoninteractiveUsageLocked(String packageName, int userId, int bucket,
            int subReason, long elapsedRealtime, long nextCheckDelay) {
        final AppUsageHistory appUsage = mAppIdleHistory.reportUsage(packageName, userId, bucket,
                subReason, 0, elapsedRealtime + nextCheckDelay);
        mHandler.sendMessageDelayed(
                mHandler.obtainMessage(MSG_CHECK_PACKAGE_IDLE_STATE, userId, -1, packageName),
                nextCheckDelay);
        maybeInformListeners(packageName, userId, elapsedRealtime, appUsage.currentBucket,
                appUsage.bucketingReason, false);
    }

    @VisibleForTesting
    void setChargingState(boolean isCharging) {
        synchronized (mAppIdleLock) {
            if (mIsCharging != isCharging) {
                if (DEBUG) Slog.d(TAG, "Setting mIsCharging to " + isCharging);
                mIsCharging = isCharging;
                postParoleStateChanged();
            }
        }
    }

    @Override
    public boolean isInParole() {
        return !mAppIdleEnabled || mIsCharging;
    }

    private void postParoleStateChanged() {
        if (DEBUG) Slog.d(TAG, "Posting MSG_PAROLE_STATE_CHANGED");
        mHandler.removeMessages(MSG_PAROLE_STATE_CHANGED);
        mHandler.sendEmptyMessage(MSG_PAROLE_STATE_CHANGED);
    }

    @Override
    public void postCheckIdleStates(int userId) {
        mHandler.sendMessage(mHandler.obtainMessage(MSG_CHECK_IDLE_STATES, userId, 0));
    }

    @Override
    public void postOneTimeCheckIdleStates() {
        if (mInjector.getBootPhase() < PHASE_SYSTEM_SERVICES_READY) {
            // Not booted yet; wait for it!
            mPendingOneTimeCheckIdleStates = true;
        } else {
            mHandler.sendEmptyMessage(MSG_ONE_TIME_CHECK_IDLE_STATES);
            mPendingOneTimeCheckIdleStates = false;
        }
    }

    @VisibleForTesting
    boolean checkIdleStates(int checkUserId) {
        if (!mAppIdleEnabled) {
            return false;
        }

        final int[] runningUserIds;
        try {
            runningUserIds = mInjector.getRunningUserIds();
            if (checkUserId != UserHandle.USER_ALL
                    && !ArrayUtils.contains(runningUserIds, checkUserId)) {
                return false;
            }
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }

        final long elapsedRealtime = mInjector.elapsedRealtime();
        for (int i = 0; i < runningUserIds.length; i++) {
            final int userId = runningUserIds[i];
            if (checkUserId != UserHandle.USER_ALL && checkUserId != userId) {
                continue;
            }
            if (DEBUG) {
                Slog.d(TAG, "Checking idle state for user " + userId);
            }
            List<PackageInfo> packages = mPackageManager.getInstalledPackagesAsUser(
                    PackageManager.MATCH_DISABLED_COMPONENTS,
                    userId);
            final int packageCount = packages.size();
            for (int p = 0; p < packageCount; p++) {
                final PackageInfo pi = packages.get(p);
                final String packageName = pi.packageName;
                checkAndUpdateStandbyState(packageName, userId, pi.applicationInfo.uid,
                        elapsedRealtime);
            }
        }
        if (DEBUG) {
            Slog.d(TAG, "checkIdleStates took "
                    + (mInjector.elapsedRealtime() - elapsedRealtime));
        }
        return true;
    }

    /** Check if we need to update the standby state of a specific app. */
    private void checkAndUpdateStandbyState(String packageName, @UserIdInt int userId,
            int uid, long elapsedRealtime) {
        if (uid <= 0) {
            try {
                uid = mPackageManager.getPackageUidAsUser(packageName, userId);
            } catch (PackageManager.NameNotFoundException e) {
                // Not a valid package for this user, nothing to do
                // TODO: Remove any history of removed packages
                return;
            }
        }
        final int minBucket = getAppMinBucket(packageName,
                UserHandle.getAppId(uid),
                userId);
        if (DEBUG) {
            Slog.d(TAG, "   Checking idle state for " + packageName
                    + " minBucket=" + minBucket);
        }
        if (minBucket <= STANDBY_BUCKET_ACTIVE) {
            // No extra processing needed for ACTIVE or higher since apps can't drop into lower
            // buckets.
            synchronized (mAppIdleLock) {
                mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime,
                        minBucket, REASON_MAIN_DEFAULT);
            }
            maybeInformListeners(packageName, userId, elapsedRealtime,
                    minBucket, REASON_MAIN_DEFAULT, false);
        } else {
            synchronized (mAppIdleLock) {
                final AppIdleHistory.AppUsageHistory app =
                        mAppIdleHistory.getAppUsageHistory(packageName,
                        userId, elapsedRealtime);
                int reason = app.bucketingReason;
                final int oldMainReason = reason & REASON_MAIN_MASK;

                // If the bucket was forced by the user/developer, leave it alone.
                // A usage event will be the only way to bring it out of this forced state
                if (oldMainReason == REASON_MAIN_FORCED_BY_USER) {
                    return;
                }
                final int oldBucket = app.currentBucket;
                if (oldBucket == STANDBY_BUCKET_NEVER) {
                    // None of this should bring an app out of the NEVER bucket.
                    return;
                }
                int newBucket = Math.max(oldBucket, STANDBY_BUCKET_ACTIVE); // Undo EXEMPTED
                boolean predictionLate = predictionTimedOut(app, elapsedRealtime);
                // Compute age-based bucket
                if (oldMainReason == REASON_MAIN_DEFAULT
                        || oldMainReason == REASON_MAIN_USAGE
                        || oldMainReason == REASON_MAIN_TIMEOUT
                        || predictionLate) {

                    if (!predictionLate && app.lastPredictedBucket >= STANDBY_BUCKET_ACTIVE
                            && app.lastPredictedBucket <= STANDBY_BUCKET_RARE) {
                        newBucket = app.lastPredictedBucket;
                        reason = REASON_MAIN_PREDICTED | REASON_SUB_PREDICTED_RESTORED;
                        if (DEBUG) {
                            Slog.d(TAG, "Restored predicted newBucket = " + newBucket);
                        }
                    } else {
                        newBucket = getBucketForLocked(packageName, userId,
                                elapsedRealtime);
                        if (DEBUG) {
                            Slog.d(TAG, "Evaluated AOSP newBucket = " + newBucket);
                        }
                        reason = REASON_MAIN_TIMEOUT;
                    }
                }

                // Check if the app is within one of the timeouts for forced bucket elevation
                final long elapsedTimeAdjusted = mAppIdleHistory.getElapsedTime(elapsedRealtime);
                if (newBucket >= STANDBY_BUCKET_ACTIVE
                        && app.bucketActiveTimeoutTime > elapsedTimeAdjusted) {
                    newBucket = STANDBY_BUCKET_ACTIVE;
                    reason = app.bucketingReason;
                    if (DEBUG) {
                        Slog.d(TAG, "    Keeping at ACTIVE due to min timeout");
                    }
                } else if (newBucket >= STANDBY_BUCKET_WORKING_SET
                        && app.bucketWorkingSetTimeoutTime > elapsedTimeAdjusted) {
                    newBucket = STANDBY_BUCKET_WORKING_SET;
                    // If it was already there, keep the reason, else assume timeout to WS
                    reason = (newBucket == oldBucket)
                            ? app.bucketingReason
                            : REASON_MAIN_USAGE | REASON_SUB_USAGE_ACTIVE_TIMEOUT;
                    if (DEBUG) {
                        Slog.d(TAG, "    Keeping at WORKING_SET due to min timeout");
                    }
                }

                if (app.lastRestrictAttemptElapsedTime > app.lastUsedByUserElapsedTime
                        && elapsedTimeAdjusted - app.lastUsedByUserElapsedTime
                        >= mInjector.getAutoRestrictedBucketDelayMs()) {
                    newBucket = STANDBY_BUCKET_RESTRICTED;
                    reason = app.lastRestrictReason;
                    if (DEBUG) {
                        Slog.d(TAG, "Bringing down to RESTRICTED due to timeout");
                    }
                }
                if (newBucket == STANDBY_BUCKET_RESTRICTED && !mAllowRestrictedBucket) {
                    newBucket = STANDBY_BUCKET_RARE;
                    // Leave the reason alone.
                    if (DEBUG) {
                        Slog.d(TAG, "Bringing up from RESTRICTED to RARE due to off switch");
                    }
                }
                if (newBucket > minBucket) {
                    newBucket = minBucket;
                    // Leave the reason alone.
                    if (DEBUG) {
                        Slog.d(TAG, "Bringing up from " + newBucket + " to " + minBucket
                                + " due to min bucketing");
                    }
                }
                if (DEBUG) {
                    Slog.d(TAG, "     Old bucket=" + oldBucket
                            + ", newBucket=" + newBucket);
                }
                if (oldBucket != newBucket || predictionLate) {
                    mAppIdleHistory.setAppStandbyBucket(packageName, userId,
                            elapsedRealtime, newBucket, reason);
                    maybeInformListeners(packageName, userId, elapsedRealtime,
                            newBucket, reason, false);
                }
            }
        }
    }

    /** Returns true if there hasn't been a prediction for the app in a while. */
    private boolean predictionTimedOut(AppIdleHistory.AppUsageHistory app, long elapsedRealtime) {
        return app.lastPredictedTime > 0
                && mAppIdleHistory.getElapsedTime(elapsedRealtime)
                    - app.lastPredictedTime > mPredictionTimeoutMillis;
    }

    /** Inform listeners if the bucket has changed since it was last reported to listeners */
    private void maybeInformListeners(String packageName, int userId,
            long elapsedRealtime, int bucket, int reason, boolean userStartedInteracting) {
        synchronized (mAppIdleLock) {
            if (mAppIdleHistory.shouldInformListeners(packageName, userId,
                    elapsedRealtime, bucket)) {
                final StandbyUpdateRecord r = StandbyUpdateRecord.obtain(packageName, userId,
                        bucket, reason, userStartedInteracting);
                if (DEBUG) Slog.d(TAG, "Standby bucket for " + packageName + "=" + bucket);
                mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, r));
            }
        }
    }

    /**
     * Evaluates next bucket based on time since last used and the bucketing thresholds.
     * @param packageName the app
     * @param userId the user
     * @param elapsedRealtime as the name suggests, current elapsed time
     * @return the bucket for the app, based on time since last used
     */
    @GuardedBy("mAppIdleLock")
    @StandbyBuckets
    private int getBucketForLocked(String packageName, int userId,
            long elapsedRealtime) {
        int bucketIndex = mAppIdleHistory.getThresholdIndex(packageName, userId,
                elapsedRealtime, mAppStandbyScreenThresholds, mAppStandbyElapsedThresholds);
        return THRESHOLD_BUCKETS[bucketIndex];
    }

    private void notifyBatteryStats(String packageName, int userId, boolean idle) {
        try {
            final int uid = mPackageManager.getPackageUidAsUser(packageName,
                    PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
            if (idle) {
                mInjector.noteEvent(BatteryStats.HistoryItem.EVENT_PACKAGE_INACTIVE,
                        packageName, uid);
            } else {
                mInjector.noteEvent(BatteryStats.HistoryItem.EVENT_PACKAGE_ACTIVE,
                        packageName, uid);
            }
        } catch (PackageManager.NameNotFoundException | RemoteException e) {
        }
    }

    @Override
    public void reportEvent(UsageEvents.Event event, long elapsedRealtime, int userId) {
        if (!mAppIdleEnabled) return;
        final int eventType = event.getEventType();
        if ((eventType == UsageEvents.Event.ACTIVITY_RESUMED
                || eventType == UsageEvents.Event.ACTIVITY_PAUSED
                || eventType == UsageEvents.Event.SYSTEM_INTERACTION
                || eventType == UsageEvents.Event.USER_INTERACTION
                || eventType == UsageEvents.Event.NOTIFICATION_SEEN
                || eventType == UsageEvents.Event.SLICE_PINNED
                || eventType == UsageEvents.Event.SLICE_PINNED_PRIV
                || eventType == UsageEvents.Event.FOREGROUND_SERVICE_START)) {
            final String pkg = event.getPackageName();
            final List<UserHandle> linkedProfiles = getCrossProfileTargets(pkg, userId);
            synchronized (mAppIdleLock) {
                reportEventLocked(pkg, eventType, elapsedRealtime, userId);

                final int size = linkedProfiles.size();
                for (int profileIndex = 0; profileIndex < size; profileIndex++) {
                    final int linkedUserId = linkedProfiles.get(profileIndex).getIdentifier();
                    reportEventLocked(pkg, eventType, elapsedRealtime, linkedUserId);
                }
            }
        }
    }

    private void reportEventLocked(String pkg, int eventType, long elapsedRealtime, int userId) {
        // TODO: Ideally this should call isAppIdleFiltered() to avoid calling back
        // about apps that are on some kind of whitelist anyway.
        final boolean previouslyIdle = mAppIdleHistory.isIdle(
                pkg, userId, elapsedRealtime);

        final AppUsageHistory appHistory = mAppIdleHistory.getAppUsageHistory(
                pkg, userId, elapsedRealtime);
        final int prevBucket = appHistory.currentBucket;
        final int prevBucketReason = appHistory.bucketingReason;
        final long nextCheckDelay;
        final int subReason = usageEventToSubReason(eventType);
        final int reason = REASON_MAIN_USAGE | subReason;
        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, userId,
                    STANDBY_BUCKET_WORKING_SET, subReason,
                    0, elapsedRealtime + mNotificationSeenTimeoutMillis);
            nextCheckDelay = mNotificationSeenTimeoutMillis;
        } else if (eventType == UsageEvents.Event.SYSTEM_INTERACTION) {
            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, userId,
                    STANDBY_BUCKET_ACTIVE, subReason,
                    0, elapsedRealtime + mInitialForegroundServiceStartTimeoutMillis);
            nextCheckDelay = mInitialForegroundServiceStartTimeoutMillis;
        } else {
            mAppIdleHistory.reportUsage(appHistory, pkg, userId,
                    STANDBY_BUCKET_ACTIVE, subReason,
                    elapsedRealtime, elapsedRealtime + mStrongUsageTimeoutMillis);
            nextCheckDelay = mStrongUsageTimeoutMillis;
        }
        if (appHistory.currentBucket != prevBucket) {
            mHandler.sendMessageDelayed(
                    mHandler.obtainMessage(MSG_CHECK_PACKAGE_IDLE_STATE, userId, -1, pkg),
                    nextCheckDelay);
            final boolean userStartedInteracting =
                    appHistory.currentBucket == STANDBY_BUCKET_ACTIVE
                            && (prevBucketReason & REASON_MAIN_MASK) != REASON_MAIN_USAGE;
            maybeInformListeners(pkg, userId, elapsedRealtime,
                    appHistory.currentBucket, reason, userStartedInteracting);
        }

        if (previouslyIdle) {
            notifyBatteryStats(pkg, userId, false);
        }
    }

    /**
     * Note: don't call this with the lock held since it makes calls to other system services.
     */
    private @NonNull List<UserHandle> getCrossProfileTargets(String pkg, int userId) {
        synchronized (mAppIdleLock) {
            if (!mLinkCrossProfileApps) return Collections.emptyList();
        }
        return mInjector.getValidCrossProfileTargets(pkg, userId);
    }

    private int usageEventToSubReason(int eventType) {
        switch (eventType) {
            case UsageEvents.Event.ACTIVITY_RESUMED: return REASON_SUB_USAGE_MOVE_TO_FOREGROUND;
            case UsageEvents.Event.ACTIVITY_PAUSED: return REASON_SUB_USAGE_MOVE_TO_BACKGROUND;
            case UsageEvents.Event.SYSTEM_INTERACTION: return REASON_SUB_USAGE_SYSTEM_INTERACTION;
            case UsageEvents.Event.USER_INTERACTION: return REASON_SUB_USAGE_USER_INTERACTION;
            case UsageEvents.Event.NOTIFICATION_SEEN: return REASON_SUB_USAGE_NOTIFICATION_SEEN;
            case UsageEvents.Event.SLICE_PINNED: return REASON_SUB_USAGE_SLICE_PINNED;
            case UsageEvents.Event.SLICE_PINNED_PRIV: return REASON_SUB_USAGE_SLICE_PINNED_PRIV;
            case UsageEvents.Event.FOREGROUND_SERVICE_START:
                return REASON_SUB_USAGE_FOREGROUND_SERVICE_START;
            default: return 0;
        }
    }

    @VisibleForTesting
    void forceIdleState(String packageName, int userId, boolean idle) {
        if (!mAppIdleEnabled) return;

        final int appId = getAppId(packageName);
        if (appId < 0) return;
        final long elapsedRealtime = mInjector.elapsedRealtime();

        final boolean previouslyIdle = isAppIdleFiltered(packageName, appId,
                userId, elapsedRealtime);
        final int standbyBucket;
        synchronized (mAppIdleLock) {
            standbyBucket = mAppIdleHistory.setIdle(packageName, userId, idle, elapsedRealtime);
        }
        final boolean stillIdle = isAppIdleFiltered(packageName, appId,
                userId, elapsedRealtime);
        // Inform listeners if necessary
        if (previouslyIdle != stillIdle) {
            maybeInformListeners(packageName, userId, elapsedRealtime, standbyBucket,
                    REASON_MAIN_FORCED_BY_USER, false);
            if (!stillIdle) {
                notifyBatteryStats(packageName, userId, idle);
            }
        }
    }

    @Override
    public void setLastJobRunTime(String packageName, int userId, long elapsedRealtime) {
        synchronized (mAppIdleLock) {
            mAppIdleHistory.setLastJobRunTime(packageName, userId, elapsedRealtime);
        }
    }

    @Override
    public long getTimeSinceLastJobRun(String packageName, int userId) {
        final long elapsedRealtime = mInjector.elapsedRealtime();
        synchronized (mAppIdleLock) {
            return mAppIdleHistory.getTimeSinceLastJobRun(packageName, userId, elapsedRealtime);
        }
    }

    @Override
    public void onUserRemoved(int userId) {
        synchronized (mAppIdleLock) {
            mAppIdleHistory.onUserRemoved(userId);
            synchronized (mActiveAdminApps) {
                mActiveAdminApps.remove(userId);
            }
        }
    }

    private boolean isAppIdleUnfiltered(String packageName, int userId, long elapsedRealtime) {
        synchronized (mAppIdleLock) {
            return mAppIdleHistory.isIdle(packageName, userId, elapsedRealtime);
        }
    }

    @Override
    public void addListener(AppIdleStateChangeListener listener) {
        synchronized (mPackageAccessListeners) {
            if (!mPackageAccessListeners.contains(listener)) {
                mPackageAccessListeners.add(listener);
            }
        }
    }

    @Override
    public void removeListener(AppIdleStateChangeListener listener) {
        synchronized (mPackageAccessListeners) {
            mPackageAccessListeners.remove(listener);
        }
    }

    @Override
    public int getAppId(String packageName) {
        try {
            ApplicationInfo ai = mPackageManager.getApplicationInfo(packageName,
                    PackageManager.MATCH_ANY_USER
                            | PackageManager.MATCH_DISABLED_COMPONENTS);
            return ai.uid;
        } catch (PackageManager.NameNotFoundException re) {
            return -1;
        }
    }

    @Override
    public boolean isAppIdleFiltered(String packageName, int userId, long elapsedRealtime,
            boolean shouldObfuscateInstantApps) {
        if (shouldObfuscateInstantApps &&
                mInjector.isPackageEphemeral(userId, packageName)) {
            return false;
        }
        return isAppIdleFiltered(packageName, getAppId(packageName), userId, elapsedRealtime);
    }

    @StandbyBuckets
    private int getAppMinBucket(String packageName, int userId) {
        try {
            final int uid = mPackageManager.getPackageUidAsUser(packageName, userId);
            return getAppMinBucket(packageName, UserHandle.getAppId(uid), userId);
        } catch (PackageManager.NameNotFoundException e) {
            // Not a valid package for this user, nothing to do
            return STANDBY_BUCKET_NEVER;
        }
    }

    /**
     * Return the lowest bucket this app should ever enter.
     */
    @StandbyBuckets
    private int getAppMinBucket(String packageName, int appId, int userId) {
        if (packageName == null) return STANDBY_BUCKET_NEVER;
        // If not enabled at all, of course nobody is ever idle.
        if (!mAppIdleEnabled) {
            return STANDBY_BUCKET_EXEMPTED;
        }
        if (appId < Process.FIRST_APPLICATION_UID) {
            // System uids never go idle.
            return STANDBY_BUCKET_EXEMPTED;
        }
        if (packageName.equals("android")) {
            // Nor does the framework (which should be redundant with the above, but for MR1 we will
            // retain this for safety).
            return STANDBY_BUCKET_EXEMPTED;
        }
        if (mSystemServicesReady) {
            // We allow all whitelisted apps, including those that don't want to be whitelisted
            // for idle mode, because app idle (aka app standby) is really not as big an issue
            // for controlling who participates vs. doze mode.
            if (mInjector.isNonIdleWhitelisted(packageName)) {
                return STANDBY_BUCKET_EXEMPTED;
            }

            if (isActiveDeviceAdmin(packageName, userId)) {
                return STANDBY_BUCKET_EXEMPTED;
            }

            if (isActiveNetworkScorer(packageName)) {
                return STANDBY_BUCKET_EXEMPTED;
            }

            if (mAppWidgetManager != null
                    && mInjector.isBoundWidgetPackage(mAppWidgetManager, packageName, userId)) {
                return STANDBY_BUCKET_ACTIVE;
            }

            if (isDeviceProvisioningPackage(packageName)) {
                return STANDBY_BUCKET_EXEMPTED;
            }
        }

        // Check this last, as it can be the most expensive check
        if (isCarrierApp(packageName)) {
            return STANDBY_BUCKET_EXEMPTED;
        }

        if (isHeadlessSystemApp(packageName)) {
            return STANDBY_BUCKET_ACTIVE;
        }

        return STANDBY_BUCKET_NEVER;
    }

    private boolean isHeadlessSystemApp(String packageName) {
        synchronized (mHeadlessSystemApps) {
            return mHeadlessSystemApps.contains(packageName);
        }
    }

    @Override
    public boolean isAppIdleFiltered(String packageName, int appId, int userId,
            long elapsedRealtime) {
        if (getAppMinBucket(packageName, appId, userId) < AppIdleHistory.IDLE_BUCKET_CUTOFF) {
            return false;
        } else {
            synchronized (mAppIdleLock) {
                if (!mAppIdleEnabled || mIsCharging) {
                    return false;
                }
            }
            return isAppIdleUnfiltered(packageName, userId, elapsedRealtime);
        }
    }

    static boolean isUserUsage(int reason) {
        if ((reason & REASON_MAIN_MASK) == REASON_MAIN_USAGE) {
            final int subReason = reason & REASON_SUB_MASK;
            return subReason == REASON_SUB_USAGE_USER_INTERACTION
                    || subReason == REASON_SUB_USAGE_MOVE_TO_FOREGROUND;
        }
        return false;
    }

    @Override
    public int[] getIdleUidsForUser(int userId) {
        if (!mAppIdleEnabled) {
            return new int[0];
        }

        final long elapsedRealtime = mInjector.elapsedRealtime();

        List<ApplicationInfo> apps;
        try {
            ParceledListSlice<ApplicationInfo> slice = AppGlobals.getPackageManager()
                    .getInstalledApplications(/* flags= */ 0, userId);
            if (slice == null) {
                return new int[0];
            }
            apps = slice.getList();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }

        // State of each uid.  Key is the uid.  Value lower 16 bits is the number of apps
        // associated with that uid, upper 16 bits is the number of those apps that is idle.
        SparseIntArray uidStates = new SparseIntArray();

        // Now resolve all app state.  Iterating over all apps, keeping track of how many
        // we find for each uid and how many of those are idle.
        for (int i = apps.size() - 1; i >= 0; i--) {
            ApplicationInfo ai = apps.get(i);

            // Check whether this app is idle.
            boolean idle = isAppIdleFiltered(ai.packageName, UserHandle.getAppId(ai.uid),
                    userId, elapsedRealtime);

            int index = uidStates.indexOfKey(ai.uid);
            if (index < 0) {
                uidStates.put(ai.uid, 1 + (idle ? 1<<16 : 0));
            } else {
                int value = uidStates.valueAt(index);
                uidStates.setValueAt(index, value + 1 + (idle ? 1<<16 : 0));
            }
        }
        if (DEBUG) {
            Slog.d(TAG, "getIdleUids took " + (mInjector.elapsedRealtime() - elapsedRealtime));
        }
        int numIdle = 0;
        for (int i = uidStates.size() - 1; i >= 0; i--) {
            int value = uidStates.valueAt(i);
            if ((value&0x7fff) == (value>>16)) {
                numIdle++;
            }
        }

        int[] res = new int[numIdle];
        numIdle = 0;
        for (int i = uidStates.size() - 1; i >= 0; i--) {
            int value = uidStates.valueAt(i);
            if ((value&0x7fff) == (value>>16)) {
                res[numIdle] = uidStates.keyAt(i);
                numIdle++;
            }
        }

        return res;
    }

    @Override
    public void setAppIdleAsync(String packageName, boolean idle, int userId) {
        if (packageName == null || !mAppIdleEnabled) return;

        mHandler.obtainMessage(MSG_FORCE_IDLE_STATE, userId, idle ? 1 : 0, packageName)
                .sendToTarget();
    }

    @Override
    @StandbyBuckets public int getAppStandbyBucket(String packageName, int userId,
            long elapsedRealtime, boolean shouldObfuscateInstantApps) {
        if (!mAppIdleEnabled || (shouldObfuscateInstantApps
                && mInjector.isPackageEphemeral(userId, packageName))) {
            return STANDBY_BUCKET_ACTIVE;
        }

        synchronized (mAppIdleLock) {
            return mAppIdleHistory.getAppStandbyBucket(packageName, userId, elapsedRealtime);
        }
    }

    @VisibleForTesting
    int getAppStandbyBucketReason(String packageName, int userId, long elapsedRealtime) {
        synchronized (mAppIdleLock) {
            return mAppIdleHistory.getAppStandbyReason(packageName, userId, elapsedRealtime);
        }
    }

    @Override
    public List<AppStandbyInfo> getAppStandbyBuckets(int userId) {
        synchronized (mAppIdleLock) {
            return mAppIdleHistory.getAppStandbyBuckets(userId, mAppIdleEnabled);
        }
    }

    @Override
    public void restrictApp(@NonNull String packageName, int userId,
            @SystemForcedReasons int restrictReason) {
        // If the package is not installed, don't allow the bucket to be set.
        if (!mInjector.isPackageInstalled(packageName, 0, userId)) {
            Slog.e(TAG, "Tried to restrict uninstalled app: " + packageName);
            return;
        }

        final int reason = REASON_MAIN_FORCED_BY_SYSTEM | (REASON_SUB_MASK & restrictReason);
        final long nowElapsed = mInjector.elapsedRealtime();
        final int bucket = mAllowRestrictedBucket ? STANDBY_BUCKET_RESTRICTED : STANDBY_BUCKET_RARE;
        setAppStandbyBucket(packageName, userId, bucket, reason, nowElapsed, false);
    }

    @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 int reason;
        // The Settings app runs in the system UID but in a separate process. Assume
        // things coming from other processes are due to the user.
        if ((UserHandle.isSameApp(callingUid, Process.SYSTEM_UID) && callingPid != Process.myPid())
                || shellCaller) {
            reason = REASON_MAIN_FORCED_BY_USER;
        } else if (UserHandle.isCore(callingUid)) {
            reason = REASON_MAIN_FORCED_BY_SYSTEM;
        } else {
            reason = 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
    void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
            int reason) {
        setAppStandbyBucket(
                packageName, userId, newBucket, reason, mInjector.elapsedRealtime(), false);
    }

    private void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
            int reason, long elapsedRealtime, boolean resetTimeout) {
        if (!mAppIdleEnabled) return;

        synchronized (mAppIdleLock) {
            // If the package is not installed, don't allow the bucket to be set.
            if (!mInjector.isPackageInstalled(packageName, 0, userId)) {
                Slog.e(TAG, "Tried to set bucket of uninstalled app: " + packageName);
                return;
            }
            if (newBucket == STANDBY_BUCKET_RESTRICTED && !mAllowRestrictedBucket) {
                newBucket = STANDBY_BUCKET_RARE;
            }
            AppIdleHistory.AppUsageHistory app = mAppIdleHistory.getAppUsageHistory(packageName,
                    userId, elapsedRealtime);
            boolean predicted = (reason & REASON_MAIN_MASK) == REASON_MAIN_PREDICTED;

            // Don't allow changing bucket if higher than ACTIVE
            if (app.currentBucket < STANDBY_BUCKET_ACTIVE) return;

            // Don't allow prediction to change from/to NEVER.
            if ((app.currentBucket == STANDBY_BUCKET_NEVER || newBucket == STANDBY_BUCKET_NEVER)
                    && predicted) {
                return;
            }

            final boolean wasForcedBySystem =
                    (app.bucketingReason & REASON_MAIN_MASK) == REASON_MAIN_FORCED_BY_SYSTEM;

            // If the bucket was forced, don't allow prediction to override
            if (predicted
                    && ((app.bucketingReason & REASON_MAIN_MASK) == REASON_MAIN_FORCED_BY_USER
                    || wasForcedBySystem)) {
                return;
            }

            final boolean isForcedBySystem =
                    (reason & REASON_MAIN_MASK) == REASON_MAIN_FORCED_BY_SYSTEM;

            if (app.currentBucket == newBucket && wasForcedBySystem && isForcedBySystem) {
                mAppIdleHistory
                        .noteRestrictionAttempt(packageName, userId, elapsedRealtime, reason);
                // Keep track of all restricting reasons
                reason = REASON_MAIN_FORCED_BY_SYSTEM
                        | (app.bucketingReason & REASON_SUB_MASK)
                        | (reason & REASON_SUB_MASK);
                mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime,
                        newBucket, reason, resetTimeout);
                return;
            }

            final boolean isForcedByUser =
                    (reason & REASON_MAIN_MASK) == REASON_MAIN_FORCED_BY_USER;

            if (app.currentBucket == STANDBY_BUCKET_RESTRICTED) {
                if ((app.bucketingReason & REASON_MAIN_MASK) == REASON_MAIN_TIMEOUT) {
                    if (predicted && newBucket >= STANDBY_BUCKET_RARE) {
                        // Predicting into RARE or below means we don't expect the user to use the
                        // app anytime soon, so don't elevate it from RESTRICTED.
                        return;
                    }
                } else if (!isUserUsage(reason) && !isForcedByUser) {
                    // If the current bucket is RESTRICTED, only user force or usage should bring
                    // it out, unless the app was put into the bucket due to timing out.
                    return;
                }
            }

            if (newBucket == STANDBY_BUCKET_RESTRICTED) {
                mAppIdleHistory
                        .noteRestrictionAttempt(packageName, userId, elapsedRealtime, reason);

                if (isForcedByUser) {
                    // Only user force can bypass the delay restriction. If the user forced the
                    // app into the RESTRICTED bucket, then a toast confirming the action
                    // shouldn't be surprising.
                    if (Build.IS_DEBUGGABLE) {
                        Toast.makeText(mContext,
                                // Since AppStandbyController sits low in the lock hierarchy,
                                // make sure not to call out with the lock held.
                                mHandler.getLooper(),
                                mContext.getResources().getString(
                                        R.string.as_app_forced_to_restricted_bucket, packageName),
                                Toast.LENGTH_SHORT)
                                .show();
                    } else {
                        Slog.i(TAG, packageName + " restricted by user");
                    }
                } else {
                    final long timeUntilRestrictPossibleMs = app.lastUsedByUserElapsedTime
                            + mInjector.getAutoRestrictedBucketDelayMs() - elapsedRealtime;
                    if (timeUntilRestrictPossibleMs > 0) {
                        Slog.w(TAG, "Tried to restrict recently used app: " + packageName
                                + " due to " + reason);
                        mHandler.sendMessageDelayed(
                                mHandler.obtainMessage(
                                        MSG_CHECK_PACKAGE_IDLE_STATE, userId, -1, packageName),
                                timeUntilRestrictPossibleMs);
                        return;
                    }
                }
            }

            // If the bucket is required to stay in a higher state for a specified duration, don't
            // override unless the duration has passed
            if (predicted) {
                // Check if the app is within one of the timeouts for forced bucket elevation
                final long elapsedTimeAdjusted = mAppIdleHistory.getElapsedTime(elapsedRealtime);
                // In case of not using the prediction, just keep track of it for applying after
                // ACTIVE or WORKING_SET timeout.
                mAppIdleHistory.updateLastPrediction(app, elapsedTimeAdjusted, newBucket);

                if (newBucket > STANDBY_BUCKET_ACTIVE
                        && app.bucketActiveTimeoutTime > elapsedTimeAdjusted) {
                    newBucket = STANDBY_BUCKET_ACTIVE;
                    reason = app.bucketingReason;
                    if (DEBUG) {
                        Slog.d(TAG, "    Keeping at ACTIVE due to min timeout");
                    }
                } else if (newBucket > STANDBY_BUCKET_WORKING_SET
                        && app.bucketWorkingSetTimeoutTime > elapsedTimeAdjusted) {
                    newBucket = STANDBY_BUCKET_WORKING_SET;
                    if (app.currentBucket != newBucket) {
                        reason = REASON_MAIN_USAGE | REASON_SUB_USAGE_ACTIVE_TIMEOUT;
                    } else {
                        reason = app.bucketingReason;
                    }
                    if (DEBUG) {
                        Slog.d(TAG, "    Keeping at WORKING_SET due to min timeout");
                    }
                } else if (newBucket == STANDBY_BUCKET_RARE
                        && mAllowRestrictedBucket
                        && getBucketForLocked(packageName, userId, elapsedRealtime)
                        == STANDBY_BUCKET_RESTRICTED) {
                    // Prediction doesn't think the app will be used anytime soon and
                    // it's been long enough that it could just time out into restricted,
                    // so time it out there instead. Using TIMEOUT will allow prediction
                    // to raise the bucket when it needs to.
                    newBucket = STANDBY_BUCKET_RESTRICTED;
                    reason = REASON_MAIN_TIMEOUT;
                    if (DEBUG) {
                        Slog.d(TAG,
                                "Prediction to RARE overridden by timeout into RESTRICTED");
                    }
                }
            }

            // Make sure we don't put the app in a lower bucket than it's supposed to be in.
            newBucket = Math.min(newBucket, getAppMinBucket(packageName, userId));
            mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime, newBucket,
                    reason, resetTimeout);
        }
        maybeInformListeners(packageName, userId, elapsedRealtime, newBucket, reason, false);
    }

    @VisibleForTesting
    boolean isActiveDeviceAdmin(String packageName, int userId) {
        synchronized (mActiveAdminApps) {
            final Set<String> adminPkgs = mActiveAdminApps.get(userId);
            return adminPkgs != null && adminPkgs.contains(packageName);
        }
    }

    @Override
    public void addActiveDeviceAdmin(String adminPkg, int userId) {
        synchronized (mActiveAdminApps) {
            Set<String> adminPkgs = mActiveAdminApps.get(userId);
            if (adminPkgs == null) {
                adminPkgs = new ArraySet<>();
                mActiveAdminApps.put(userId, adminPkgs);
            }
            adminPkgs.add(adminPkg);
        }
    }

    @Override
    public void setActiveAdminApps(Set<String> adminPkgs, int userId) {
        synchronized (mActiveAdminApps) {
            if (adminPkgs == null) {
                mActiveAdminApps.remove(userId);
            } else {
                mActiveAdminApps.put(userId, adminPkgs);
            }
        }
    }

    @Override
    public void onAdminDataAvailable() {
        mAdminDataAvailableLatch.countDown();
    }

    /**
     * This will only ever be called once - during device boot.
     */
    private void waitForAdminData() {
        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) {
            ConcurrentUtils.waitForCountDownNoInterrupt(mAdminDataAvailableLatch,
                    WAIT_FOR_ADMIN_DATA_TIMEOUT_MS, "Wait for admin data");
        }
    }

    @VisibleForTesting
    Set<String> getActiveAdminAppsForTest(int userId) {
        synchronized (mActiveAdminApps) {
            return mActiveAdminApps.get(userId);
        }
    }

    /**
     * Returns {@code true} if the supplied package is the device provisioning app. Otherwise,
     * returns {@code false}.
     */
    private boolean isDeviceProvisioningPackage(String packageName) {
        String deviceProvisioningPackage = mContext.getResources().getString(
                com.android.internal.R.string.config_deviceProvisioningPackage);
        return deviceProvisioningPackage != null && deviceProvisioningPackage.equals(packageName);
    }

    private boolean isCarrierApp(String packageName) {
        synchronized (mAppIdleLock) {
            if (!mHaveCarrierPrivilegedApps) {
                fetchCarrierPrivilegedAppsLocked();
            }
            if (mCarrierPrivilegedApps != null) {
                return mCarrierPrivilegedApps.contains(packageName);
            }
            return false;
        }
    }

    @Override
    public void clearCarrierPrivilegedApps() {
        if (DEBUG) {
            Slog.i(TAG, "Clearing carrier privileged apps list");
        }
        synchronized (mAppIdleLock) {
            mHaveCarrierPrivilegedApps = false;
            mCarrierPrivilegedApps = null; // Need to be refetched.
        }
    }

    @GuardedBy("mAppIdleLock")
    private void fetchCarrierPrivilegedAppsLocked() {
        TelephonyManager telephonyManager =
                mContext.getSystemService(TelephonyManager.class);
        mCarrierPrivilegedApps =
                telephonyManager.getCarrierPrivilegedPackagesForAllActiveSubscriptions();
        mHaveCarrierPrivilegedApps = true;
        if (DEBUG) {
            Slog.d(TAG, "apps with carrier privilege " + mCarrierPrivilegedApps);
        }
    }

    private boolean isActiveNetworkScorer(String packageName) {
        String activeScorer = mInjector.getActiveNetworkScorer();
        return packageName != null && packageName.equals(activeScorer);
    }

    private void informListeners(String packageName, int userId, int bucket, int reason,
            boolean userInteraction) {
        final boolean idle = bucket >= STANDBY_BUCKET_RARE;
        synchronized (mPackageAccessListeners) {
            for (AppIdleStateChangeListener listener : mPackageAccessListeners) {
                listener.onAppIdleStateChanged(packageName, userId, idle, bucket, reason);
                if (userInteraction) {
                    listener.onUserInteractionStarted(packageName, userId);
                }
            }
        }
    }

    private void informParoleStateChanged() {
        final boolean paroled = isInParole();
        synchronized (mPackageAccessListeners) {
            for (AppIdleStateChangeListener listener : mPackageAccessListeners) {
                listener.onParoleStateChanged(paroled);
            }
        }
    }

    @Override
    public void flushToDisk(int userId) {
        synchronized (mAppIdleLock) {
            mAppIdleHistory.writeAppIdleTimes(userId);
        }
    }

    @Override
    public void flushDurationsToDisk() {
        // Persist elapsed and screen on time. If this fails for whatever reason, the apps will be
        // considered not-idle, which is the safest outcome in such an event.
        synchronized (mAppIdleLock) {
            mAppIdleHistory.writeAppIdleDurations();
        }
    }

    private boolean isDisplayOn() {
        return mInjector.isDefaultDisplayOn();
    }

    @VisibleForTesting
    void clearAppIdleForPackage(String packageName, int userId) {
        synchronized (mAppIdleLock) {
            mAppIdleHistory.clearUsage(packageName, userId);
        }
    }

    /**
     * Remove an app from the {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED}
     * bucket if it was forced into the bucket by the system because it was buggy.
     */
    @VisibleForTesting
    void maybeUnrestrictBuggyApp(String packageName, int userId) {
        synchronized (mAppIdleLock) {
            final long elapsedRealtime = mInjector.elapsedRealtime();
            final AppIdleHistory.AppUsageHistory app =
                    mAppIdleHistory.getAppUsageHistory(packageName, userId, elapsedRealtime);
            if (app.currentBucket != STANDBY_BUCKET_RESTRICTED
                    || (app.bucketingReason & REASON_MAIN_MASK) != REASON_MAIN_FORCED_BY_SYSTEM) {
                return;
            }

            final int newBucket;
            final int newReason;
            if ((app.bucketingReason & REASON_SUB_MASK) == REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY) {
                // If bugginess was the only reason the app should be restricted, then lift it out.
                newBucket = STANDBY_BUCKET_RARE;
                newReason = REASON_MAIN_DEFAULT | REASON_SUB_DEFAULT_APP_UPDATE;
            } else {
                // There's another reason the app was restricted. Remove the buggy bit and call
                // it a day.
                newBucket = STANDBY_BUCKET_RESTRICTED;
                newReason = app.bucketingReason & ~REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY;
            }
            mAppIdleHistory.setAppStandbyBucket(
                    packageName, userId, elapsedRealtime, newBucket, newReason);
        }
    }

    private class PackageReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            final String pkgName = intent.getData().getSchemeSpecificPart();
            final int userId = getSendingUserId();
            if (Intent.ACTION_PACKAGE_ADDED.equals(action)
                    || Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
                clearCarrierPrivilegedApps();
                // ACTION_PACKAGE_ADDED is called even for system app downgrades.
                evaluateSystemAppException(pkgName, userId);
                mHandler.obtainMessage(MSG_CHECK_PACKAGE_IDLE_STATE, userId, -1, pkgName)
                    .sendToTarget();
            }
            if ((Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
                    Intent.ACTION_PACKAGE_ADDED.equals(action))) {
                if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
                    maybeUnrestrictBuggyApp(pkgName, userId);
                } else {
                    clearAppIdleForPackage(pkgName, userId);
                }
            }
        }
    }

    private void evaluateSystemAppException(String packageName, int userId) {
        if (!mSystemServicesReady) {
            // The app will be evaluated in when services are ready.
            return;
        }
        try {
            PackageInfo pi = mPackageManager.getPackageInfoAsUser(
                    packageName, HEADLESS_APP_CHECK_FLAGS, userId);
            evaluateSystemAppException(pi);
        } catch (PackageManager.NameNotFoundException e) {
            synchronized (mHeadlessSystemApps) {
                mHeadlessSystemApps.remove(packageName);
            }
        }
    }

    /** Returns true if the exception status changed. */
    private boolean evaluateSystemAppException(@Nullable PackageInfo pkgInfo) {
        if (pkgInfo == null || pkgInfo.applicationInfo == null
                || (!pkgInfo.applicationInfo.isSystemApp()
                        && !pkgInfo.applicationInfo.isUpdatedSystemApp())) {
            return false;
        }
        synchronized (mHeadlessSystemApps) {
            if (pkgInfo.activities == null || pkgInfo.activities.length == 0) {
                // Headless system app.
                return mHeadlessSystemApps.add(pkgInfo.packageName);
            } else {
                return mHeadlessSystemApps.remove(pkgInfo.packageName);
            }
        }
    }

    /** Call on a system version update to temporarily reset system app buckets. */
    @Override
    public void initializeDefaultsForSystemApps(int userId) {
        if (!mSystemServicesReady) {
            // Do it later, since SettingsProvider wasn't queried yet for app_standby_enabled
            mPendingInitializeDefaults = true;
            return;
        }
        Slog.d(TAG, "Initializing defaults for system apps on user " + userId + ", "
                + "appIdleEnabled=" + mAppIdleEnabled);
        final long elapsedRealtime = mInjector.elapsedRealtime();
        List<PackageInfo> packages = mPackageManager.getInstalledPackagesAsUser(
                PackageManager.MATCH_DISABLED_COMPONENTS,
                userId);
        final int packageCount = packages.size();
        synchronized (mAppIdleLock) {
            for (int i = 0; i < packageCount; i++) {
                final PackageInfo pi = packages.get(i);
                String packageName = pi.packageName;
                if (pi.applicationInfo != null && pi.applicationInfo.isSystemApp()) {
                    // Mark app as used for 2 hours. After that it can timeout to whatever the
                    // past usage pattern was.
                    mAppIdleHistory.reportUsage(packageName, userId, STANDBY_BUCKET_ACTIVE,
                            REASON_SUB_USAGE_SYSTEM_UPDATE, 0,
                            elapsedRealtime + mSystemUpdateUsageTimeoutMillis);
                }
            }
            // Immediately persist defaults to disk
            mAppIdleHistory.writeAppIdleTimes(userId);
        }
    }

    /** Call on system boot to get the initial set of headless system apps. */
    private void loadHeadlessSystemAppCache() {
        Slog.d(TAG, "Loading headless system app cache. appIdleEnabled=" + mAppIdleEnabled);
        final List<PackageInfo> packages = mPackageManager.getInstalledPackagesAsUser(
                HEADLESS_APP_CHECK_FLAGS, UserHandle.USER_SYSTEM);
        final int packageCount = packages.size();
        for (int i = 0; i < packageCount; i++) {
            PackageInfo pkgInfo = packages.get(i);
            if (pkgInfo != null && evaluateSystemAppException(pkgInfo)) {
                mHandler.obtainMessage(MSG_CHECK_PACKAGE_IDLE_STATE,
                        UserHandle.USER_SYSTEM, -1, pkgInfo.packageName)
                    .sendToTarget();
            }
        }
    }

    @Override
    public void postReportContentProviderUsage(String name, String packageName, int userId) {
        SomeArgs args = SomeArgs.obtain();
        args.arg1 = name;
        args.arg2 = packageName;
        args.arg3 = userId;
        mHandler.obtainMessage(MSG_REPORT_CONTENT_PROVIDER_USAGE, args)
                .sendToTarget();
    }

    @Override
    public void postReportSyncScheduled(String packageName, int userId, boolean exempted) {
        mHandler.obtainMessage(MSG_REPORT_SYNC_SCHEDULED, userId, exempted ? 1 : 0, packageName)
                .sendToTarget();
    }

    @Override
    public void postReportExemptedSyncStart(String packageName, int userId) {
        mHandler.obtainMessage(MSG_REPORT_EXEMPTED_SYNC_START, userId, 0, packageName)
                .sendToTarget();
    }

    @Override
    public void dumpUser(IndentingPrintWriter idpw, int userId, List<String> pkgs) {
        synchronized (mAppIdleLock) {
            mAppIdleHistory.dump(idpw, userId, pkgs);
        }
    }

    @Override
    public void dumpState(String[] args, PrintWriter pw) {
        synchronized (mAppIdleLock) {
            pw.println("Carrier privileged apps (have=" + mHaveCarrierPrivilegedApps
                    + "): " + mCarrierPrivilegedApps);
        }

        pw.println();
        pw.println("Settings:");

        pw.print("  mCheckIdleIntervalMillis=");
        TimeUtils.formatDuration(mCheckIdleIntervalMillis, pw);
        pw.println();

        pw.print("  mStrongUsageTimeoutMillis=");
        TimeUtils.formatDuration(mStrongUsageTimeoutMillis, pw);
        pw.println();
        pw.print("  mNotificationSeenTimeoutMillis=");
        TimeUtils.formatDuration(mNotificationSeenTimeoutMillis, pw);
        pw.println();
        pw.print("  mSyncAdapterTimeoutMillis=");
        TimeUtils.formatDuration(mSyncAdapterTimeoutMillis, pw);
        pw.println();
        pw.print("  mSystemInteractionTimeoutMillis=");
        TimeUtils.formatDuration(mSystemInteractionTimeoutMillis, pw);
        pw.println();
        pw.print("  mInitialForegroundServiceStartTimeoutMillis=");
        TimeUtils.formatDuration(mInitialForegroundServiceStartTimeoutMillis, pw);
        pw.println();

        pw.print("  mPredictionTimeoutMillis=");
        TimeUtils.formatDuration(mPredictionTimeoutMillis, pw);
        pw.println();

        pw.print("  mExemptedSyncScheduledNonDozeTimeoutMillis=");
        TimeUtils.formatDuration(mExemptedSyncScheduledNonDozeTimeoutMillis, pw);
        pw.println();
        pw.print("  mExemptedSyncScheduledDozeTimeoutMillis=");
        TimeUtils.formatDuration(mExemptedSyncScheduledDozeTimeoutMillis, pw);
        pw.println();
        pw.print("  mExemptedSyncStartTimeoutMillis=");
        TimeUtils.formatDuration(mExemptedSyncStartTimeoutMillis, pw);
        pw.println();
        pw.print("  mUnexemptedSyncScheduledTimeoutMillis=");
        TimeUtils.formatDuration(mUnexemptedSyncScheduledTimeoutMillis, pw);
        pw.println();

        pw.print("  mSystemUpdateUsageTimeoutMillis=");
        TimeUtils.formatDuration(mSystemUpdateUsageTimeoutMillis, pw);
        pw.println();

        pw.println();
        pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled);
        pw.print(" mAllowRestrictedBucket=");
        pw.print(mAllowRestrictedBucket);
        pw.print(" mIsCharging=");
        pw.print(mIsCharging);
        pw.println();
        pw.print("mScreenThresholds="); pw.println(Arrays.toString(mAppStandbyScreenThresholds));
        pw.print("mElapsedThresholds="); pw.println(Arrays.toString(mAppStandbyElapsedThresholds));
        pw.println();

        pw.println("mHeadlessSystemApps=[");
        synchronized (mHeadlessSystemApps) {
            for (int i = mHeadlessSystemApps.size() - 1; i >= 0; --i) {
                pw.print("  ");
                pw.print(mHeadlessSystemApps.valueAt(i));
                pw.println(",");
            }
        }
        pw.println("]");
        pw.println();

        mInjector.dump(pw);
    }

    /**
     * Injector for interaction with external code. Override methods to provide a mock
     * implementation for tests.
     * onBootPhase() must be called with at least the PHASE_SYSTEM_SERVICES_READY
     */
    static class Injector {

        private final Context mContext;
        private final Looper mLooper;
        private IBatteryStats mBatteryStats;
        private BatteryManager mBatteryManager;
        private PackageManagerInternal mPackageManagerInternal;
        private DisplayManager mDisplayManager;
        private PowerManager mPowerManager;
        private IDeviceIdleController mDeviceIdleController;
        private CrossProfileAppsInternal mCrossProfileAppsInternal;
        int mBootPhase;
        /**
         * The minimum amount of time required since the last user interaction before an app can be
         * automatically placed in the RESTRICTED bucket.
         */
        long mAutoRestrictedBucketDelayMs = ONE_DAY;
        /**
         * Cached set of apps that are power whitelisted, including those not whitelisted from idle.
         */
        @GuardedBy("mPowerWhitelistedApps")
        private final ArraySet<String> mPowerWhitelistedApps = new ArraySet<>();

        Injector(Context context, Looper looper) {
            mContext = context;
            mLooper = looper;
        }

        Context getContext() {
            return mContext;
        }

        Looper getLooper() {
            return mLooper;
        }

        void onBootPhase(int phase) {
            if (phase == PHASE_SYSTEM_SERVICES_READY) {
                mDeviceIdleController = IDeviceIdleController.Stub.asInterface(
                        ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
                mBatteryStats = IBatteryStats.Stub.asInterface(
                        ServiceManager.getService(BatteryStats.SERVICE_NAME));
                mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
                mDisplayManager = (DisplayManager) mContext.getSystemService(
                        Context.DISPLAY_SERVICE);
                mPowerManager = mContext.getSystemService(PowerManager.class);
                mBatteryManager = mContext.getSystemService(BatteryManager.class);
                mCrossProfileAppsInternal = LocalServices.getService(
                        CrossProfileAppsInternal.class);

                final ActivityManager activityManager =
                        (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
                if (activityManager.isLowRamDevice() || ActivityManager.isSmallBatteryDevice()) {
                    mAutoRestrictedBucketDelayMs = 12 * ONE_HOUR;
                }
            }
            mBootPhase = phase;
        }

        int getBootPhase() {
            return mBootPhase;
        }

        /**
         * Returns the elapsed realtime since the device started. Override this
         * to control the clock.
         * @return elapsed realtime
         */
        long elapsedRealtime() {
            return SystemClock.elapsedRealtime();
        }

        long currentTimeMillis() {
            return System.currentTimeMillis();
        }

        boolean isAppIdleEnabled() {
            final boolean buildFlag = mContext.getResources().getBoolean(
                    com.android.internal.R.bool.config_enableAutoPowerModes);
            final boolean runtimeFlag = Global.getInt(mContext.getContentResolver(),
                    Global.APP_STANDBY_ENABLED, 1) == 1
                    && Global.getInt(mContext.getContentResolver(),
                    Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, 1) == 1;
            return buildFlag && runtimeFlag;
        }

        boolean isCharging() {
            return mBatteryManager.isCharging();
        }

        boolean isNonIdleWhitelisted(String packageName) {
            if (mBootPhase < PHASE_SYSTEM_SERVICES_READY) {
                return false;
            }
            synchronized (mPowerWhitelistedApps) {
                return mPowerWhitelistedApps.contains(packageName);
            }
        }

        private void updatePowerWhitelistCache() {
            if (mBootPhase < PHASE_SYSTEM_SERVICES_READY) {
                return;
            }
            try {
                // Don't call out to DeviceIdleController with the lock held.
                final String[] whitelistedPkgs =
                        mDeviceIdleController.getFullPowerWhitelistExceptIdle();
                synchronized (mPowerWhitelistedApps) {
                    mPowerWhitelistedApps.clear();
                    final int len = whitelistedPkgs.length;
                    for (int i = 0; i < len; ++i) {
                        mPowerWhitelistedApps.add(whitelistedPkgs[i]);
                    }
                }
            } catch (RemoteException e) {
                // Should not happen.
                Slog.wtf(TAG, "Failed to get power whitelist", e);
            }
        }

        boolean isRestrictedBucketEnabled() {
            return Global.getInt(mContext.getContentResolver(),
                    Global.ENABLE_RESTRICTED_BUCKET,
                    Global.DEFAULT_ENABLE_RESTRICTED_BUCKET) == 1;
        }

        File getDataSystemDirectory() {
            return Environment.getDataSystemDirectory();
        }

        /**
         * Return the minimum amount of time that must have passed since the last user usage before
         * an app can be automatically put into the
         * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} bucket.
         */
        long getAutoRestrictedBucketDelayMs() {
            return mAutoRestrictedBucketDelayMs;
        }

        void noteEvent(int event, String packageName, int uid) throws RemoteException {
            mBatteryStats.noteEvent(event, packageName, uid);
        }

        PackageManagerInternal getPackageManagerInternal() {
            return mPackageManagerInternal;
        }

        boolean isPackageEphemeral(int userId, String packageName) {
            return mPackageManagerInternal.isPackageEphemeral(userId, packageName);
        }

        boolean isPackageInstalled(String packageName, int flags, int userId) {
            return mPackageManagerInternal.getPackageUid(packageName, flags, userId) >= 0;
        }

        int[] getRunningUserIds() throws RemoteException {
            return ActivityManager.getService().getRunningUserIds();
        }

        boolean isDefaultDisplayOn() {
            return mDisplayManager
                    .getDisplay(Display.DEFAULT_DISPLAY).getState() == Display.STATE_ON;
        }

        void registerDisplayListener(DisplayManager.DisplayListener listener, Handler handler) {
            mDisplayManager.registerDisplayListener(listener, handler);
        }

        String getActiveNetworkScorer() {
            NetworkScoreManager nsm = (NetworkScoreManager) mContext.getSystemService(
                    Context.NETWORK_SCORE_SERVICE);
            return nsm.getActiveScorerPackage();
        }

        public boolean isBoundWidgetPackage(AppWidgetManager appWidgetManager, String packageName,
                int userId) {
            return appWidgetManager.isBoundWidgetPackage(packageName, userId);
        }

        String getAppIdleSettings() {
            return Global.getString(mContext.getContentResolver(),
                    Global.APP_IDLE_CONSTANTS);
        }

        /** Whether the device is in doze or not. */
        public boolean isDeviceIdleMode() {
            return mPowerManager.isDeviceIdleMode();
        }

        public List<UserHandle> getValidCrossProfileTargets(String pkg, int userId) {
            final int uid = mPackageManagerInternal.getPackageUidInternal(pkg, 0, userId);
            final AndroidPackage aPkg = mPackageManagerInternal.getPackage(uid);
            if (uid < 0
                    || aPkg == null
                    || !aPkg.isCrossProfile()
                    || !mCrossProfileAppsInternal
                            .verifyUidHasInteractAcrossProfilePermission(pkg, uid)) {
                if (uid >= 0 && aPkg == null) {
                    Slog.wtf(TAG, "Null package retrieved for UID " + uid);
                }
                return Collections.emptyList();
            }
            return mCrossProfileAppsInternal.getTargetUserProfiles(pkg, userId);
        }

        void dump(PrintWriter pw) {
            pw.println("mPowerWhitelistedApps=[");
            synchronized (mPowerWhitelistedApps) {
                for (int i = mPowerWhitelistedApps.size() - 1; i >= 0; --i) {
                    pw.print("  ");
                    pw.print(mPowerWhitelistedApps.valueAt(i));
                    pw.println(",");
                }
            }
            pw.println("]");
            pw.println();
        }
    }

    class AppStandbyHandler extends Handler {

        AppStandbyHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_INFORM_LISTENERS:
                    StandbyUpdateRecord r = (StandbyUpdateRecord) msg.obj;
                    informListeners(r.packageName, r.userId, r.bucket, r.reason,
                            r.isUserInteraction);
                    r.recycle();
                    break;

                case MSG_FORCE_IDLE_STATE:
                    forceIdleState((String) msg.obj, msg.arg1, msg.arg2 == 1);
                    break;

                case MSG_CHECK_IDLE_STATES:
                    if (checkIdleStates(msg.arg1) && mAppIdleEnabled) {
                        mHandler.sendMessageDelayed(mHandler.obtainMessage(
                                MSG_CHECK_IDLE_STATES, msg.arg1, 0),
                                mCheckIdleIntervalMillis);
                    }
                    break;

                case MSG_ONE_TIME_CHECK_IDLE_STATES:
                    mHandler.removeMessages(MSG_ONE_TIME_CHECK_IDLE_STATES);
                    waitForAdminData();
                    checkIdleStates(UserHandle.USER_ALL);
                    break;

                case MSG_REPORT_CONTENT_PROVIDER_USAGE:
                    SomeArgs args = (SomeArgs) msg.obj;
                    reportContentProviderUsage((String) args.arg1, // authority name
                            (String) args.arg2, // package name
                            (int) args.arg3); // userId
                    args.recycle();
                    break;

                case MSG_PAROLE_STATE_CHANGED:
                    if (DEBUG) Slog.d(TAG, "Parole state: " + isInParole());
                    informParoleStateChanged();
                    break;

                case MSG_CHECK_PACKAGE_IDLE_STATE:
                    checkAndUpdateStandbyState((String) msg.obj, msg.arg1, msg.arg2,
                            mInjector.elapsedRealtime());
                    break;

                case MSG_REPORT_SYNC_SCHEDULED:
                    final boolean exempted = msg.arg2 > 0 ? true : false;
                    if (exempted) {
                        reportExemptedSyncScheduled((String) msg.obj, msg.arg1);
                    } else {
                        reportUnexemptedSyncScheduled((String) msg.obj, msg.arg1);
                    }
                    break;

                case MSG_REPORT_EXEMPTED_SYNC_START:
                    reportExemptedSyncStart((String) msg.obj, msg.arg1);
                    break;

                default:
                    super.handleMessage(msg);
                    break;

            }
        }
    };

    private class DeviceStateReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (intent.getAction()) {
                case BatteryManager.ACTION_CHARGING:
                    setChargingState(true);
                    break;
                case BatteryManager.ACTION_DISCHARGING:
                    setChargingState(false);
                    break;
                case PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED:
                    if (mSystemServicesReady) {
                        mHandler.post(mInjector::updatePowerWhitelistCache);
                    }
                    break;
            }
        }
    }

    private final DisplayManager.DisplayListener mDisplayListener
            = new DisplayManager.DisplayListener() {

        @Override public void onDisplayAdded(int displayId) {
        }

        @Override public void onDisplayRemoved(int displayId) {
        }

        @Override public void onDisplayChanged(int displayId) {
            if (displayId == Display.DEFAULT_DISPLAY) {
                final boolean displayOn = isDisplayOn();
                synchronized (mAppIdleLock) {
                    mAppIdleHistory.updateDisplay(displayOn, mInjector.elapsedRealtime());
                }
            }
        }
    };

    /**
     * Observe settings changes for {@link Global#APP_IDLE_CONSTANTS}.
     */
    private class SettingsObserver extends ContentObserver {
        private static final String KEY_SCREEN_TIME_THRESHOLDS = "screen_thresholds";
        private static final String KEY_ELAPSED_TIME_THRESHOLDS = "elapsed_thresholds";
        private static final String KEY_STRONG_USAGE_HOLD_DURATION = "strong_usage_duration";
        private static final String KEY_NOTIFICATION_SEEN_HOLD_DURATION =
                "notification_seen_duration";
        private static final String KEY_SYSTEM_UPDATE_HOLD_DURATION =
                "system_update_usage_duration";
        private static final String KEY_PREDICTION_TIMEOUT = "prediction_timeout";
        private static final String KEY_SYNC_ADAPTER_HOLD_DURATION = "sync_adapter_duration";
        private static final String KEY_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_HOLD_DURATION =
                "exempted_sync_scheduled_nd_duration";
        private static final String KEY_EXEMPTED_SYNC_SCHEDULED_DOZE_HOLD_DURATION =
                "exempted_sync_scheduled_d_duration";
        private static final String KEY_EXEMPTED_SYNC_START_HOLD_DURATION =
                "exempted_sync_start_duration";
        private static final String KEY_UNEXEMPTED_SYNC_SCHEDULED_HOLD_DURATION =
                "unexempted_sync_scheduled_duration";
        private static final String KEY_SYSTEM_INTERACTION_HOLD_DURATION =
                "system_interaction_duration";
        private static final String KEY_INITIAL_FOREGROUND_SERVICE_START_HOLD_DURATION =
                "initial_foreground_service_start_duration";
        private static final String KEY_AUTO_RESTRICTED_BUCKET_DELAY_MS =
                "auto_restricted_bucket_delay_ms";
        private static final String KEY_CROSS_PROFILE_APPS_SHARE_STANDBY_BUCKETS =
                "cross_profile_apps_share_standby_buckets";
        public static final long DEFAULT_STRONG_USAGE_TIMEOUT = 1 * ONE_HOUR;
        public static final long DEFAULT_NOTIFICATION_TIMEOUT = 12 * ONE_HOUR;
        public static final long DEFAULT_SYSTEM_UPDATE_TIMEOUT = 2 * ONE_HOUR;
        public static final long DEFAULT_SYSTEM_INTERACTION_TIMEOUT = 10 * ONE_MINUTE;
        public static final long DEFAULT_SYNC_ADAPTER_TIMEOUT = 10 * ONE_MINUTE;
        public static final long DEFAULT_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_TIMEOUT = 10 * ONE_MINUTE;
        public static final long DEFAULT_EXEMPTED_SYNC_SCHEDULED_DOZE_TIMEOUT = 4 * ONE_HOUR;
        public static final long DEFAULT_EXEMPTED_SYNC_START_TIMEOUT = 10 * ONE_MINUTE;
        public static final long DEFAULT_UNEXEMPTED_SYNC_SCHEDULED_TIMEOUT = 10 * ONE_MINUTE;
        public static final long DEFAULT_INITIAL_FOREGROUND_SERVICE_START_TIMEOUT = 30 * ONE_MINUTE;
        public static final long DEFAULT_AUTO_RESTRICTED_BUCKET_DELAY_MS = ONE_DAY;
        public static final boolean DEFAULT_CROSS_PROFILE_APPS_SHARE_STANDBY_BUCKETS = true;

        private final KeyValueListParser mParser = new KeyValueListParser(',');

        SettingsObserver(Handler handler) {
            super(handler);
        }

        void registerObserver() {
            final ContentResolver cr = mContext.getContentResolver();
            cr.registerContentObserver(Global.getUriFor(Global.APP_IDLE_CONSTANTS), false, this);
            cr.registerContentObserver(Global.getUriFor(Global.APP_STANDBY_ENABLED), false, this);
            cr.registerContentObserver(Global.getUriFor(Global.ENABLE_RESTRICTED_BUCKET),
                    false, this);
            cr.registerContentObserver(Global.getUriFor(Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED),
                    false, this);
        }

        @Override
        public void onChange(boolean selfChange) {
            updateSettings();
            postOneTimeCheckIdleStates();
        }

        void updateSettings() {
            if (DEBUG) {
                Slog.d(TAG,
                        "appidle=" + Global.getString(mContext.getContentResolver(),
                                Global.APP_STANDBY_ENABLED));
                Slog.d(TAG,
                        "adaptivebat=" + Global.getString(mContext.getContentResolver(),
                                Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED));
                Slog.d(TAG, "appidleconstants=" + Global.getString(
                        mContext.getContentResolver(),
                        Global.APP_IDLE_CONSTANTS));
            }

            // Look at global settings for this.
            // TODO: Maybe apply different thresholds for different users.
            try {
                mParser.setString(mInjector.getAppIdleSettings());
            } catch (IllegalArgumentException e) {
                Slog.e(TAG, "Bad value for app idle settings: " + e.getMessage());
                // fallthrough, mParser is empty and all defaults will be returned.
            }

            synchronized (mAppIdleLock) {

                String screenThresholdsValue = mParser.getString(KEY_SCREEN_TIME_THRESHOLDS, null);
                mAppStandbyScreenThresholds = parseLongArray(screenThresholdsValue,
                        SCREEN_TIME_THRESHOLDS, MINIMUM_SCREEN_TIME_THRESHOLDS);

                String elapsedThresholdsValue = mParser.getString(KEY_ELAPSED_TIME_THRESHOLDS,
                        null);
                mAppStandbyElapsedThresholds = parseLongArray(elapsedThresholdsValue,
                        ELAPSED_TIME_THRESHOLDS, MINIMUM_ELAPSED_TIME_THRESHOLDS);
                mCheckIdleIntervalMillis = Math.min(mAppStandbyElapsedThresholds[1] / 4,
                        COMPRESS_TIME ? ONE_MINUTE : 4 * 60 * ONE_MINUTE); // 4 hours
                mStrongUsageTimeoutMillis = mParser.getDurationMillis(
                        KEY_STRONG_USAGE_HOLD_DURATION,
                                COMPRESS_TIME ? ONE_MINUTE : DEFAULT_STRONG_USAGE_TIMEOUT);
                mNotificationSeenTimeoutMillis = mParser.getDurationMillis(
                        KEY_NOTIFICATION_SEEN_HOLD_DURATION,
                                COMPRESS_TIME ? 12 * ONE_MINUTE : DEFAULT_NOTIFICATION_TIMEOUT);
                mSystemUpdateUsageTimeoutMillis = mParser.getDurationMillis(
                        KEY_SYSTEM_UPDATE_HOLD_DURATION,
                                COMPRESS_TIME ? 2 * ONE_MINUTE : DEFAULT_SYSTEM_UPDATE_TIMEOUT);
                mPredictionTimeoutMillis = mParser.getDurationMillis(
                        KEY_PREDICTION_TIMEOUT,
                                COMPRESS_TIME ? 10 * ONE_MINUTE : DEFAULT_PREDICTION_TIMEOUT);
                mSyncAdapterTimeoutMillis = mParser.getDurationMillis(
                        KEY_SYNC_ADAPTER_HOLD_DURATION,
                                COMPRESS_TIME ? ONE_MINUTE : DEFAULT_SYNC_ADAPTER_TIMEOUT);

                mExemptedSyncScheduledNonDozeTimeoutMillis = mParser.getDurationMillis(
                        KEY_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_HOLD_DURATION,
                                COMPRESS_TIME ? (ONE_MINUTE / 2)
                                        : DEFAULT_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_TIMEOUT);

                mExemptedSyncScheduledDozeTimeoutMillis = mParser.getDurationMillis(
                        KEY_EXEMPTED_SYNC_SCHEDULED_DOZE_HOLD_DURATION,
                                COMPRESS_TIME ? ONE_MINUTE
                                        : DEFAULT_EXEMPTED_SYNC_SCHEDULED_DOZE_TIMEOUT);

                mExemptedSyncStartTimeoutMillis = mParser.getDurationMillis(
                        KEY_EXEMPTED_SYNC_START_HOLD_DURATION,
                                COMPRESS_TIME ? ONE_MINUTE
                                        : DEFAULT_EXEMPTED_SYNC_START_TIMEOUT);

                mUnexemptedSyncScheduledTimeoutMillis = mParser.getDurationMillis(
                        KEY_UNEXEMPTED_SYNC_SCHEDULED_HOLD_DURATION,
                                COMPRESS_TIME
                                        ? ONE_MINUTE : DEFAULT_UNEXEMPTED_SYNC_SCHEDULED_TIMEOUT);

                mSystemInteractionTimeoutMillis = mParser.getDurationMillis(
                        KEY_SYSTEM_INTERACTION_HOLD_DURATION,
                                COMPRESS_TIME ? ONE_MINUTE : DEFAULT_SYSTEM_INTERACTION_TIMEOUT);

                mInitialForegroundServiceStartTimeoutMillis = mParser.getDurationMillis(
                        KEY_INITIAL_FOREGROUND_SERVICE_START_HOLD_DURATION,
                        COMPRESS_TIME ? ONE_MINUTE :
                                DEFAULT_INITIAL_FOREGROUND_SERVICE_START_TIMEOUT);

                mInjector.mAutoRestrictedBucketDelayMs = Math.max(
                        COMPRESS_TIME ? ONE_MINUTE : 2 * ONE_HOUR,
                        mParser.getDurationMillis(KEY_AUTO_RESTRICTED_BUCKET_DELAY_MS,
                                COMPRESS_TIME
                                        ? ONE_MINUTE : DEFAULT_AUTO_RESTRICTED_BUCKET_DELAY_MS));

                mLinkCrossProfileApps = mParser.getBoolean(
                        KEY_CROSS_PROFILE_APPS_SHARE_STANDBY_BUCKETS,
                        DEFAULT_CROSS_PROFILE_APPS_SHARE_STANDBY_BUCKETS);

                mAllowRestrictedBucket = mInjector.isRestrictedBucketEnabled();
            }

            // Check if app_idle_enabled has changed. Do this after getting the rest of the settings
            // in case we need to change something based on the new values.
            setAppIdleEnabled(mInjector.isAppIdleEnabled());
        }

        long[] parseLongArray(String values, long[] defaults, long[] minValues) {
            if (values == null) return defaults;
            if (values.isEmpty()) {
                // Reset to defaults
                return defaults;
            } else {
                String[] thresholds = values.split("/");
                if (thresholds.length == THRESHOLD_BUCKETS.length) {
                    if (minValues.length != THRESHOLD_BUCKETS.length) {
                        Slog.wtf(TAG, "minValues array is the wrong size");
                        // Use zeroes as the minimums.
                        minValues = new long[THRESHOLD_BUCKETS.length];
                    }
                    long[] array = new long[THRESHOLD_BUCKETS.length];
                    for (int i = 0; i < THRESHOLD_BUCKETS.length; i++) {
                        try {
                            if (thresholds[i].startsWith("P") || thresholds[i].startsWith("p")) {
                                array[i] = Math.max(minValues[i],
                                        Duration.parse(thresholds[i]).toMillis());
                            } else {
                                array[i] = Math.max(minValues[i], Long.parseLong(thresholds[i]));
                            }
                        } catch (NumberFormatException|DateTimeParseException e) {
                            return defaults;
                        }
                    }
                    return array;
                } else {
                    return defaults;
                }
            }
        }
    }
}
