/*
 * 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.power.batterysaver;

import android.annotation.IntDef;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.BatterySaverPolicyConfig;
import android.os.Handler;
import android.os.PowerManager;
import android.os.PowerManager.ServiceType;
import android.os.PowerSaveState;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.KeyValueListParser;
import android.util.Slog;
import android.view.accessibility.AccessibilityManager;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.ConcurrentUtils;
import com.android.server.power.PowerManagerService;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Class to decide whether to turn on battery saver mode for specific services.
 *
 * IMPORTANT: This class shares the power manager lock, which is very low in the lock hierarchy.
 * Do not call out with the lock held, such as AccessibilityManager. (Settings provider is okay.)
 *
 * Test: atest com.android.server.power.batterysaver.BatterySaverPolicyTest
 */
public class BatterySaverPolicy extends ContentObserver {
    private static final String TAG = "BatterySaverPolicy";

    static final boolean DEBUG = false; // DO NOT SUBMIT WITH TRUE.

    private static final String KEY_GPS_MODE = "gps_mode";
    private static final String KEY_VIBRATION_DISABLED = "vibration_disabled";
    private static final String KEY_ANIMATION_DISABLED = "animation_disabled";
    private static final String KEY_SOUNDTRIGGER_DISABLED = "soundtrigger_disabled";

    /**
     * Disable turning on the network firewall when Battery Saver is turned on.
     * If set to false, the firewall WILL be turned on when Battery Saver is turned on.
     * If set to true, the firewall WILL NOT be turned on when Battery Saver is turned on.
     */
    private static final String KEY_ACTIVATE_FIREWALL_DISABLED = "firewall_disabled";

    /**
     * Disable turning on the special low power screen brightness dimming when Battery Saver is
     * turned on.
     * If set to false, the screen brightness dimming WILL be turned on by Battery Saver.
     * If set to true, the screen brightness WILL NOT be turned on by Battery Saver.
     */
    private static final String KEY_ADJUST_BRIGHTNESS_DISABLED = "adjust_brightness_disabled";

    /**
     * Disable turning on Data Saver when Battery Saver is turned on.
     * If set to false, Data Saver WILL be turned on when Battery Saver is turned on.
     * If set to true, Data Saver WILL NOT be turned on when Battery Saver is turned on.
     */
    private static final String KEY_ACTIVATE_DATASAVER_DISABLED = "datasaver_disabled";

    /**
     * {@code true} if the Policy should advertise to the rest of the system that battery saver
     * is enabled. This advertising could cause other system components to change their
     * behavior. This will not affect other policy flags and what they change.
     */
    private static final String KEY_ADVERTISE_IS_ENABLED = "advertise_is_enabled";

    private static final String KEY_LAUNCH_BOOST_DISABLED = "launch_boost_disabled";
    private static final String KEY_ADJUST_BRIGHTNESS_FACTOR = "adjust_brightness_factor";
    private static final String KEY_FULLBACKUP_DEFERRED = "fullbackup_deferred";
    private static final String KEY_KEYVALUE_DEFERRED = "keyvaluebackup_deferred";
    private static final String KEY_FORCE_ALL_APPS_STANDBY = "force_all_apps_standby";
    private static final String KEY_FORCE_BACKGROUND_CHECK = "force_background_check";
    private static final String KEY_OPTIONAL_SENSORS_DISABLED = "optional_sensors_disabled";
    private static final String KEY_AOD_DISABLED = "aod_disabled";
    // Go into deep Doze as soon as the screen turns off.
    private static final String KEY_QUICK_DOZE_ENABLED = "quick_doze_enabled";
    private static final String KEY_ENABLE_NIGHT_MODE = "enable_night_mode";

    private static final String KEY_CPU_FREQ_INTERACTIVE = "cpufreq-i";
    private static final String KEY_CPU_FREQ_NONINTERACTIVE = "cpufreq-n";

    @VisibleForTesting
    static final Policy OFF_POLICY = new Policy(
            1f,    /* adjustBrightnessFactor */
            false, /* advertiseIsEnabled */
            false, /* deferFullBackup */
            false, /* deferKeyValueBackup */
            false, /* disableAnimation */
            false, /* disableAod */
            false, /* disableLaunchBoost */
            false, /* disableOptionalSensors */
            false, /* disableSoundTrigger */
            false, /* disableVibration */
            false, /* enableAdjustBrightness */
            false, /* enableDataSaver */
            false, /* enableFireWall */
            false, /* enableNightMode */
            false, /* enableQuickDoze */
            new ArrayMap<>(), /* filesForInteractive */
            new ArrayMap<>(), /* filesForNoninteractive */
            false, /* forceAllAppsStandby */
            false, /* forceBackgroundCheck */
            PowerManager.LOCATION_MODE_NO_CHANGE /* locationMode */
    );

    private static final Policy DEFAULT_ADAPTIVE_POLICY = OFF_POLICY;

    private static final Policy DEFAULT_FULL_POLICY = new Policy(
            0.5f,  /* adjustBrightnessFactor */
            true,  /* advertiseIsEnabled */
            true,  /* deferFullBackup */
            true,  /* deferKeyValueBackup */
            false, /* disableAnimation */
            true,  /* disableAod */
            true,  /* disableLaunchBoost */
            true,  /* disableOptionalSensors */
            true,  /* disableSoundTrigger */
            true,  /* disableVibration */
            false, /* enableAdjustBrightness */
            false, /* enableDataSaver */
            true,  /* enableFirewall */
            true, /* enableNightMode */
            true, /* enableQuickDoze */
            new ArrayMap<>(), /* filesForInteractive */
            new ArrayMap<>(), /* filesForNoninteractive */
            true, /* forceAllAppsStandby */
            true, /* forceBackgroundCheck */
            PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF /* locationMode */
    );

    private final Object mLock;
    private final Handler mHandler;

    @GuardedBy("mLock")
    private String mSettings;

    @GuardedBy("mLock")
    private String mDeviceSpecificSettings;

    @GuardedBy("mLock")
    private String mDeviceSpecificSettingsSource; // For dump() only.

    @GuardedBy("mLock")
    private String mAdaptiveSettings;

    @GuardedBy("mLock")
    private String mAdaptiveDeviceSpecificSettings;

    /**
     * A short string describing which battery saver is now enabled, which we dump in the eventlog.
     */
    @GuardedBy("mLock")
    private String mEventLogKeys;

    /**
     * Whether vibration should *really* be disabled -- i.e. {@link Policy#disableVibration}
     * is true *and* {@link #mAccessibilityEnabled} is false.
     */
    @GuardedBy("mLock")
    private boolean mDisableVibrationEffective;

    /**
     * Whether accessibility is currently enabled or not.
     */
    @GuardedBy("mLock")
    private boolean mAccessibilityEnabled;

    /** The current default adaptive policy. */
    @GuardedBy("mLock")
    private Policy mDefaultAdaptivePolicy = DEFAULT_ADAPTIVE_POLICY;

    /** The policy that will be used for adaptive battery saver. */
    @GuardedBy("mLock")
    private Policy mAdaptivePolicy = DEFAULT_ADAPTIVE_POLICY;

    /** The policy to be used for full battery saver. */
    @GuardedBy("mLock")
    private Policy mFullPolicy = DEFAULT_FULL_POLICY;

    @IntDef(prefix = {"POLICY_LEVEL_"}, value = {
            POLICY_LEVEL_OFF,
            POLICY_LEVEL_ADAPTIVE,
            POLICY_LEVEL_FULL,
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface PolicyLevel {}

    static final int POLICY_LEVEL_OFF = 0;
    static final int POLICY_LEVEL_ADAPTIVE = 1;
    static final int POLICY_LEVEL_FULL = 2;

    @GuardedBy("mLock")
    private int mPolicyLevel = POLICY_LEVEL_OFF;

    private final Context mContext;
    private final ContentResolver mContentResolver;
    private final BatterySavingStats mBatterySavingStats;

    @GuardedBy("mLock")
    private final List<BatterySaverPolicyListener> mListeners = new ArrayList<>();

    public interface BatterySaverPolicyListener {
        void onBatterySaverPolicyChanged(BatterySaverPolicy policy);
    }

    public BatterySaverPolicy(Object lock, Context context, BatterySavingStats batterySavingStats) {
        super(BackgroundThread.getHandler());
        mLock = lock;
        mHandler = BackgroundThread.getHandler();
        mContext = context;
        mContentResolver = context.getContentResolver();
        mBatterySavingStats = batterySavingStats;
    }

    /**
     * Called by {@link PowerManagerService#systemReady}, *with no lock held.*
     */
    public void systemReady() {
        ConcurrentUtils.wtfIfLockHeld(TAG, mLock);

        mContentResolver.registerContentObserver(Settings.Global.getUriFor(
                Settings.Global.BATTERY_SAVER_CONSTANTS), false, this);
        mContentResolver.registerContentObserver(Settings.Global.getUriFor(
                Settings.Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS), false, this);
        mContentResolver.registerContentObserver(Settings.Global.getUriFor(
                Settings.Global.BATTERY_SAVER_ADAPTIVE_CONSTANTS), false, this);
        mContentResolver.registerContentObserver(Settings.Global.getUriFor(
                Settings.Global.BATTERY_SAVER_ADAPTIVE_DEVICE_SPECIFIC_CONSTANTS), false, this);

        final AccessibilityManager acm = mContext.getSystemService(AccessibilityManager.class);

        acm.addAccessibilityStateChangeListener((enabled) -> {
            synchronized (mLock) {
                mAccessibilityEnabled = enabled;
            }
            refreshSettings();
        });
        final boolean enabled = acm.isEnabled();
        synchronized (mLock) {
            mAccessibilityEnabled = enabled;
        }
        onChange(true, null);
    }

    @VisibleForTesting
    public void addListener(BatterySaverPolicyListener listener) {
        synchronized (mLock) {
            // TODO: set this in the constructor instead
            mListeners.add(listener);
        }
    }

    @VisibleForTesting
    String getGlobalSetting(String key) {
        return Settings.Global.getString(mContentResolver, key);
    }

    @VisibleForTesting
    int getDeviceSpecificConfigResId() {
        return R.string.config_batterySaverDeviceSpecificConfig;
    }

    @Override
    public void onChange(boolean selfChange, Uri uri) {
        refreshSettings();
    }

    private void refreshSettings() {
        final BatterySaverPolicyListener[] listeners;
        synchronized (mLock) {
            // Load the non-device-specific setting.
            final String setting = getGlobalSetting(Settings.Global.BATTERY_SAVER_CONSTANTS);

            // Load the device specific setting.
            // We first check the global setting, and if it's empty or the string "null" is set,
            // use the default value from config.xml.
            String deviceSpecificSetting = getGlobalSetting(
                    Settings.Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS);
            mDeviceSpecificSettingsSource =
                    Settings.Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS;

            if (TextUtils.isEmpty(deviceSpecificSetting) || "null".equals(deviceSpecificSetting)) {
                deviceSpecificSetting =
                        mContext.getString(getDeviceSpecificConfigResId());
                mDeviceSpecificSettingsSource = "(overlay)";
            }

            final String adaptiveSetting =
                    getGlobalSetting(Settings.Global.BATTERY_SAVER_ADAPTIVE_CONSTANTS);
            final String adaptiveDeviceSpecificSetting = getGlobalSetting(
                    Settings.Global.BATTERY_SAVER_ADAPTIVE_DEVICE_SPECIFIC_CONSTANTS);

            if (!updateConstantsLocked(setting, deviceSpecificSetting,
                    adaptiveSetting, adaptiveDeviceSpecificSetting)) {
                // Nothing of note changed.
                return;
            }

            listeners = mListeners.toArray(new BatterySaverPolicyListener[0]);
        }

        // Notify the listeners.
        mHandler.post(() -> {
            for (BatterySaverPolicyListener listener : listeners) {
                listener.onBatterySaverPolicyChanged(this);
            }
        });
    }

    @GuardedBy("mLock")
    @VisibleForTesting
    void updateConstantsLocked(final String setting, final String deviceSpecificSetting) {
        updateConstantsLocked(setting, deviceSpecificSetting, "", "");
    }

    /** @return true if the currently active policy changed. */
    private boolean updateConstantsLocked(String setting, String deviceSpecificSetting,
            String adaptiveSetting, String adaptiveDeviceSpecificSetting) {
        setting = TextUtils.emptyIfNull(setting);
        deviceSpecificSetting = TextUtils.emptyIfNull(deviceSpecificSetting);
        adaptiveSetting = TextUtils.emptyIfNull(adaptiveSetting);
        adaptiveDeviceSpecificSetting = TextUtils.emptyIfNull(adaptiveDeviceSpecificSetting);

        if (setting.equals(mSettings)
                && deviceSpecificSetting.equals(mDeviceSpecificSettings)
                && adaptiveSetting.equals(mAdaptiveSettings)
                && adaptiveDeviceSpecificSetting.equals(mAdaptiveDeviceSpecificSettings)) {
            return false;
        }

        mSettings = setting;
        mDeviceSpecificSettings = deviceSpecificSetting;
        mAdaptiveSettings = adaptiveSetting;
        mAdaptiveDeviceSpecificSettings = adaptiveDeviceSpecificSetting;

        if (DEBUG) {
            Slog.i(TAG, "mSettings=" + mSettings);
            Slog.i(TAG, "mDeviceSpecificSettings=" + mDeviceSpecificSettings);
            Slog.i(TAG, "mAdaptiveSettings=" + mAdaptiveSettings);
            Slog.i(TAG, "mAdaptiveDeviceSpecificSettings=" + mAdaptiveDeviceSpecificSettings);
        }

        boolean changed = false;
        Policy newFullPolicy = Policy.fromSettings(setting, deviceSpecificSetting,
                DEFAULT_FULL_POLICY);
        if (mPolicyLevel == POLICY_LEVEL_FULL && !mFullPolicy.equals(newFullPolicy)) {
            changed = true;
        }
        mFullPolicy = newFullPolicy;

        mDefaultAdaptivePolicy = Policy.fromSettings(adaptiveSetting, adaptiveDeviceSpecificSetting,
                DEFAULT_ADAPTIVE_POLICY);
        if (mPolicyLevel == POLICY_LEVEL_ADAPTIVE
                && !mAdaptivePolicy.equals(mDefaultAdaptivePolicy)) {
            changed = true;
        }
        // This will override any config set by an external source. This should be fine for now.
        // TODO: make sure it doesn't override what's set externally
        mAdaptivePolicy = mDefaultAdaptivePolicy;

        updatePolicyDependenciesLocked();

        return changed;
    }

    @GuardedBy("mLock")
    private void updatePolicyDependenciesLocked() {
        final Policy currPolicy = getCurrentPolicyLocked();
        // Update the effective vibration policy.
        mDisableVibrationEffective = currPolicy.disableVibration
                && !mAccessibilityEnabled; // Don't disable vibration when accessibility is on.

        final StringBuilder sb = new StringBuilder();

        if (currPolicy.forceAllAppsStandby) sb.append("A");
        if (currPolicy.forceBackgroundCheck) sb.append("B");

        if (mDisableVibrationEffective) sb.append("v");
        if (currPolicy.disableAnimation) sb.append("a");
        if (currPolicy.disableSoundTrigger) sb.append("s");
        if (currPolicy.deferFullBackup) sb.append("F");
        if (currPolicy.deferKeyValueBackup) sb.append("K");
        if (currPolicy.enableFirewall) sb.append("f");
        if (currPolicy.enableDataSaver) sb.append("d");
        if (currPolicy.enableAdjustBrightness) sb.append("b");

        if (currPolicy.disableLaunchBoost) sb.append("l");
        if (currPolicy.disableOptionalSensors) sb.append("S");
        if (currPolicy.disableAod) sb.append("o");
        if (currPolicy.enableQuickDoze) sb.append("q");

        sb.append(currPolicy.locationMode);

        mEventLogKeys = sb.toString();
    }

    static class Policy {
        /**
         * This is the flag to decide the how much to adjust the screen brightness. This is
         * the float value from 0 to 1 where 1 means don't change brightness.
         *
         * @see Settings.Global#BATTERY_SAVER_CONSTANTS
         * @see #KEY_ADJUST_BRIGHTNESS_FACTOR
         */
        public final float adjustBrightnessFactor;

        /**
         * {@code true} if the Policy should advertise to the rest of the system that battery saver
         * is enabled. This advertising could cause other system components to change their
         * behavior. This will not affect other policy flags and what they change.
         *
         * @see Settings.Global#BATTERY_SAVER_CONSTANTS
         * @see #KEY_ADVERTISE_IS_ENABLED
         */
        public final boolean advertiseIsEnabled;

        /**
         * {@code true} if full backup is deferred in battery saver mode.
         *
         * @see Settings.Global#BATTERY_SAVER_CONSTANTS
         * @see #KEY_FULLBACKUP_DEFERRED
         */
        public final boolean deferFullBackup;

        /**
         * {@code true} if key value backup is deferred in battery saver mode.
         *
         * @see Settings.Global#BATTERY_SAVER_CONSTANTS
         * @see #KEY_KEYVALUE_DEFERRED
         */
        public final boolean deferKeyValueBackup;

        /**
         * {@code true} if animation is disabled in battery saver mode.
         *
         * @see Settings.Global#BATTERY_SAVER_CONSTANTS
         * @see #KEY_ANIMATION_DISABLED
         */
        public final boolean disableAnimation;

        /**
         * {@code true} if AOD is disabled in battery saver mode.
         */
        public final boolean disableAod;

        /**
         * {@code true} if launch boost should be disabled on battery saver.
         */
        public final boolean disableLaunchBoost;

        /**
         * Whether to show non-essential sensors (e.g. edge sensors) or not.
         */
        public final boolean disableOptionalSensors;

        /**
         * {@code true} if sound trigger is disabled in battery saver mode
         * in battery saver mode.
         *
         * @see Settings.Global#BATTERY_SAVER_CONSTANTS
         * @see #KEY_SOUNDTRIGGER_DISABLED
         */
        public final boolean disableSoundTrigger;

        /**
         * {@code true} if vibration is disabled in battery saver mode.
         *
         * @see Settings.Global#BATTERY_SAVER_CONSTANTS
         * @see #KEY_VIBRATION_DISABLED
         */
        public final boolean disableVibration;

        /**
         * {@code true} if low power mode brightness adjustment should be turned on in battery saver
         * mode.
         *
         * @see Settings.Global#BATTERY_SAVER_CONSTANTS
         * @see #KEY_ADJUST_BRIGHTNESS_DISABLED
         */
        public final boolean enableAdjustBrightness;

        /**
         * {@code true} if data saver should be turned on in battery saver mode.
         *
         * @see Settings.Global#BATTERY_SAVER_CONSTANTS
         * @see #KEY_ACTIVATE_DATASAVER_DISABLED
         */
        public final boolean enableDataSaver;

        /**
         * {@code true} if network policy firewall should be turned on in battery saver mode.
         *
         * @see Settings.Global#BATTERY_SAVER_CONSTANTS
         * @see #KEY_ACTIVATE_FIREWALL_DISABLED
         */
        public final boolean enableFirewall;

        /**
         * Whether to enable night mode or not.
         */
        public final boolean enableNightMode;

        /**
         * Whether Quick Doze is enabled or not.
         */
        public final boolean enableQuickDoze;

        /**
         * List of [Filename -> content] that should be written when battery saver is activated
         * and the device is interactive.
         *
         * We use this to change the max CPU frequencies.
         */
        public final ArrayMap<String, String> filesForInteractive;

        /**
         * List of [Filename -> content] that should be written when battery saver is activated
         * and the device is non-interactive.
         *
         * We use this to change the max CPU frequencies.
         */
        public final ArrayMap<String, String> filesForNoninteractive;

        /**
         * Whether to put all apps in the stand-by mode.
         */
        public final boolean forceAllAppsStandby;

        /**
         * Whether to force background check.
         */
        public final boolean forceBackgroundCheck;

        /**
         * This is the flag to decide the location mode in battery saver mode. This was
         * previously called gpsMode.
         *
         * @see Settings.Global#BATTERY_SAVER_CONSTANTS
         * @see #KEY_GPS_MODE
         */
        public final int locationMode;

        private final int mHashCode;

        Policy(
                float adjustBrightnessFactor,
                boolean advertiseIsEnabled,
                boolean deferFullBackup,
                boolean deferKeyValueBackup,
                boolean disableAnimation,
                boolean disableAod,
                boolean disableLaunchBoost,
                boolean disableOptionalSensors,
                boolean disableSoundTrigger,
                boolean disableVibration,
                boolean enableAdjustBrightness,
                boolean enableDataSaver,
                boolean enableFirewall,
                boolean enableNightMode,
                boolean enableQuickDoze,
                ArrayMap<String, String> filesForInteractive,
                ArrayMap<String, String> filesForNoninteractive,
                boolean forceAllAppsStandby,
                boolean forceBackgroundCheck,
                int locationMode) {

            this.adjustBrightnessFactor = Math.min(1, Math.max(0, adjustBrightnessFactor));
            this.advertiseIsEnabled = advertiseIsEnabled;
            this.deferFullBackup = deferFullBackup;
            this.deferKeyValueBackup = deferKeyValueBackup;
            this.disableAnimation = disableAnimation;
            this.disableAod = disableAod;
            this.disableLaunchBoost = disableLaunchBoost;
            this.disableOptionalSensors = disableOptionalSensors;
            this.disableSoundTrigger = disableSoundTrigger;
            this.disableVibration = disableVibration;
            this.enableAdjustBrightness = enableAdjustBrightness;
            this.enableDataSaver = enableDataSaver;
            this.enableFirewall = enableFirewall;
            this.enableNightMode = enableNightMode;
            this.enableQuickDoze = enableQuickDoze;
            this.filesForInteractive = filesForInteractive;
            this.filesForNoninteractive = filesForNoninteractive;
            this.forceAllAppsStandby = forceAllAppsStandby;
            this.forceBackgroundCheck = forceBackgroundCheck;

            if (locationMode < PowerManager.MIN_LOCATION_MODE
                    || PowerManager.MAX_LOCATION_MODE < locationMode) {
                Slog.e(TAG, "Invalid location mode: " + locationMode);
                this.locationMode = PowerManager.LOCATION_MODE_NO_CHANGE;
            } else {
                this.locationMode = locationMode;
            }

            mHashCode = Objects.hash(
                    adjustBrightnessFactor,
                    advertiseIsEnabled,
                    deferFullBackup,
                    deferKeyValueBackup,
                    disableAnimation,
                    disableAod,
                    disableLaunchBoost,
                    disableOptionalSensors,
                    disableSoundTrigger,
                    disableVibration,
                    enableAdjustBrightness,
                    enableDataSaver,
                    enableFirewall,
                    enableNightMode,
                    enableQuickDoze,
                    filesForInteractive,
                    filesForNoninteractive,
                    forceAllAppsStandby,
                    forceBackgroundCheck,
                    locationMode);
        }

        static Policy fromConfig(BatterySaverPolicyConfig config) {
            if (config == null) {
                Slog.e(TAG, "Null config passed down to BatterySaverPolicy");
                return OFF_POLICY;
            }

            // Device-specific parameters.
            Map<String, String> deviceSpecificSettings = config.getDeviceSpecificSettings();
            final String cpuFreqInteractive =
                    deviceSpecificSettings.getOrDefault(KEY_CPU_FREQ_INTERACTIVE, "");
            final String cpuFreqNoninteractive =
                    deviceSpecificSettings.getOrDefault(KEY_CPU_FREQ_NONINTERACTIVE, "");

            return new Policy(
                    config.getAdjustBrightnessFactor(),
                    config.getAdvertiseIsEnabled(),
                    config.getDeferFullBackup(),
                    config.getDeferKeyValueBackup(),
                    config.getDisableAnimation(),
                    config.getDisableAod(),
                    config.getDisableLaunchBoost(),
                    config.getDisableOptionalSensors(),
                    config.getDisableSoundTrigger(),
                    config.getDisableVibration(),
                    config.getEnableAdjustBrightness(),
                    config.getEnableDataSaver(),
                    config.getEnableFirewall(),
                    config.getEnableNightMode(),
                    config.getEnableQuickDoze(),
                    /* filesForInteractive */
                    (new CpuFrequencies()).parseString(cpuFreqInteractive).toSysFileMap(),
                    /* filesForNoninteractive */
                    (new CpuFrequencies()).parseString(cpuFreqNoninteractive).toSysFileMap(),
                    config.getForceAllAppsStandby(),
                    config.getForceBackgroundCheck(),
                    config.getLocationMode()
            );
        }

        static Policy fromSettings(String settings, String deviceSpecificSettings) {
            return fromSettings(settings, deviceSpecificSettings, OFF_POLICY);
        }

        static Policy fromSettings(String settings, String deviceSpecificSettings,
                Policy defaultPolicy) {
            final KeyValueListParser parser = new KeyValueListParser(',');

            // Device-specific parameters.
            try {
                parser.setString(deviceSpecificSettings == null ? "" : deviceSpecificSettings);
            } catch (IllegalArgumentException e) {
                Slog.wtf(TAG, "Bad device specific battery saver constants: "
                        + deviceSpecificSettings);
            }

            final String cpuFreqInteractive = parser.getString(KEY_CPU_FREQ_INTERACTIVE, "");
            final String cpuFreqNoninteractive = parser.getString(KEY_CPU_FREQ_NONINTERACTIVE, "");

            // Non-device-specific parameters.
            try {
                parser.setString(settings == null ? "" : settings);
            } catch (IllegalArgumentException e) {
                Slog.wtf(TAG, "Bad battery saver constants: " + settings);
            }

            float adjustBrightnessFactor = parser.getFloat(KEY_ADJUST_BRIGHTNESS_FACTOR,
                    defaultPolicy.adjustBrightnessFactor);
            boolean advertiseIsEnabled = parser.getBoolean(KEY_ADVERTISE_IS_ENABLED,
                    defaultPolicy.advertiseIsEnabled);
            boolean deferFullBackup = parser.getBoolean(KEY_FULLBACKUP_DEFERRED,
                    defaultPolicy.deferFullBackup);
            boolean deferKeyValueBackup = parser.getBoolean(KEY_KEYVALUE_DEFERRED,
                    defaultPolicy.deferKeyValueBackup);
            boolean disableAnimation = parser.getBoolean(KEY_ANIMATION_DISABLED,
                    defaultPolicy.disableAnimation);
            boolean disableAod = parser.getBoolean(KEY_AOD_DISABLED, defaultPolicy.disableAod);
            boolean disableLaunchBoost = parser.getBoolean(KEY_LAUNCH_BOOST_DISABLED,
                    defaultPolicy.disableLaunchBoost);
            boolean disableOptionalSensors = parser.getBoolean(KEY_OPTIONAL_SENSORS_DISABLED,
                    defaultPolicy.disableOptionalSensors);
            boolean disableSoundTrigger = parser.getBoolean(KEY_SOUNDTRIGGER_DISABLED,
                    defaultPolicy.disableSoundTrigger);
            boolean disableVibrationConfig = parser.getBoolean(KEY_VIBRATION_DISABLED,
                    defaultPolicy.disableVibration);
            boolean enableAdjustBrightness = !parser.getBoolean(KEY_ADJUST_BRIGHTNESS_DISABLED,
                    !defaultPolicy.enableAdjustBrightness);
            boolean enableDataSaver = !parser.getBoolean(KEY_ACTIVATE_DATASAVER_DISABLED,
                    !defaultPolicy.enableDataSaver);
            boolean enableFirewall = !parser.getBoolean(KEY_ACTIVATE_FIREWALL_DISABLED,
                    !defaultPolicy.enableFirewall);
            boolean enableNightMode = parser.getBoolean(KEY_ENABLE_NIGHT_MODE,
                    defaultPolicy.enableNightMode);
            boolean enableQuickDoze = parser.getBoolean(KEY_QUICK_DOZE_ENABLED,
                    defaultPolicy.enableQuickDoze);
            boolean forceAllAppsStandby = parser.getBoolean(KEY_FORCE_ALL_APPS_STANDBY,
                    defaultPolicy.forceAllAppsStandby);
            boolean forceBackgroundCheck = parser.getBoolean(KEY_FORCE_BACKGROUND_CHECK,
                    defaultPolicy.forceBackgroundCheck);
            int locationMode = parser.getInt(KEY_GPS_MODE, defaultPolicy.locationMode);

            return new Policy(
                    adjustBrightnessFactor,
                    advertiseIsEnabled,
                    deferFullBackup,
                    deferKeyValueBackup,
                    disableAnimation,
                    disableAod,
                    disableLaunchBoost,
                    disableOptionalSensors,
                    disableSoundTrigger,
                    /* disableVibration */
                    disableVibrationConfig,
                    enableAdjustBrightness,
                    enableDataSaver,
                    enableFirewall,
                    enableNightMode,
                    enableQuickDoze,
                    /* filesForInteractive */
                    (new CpuFrequencies()).parseString(cpuFreqInteractive).toSysFileMap(),
                    /* filesForNoninteractive */
                    (new CpuFrequencies()).parseString(cpuFreqNoninteractive).toSysFileMap(),
                    forceAllAppsStandby,
                    forceBackgroundCheck,
                    locationMode
            );
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (!(obj instanceof Policy)) return false;
            Policy other = (Policy) obj;
            return Float.compare(other.adjustBrightnessFactor, adjustBrightnessFactor) == 0
                    && advertiseIsEnabled == other.advertiseIsEnabled
                    && deferFullBackup == other.deferFullBackup
                    && deferKeyValueBackup == other.deferKeyValueBackup
                    && disableAnimation == other.disableAnimation
                    && disableAod == other.disableAod
                    && disableLaunchBoost == other.disableLaunchBoost
                    && disableOptionalSensors == other.disableOptionalSensors
                    && disableSoundTrigger == other.disableSoundTrigger
                    && disableVibration == other.disableVibration
                    && enableAdjustBrightness == other.enableAdjustBrightness
                    && enableDataSaver == other.enableDataSaver
                    && enableFirewall == other.enableFirewall
                    && enableNightMode == other.enableNightMode
                    && enableQuickDoze == other.enableQuickDoze
                    && forceAllAppsStandby == other.forceAllAppsStandby
                    && forceBackgroundCheck == other.forceBackgroundCheck
                    && locationMode == other.locationMode
                    && filesForInteractive.equals(other.filesForInteractive)
                    && filesForNoninteractive.equals(other.filesForNoninteractive);
        }

        @Override
        public int hashCode() {
            return mHashCode;
        }
    }

    /**
     * Get the {@link PowerSaveState} based on the current policy level.
     * The result will have {@link PowerSaveState#batterySaverEnabled} and some other
     * parameters when necessary.
     *
     * @param type   type of the service, one of {@link ServiceType}
     * @return State data that contains battery saver data
     */
    public PowerSaveState getBatterySaverPolicy(@ServiceType int type) {
        synchronized (mLock) {
            final Policy currPolicy = getCurrentPolicyLocked();
            final PowerSaveState.Builder builder = new PowerSaveState.Builder()
                    .setGlobalBatterySaverEnabled(currPolicy.advertiseIsEnabled);
            switch (type) {
                case ServiceType.LOCATION:
                    boolean isEnabled = currPolicy.advertiseIsEnabled
                            || currPolicy.locationMode != PowerManager.LOCATION_MODE_NO_CHANGE;
                    return builder.setBatterySaverEnabled(isEnabled)
                            .setLocationMode(currPolicy.locationMode)
                            .build();
                case ServiceType.ANIMATION:
                    return builder.setBatterySaverEnabled(currPolicy.disableAnimation)
                            .build();
                case ServiceType.FULL_BACKUP:
                    return builder.setBatterySaverEnabled(currPolicy.deferFullBackup)
                            .build();
                case ServiceType.KEYVALUE_BACKUP:
                    return builder.setBatterySaverEnabled(currPolicy.deferKeyValueBackup)
                            .build();
                case ServiceType.NETWORK_FIREWALL:
                    return builder.setBatterySaverEnabled(currPolicy.enableFirewall)
                            .build();
                case ServiceType.SCREEN_BRIGHTNESS:
                    return builder.setBatterySaverEnabled(currPolicy.enableAdjustBrightness)
                            .setBrightnessFactor(currPolicy.adjustBrightnessFactor)
                            .build();
                case ServiceType.DATA_SAVER:
                    return builder.setBatterySaverEnabled(currPolicy.enableDataSaver)
                            .build();
                case ServiceType.SOUND:
                    return builder.setBatterySaverEnabled(currPolicy.disableSoundTrigger)
                            .build();
                case ServiceType.VIBRATION:
                    return builder.setBatterySaverEnabled(mDisableVibrationEffective)
                            .build();
                case ServiceType.FORCE_ALL_APPS_STANDBY:
                    return builder.setBatterySaverEnabled(currPolicy.forceAllAppsStandby)
                            .build();
                case ServiceType.FORCE_BACKGROUND_CHECK:
                    return builder.setBatterySaverEnabled(currPolicy.forceBackgroundCheck)
                            .build();
                case ServiceType.NIGHT_MODE:
                    return builder.setBatterySaverEnabled(currPolicy.enableNightMode)
                            .build();
                case ServiceType.OPTIONAL_SENSORS:
                    return builder.setBatterySaverEnabled(currPolicy.disableOptionalSensors)
                            .build();
                case ServiceType.AOD:
                    return builder.setBatterySaverEnabled(currPolicy.disableAod)
                            .build();
                case ServiceType.QUICK_DOZE:
                    return builder.setBatterySaverEnabled(currPolicy.enableQuickDoze)
                            .build();
                default:
                    return builder.setBatterySaverEnabled(currPolicy.advertiseIsEnabled)
                            .build();
            }
        }
    }

    /**
     * Sets the current policy.
     *
     * @return true if the policy level was changed.
     */
    boolean setPolicyLevel(@PolicyLevel int level) {
        synchronized (mLock) {
            if (mPolicyLevel == level) {
                return false;
            }
            switch (level) {
                case POLICY_LEVEL_FULL:
                case POLICY_LEVEL_ADAPTIVE:
                case POLICY_LEVEL_OFF:
                    mPolicyLevel = level;
                    break;
                default:
                    Slog.wtf(TAG, "setPolicyLevel invalid level given: " + level);
                    return false;
            }
            updatePolicyDependenciesLocked();
            return true;
        }
    }

    /** @return true if the current policy changed and the policy level is ADAPTIVE. */
    boolean setAdaptivePolicyLocked(Policy p) {
        if (p == null) {
            Slog.wtf(TAG, "setAdaptivePolicy given null policy");
            return false;
        }
        if (mAdaptivePolicy.equals(p)) {
            return false;
        }

        mAdaptivePolicy = p;
        if (mPolicyLevel == POLICY_LEVEL_ADAPTIVE) {
            updatePolicyDependenciesLocked();
            return true;
        }
        return false;
    }

    /** @return true if the current policy changed and the policy level is ADAPTIVE. */
    boolean resetAdaptivePolicyLocked() {
        return setAdaptivePolicyLocked(mDefaultAdaptivePolicy);
    }

    private Policy getCurrentPolicyLocked() {
        switch (mPolicyLevel) {
            case POLICY_LEVEL_FULL:
                return mFullPolicy;
            case POLICY_LEVEL_ADAPTIVE:
                return mAdaptivePolicy;
            case POLICY_LEVEL_OFF:
            default:
                return OFF_POLICY;
        }
    }

    public int getGpsMode() {
        synchronized (mLock) {
            return getCurrentPolicyLocked().locationMode;
        }
    }

    public ArrayMap<String, String> getFileValues(boolean interactive) {
        synchronized (mLock) {
            return interactive ? getCurrentPolicyLocked().filesForInteractive
                    : getCurrentPolicyLocked().filesForNoninteractive;
        }
    }

    public boolean isLaunchBoostDisabled() {
        synchronized (mLock) {
            return getCurrentPolicyLocked().disableLaunchBoost;
        }
    }

    boolean shouldAdvertiseIsEnabled() {
        synchronized (mLock) {
            return getCurrentPolicyLocked().advertiseIsEnabled;
        }
    }

    public String toEventLogString() {
        synchronized (mLock) {
            return mEventLogKeys;
        }
    }

    public void dump(PrintWriter pw) {
        synchronized (mLock) {
            pw.println();
            mBatterySavingStats.dump(pw, "");

            pw.println();
            pw.println("Battery saver policy (*NOTE* they only apply when battery saver is ON):");
            pw.println("  Settings: " + Settings.Global.BATTERY_SAVER_CONSTANTS);
            pw.println("    value: " + mSettings);
            pw.println("  Settings: " + mDeviceSpecificSettingsSource);
            pw.println("    value: " + mDeviceSpecificSettings);

            pw.println("  Adaptive Settings: " + Settings.Global.BATTERY_SAVER_ADAPTIVE_CONSTANTS);
            pw.println("    value: " + mAdaptiveSettings);
            pw.println("  Adaptive Device Specific Settings: "
                    + Settings.Global.BATTERY_SAVER_ADAPTIVE_DEVICE_SPECIFIC_CONSTANTS);
            pw.println("    value: " + mAdaptiveDeviceSpecificSettings);

            pw.println("  mAccessibilityEnabled=" + mAccessibilityEnabled);
            pw.println("  mPolicyLevel=" + mPolicyLevel);

            dumpPolicyLocked(pw, "  ", "full", mFullPolicy);
            dumpPolicyLocked(pw, "  ", "default adaptive", mDefaultAdaptivePolicy);
            dumpPolicyLocked(pw, "  ", "current adaptive", mAdaptivePolicy);
        }
    }

    private void dumpPolicyLocked(PrintWriter pw, String indent, String label, Policy p) {
        pw.println();
        pw.print(indent);
        pw.println("Policy '" + label + "'");
        pw.print(indent);
        pw.println("  " + KEY_ADVERTISE_IS_ENABLED + "=" + p.advertiseIsEnabled);
        pw.print(indent);
        pw.println("  " + KEY_VIBRATION_DISABLED + ":config=" + p.disableVibration);
        // mDisableVibrationEffective is based on the currently selected policy
        pw.print(indent);
        pw.println("  " + KEY_VIBRATION_DISABLED + ":effective=" + (p.disableVibration
                && !mAccessibilityEnabled));
        pw.print(indent);
        pw.println("  " + KEY_ANIMATION_DISABLED + "=" + p.disableAnimation);
        pw.print(indent);
        pw.println("  " + KEY_FULLBACKUP_DEFERRED + "=" + p.deferFullBackup);
        pw.print(indent);
        pw.println("  " + KEY_KEYVALUE_DEFERRED + "=" + p.deferKeyValueBackup);
        pw.print(indent);
        pw.println("  " + KEY_ACTIVATE_FIREWALL_DISABLED + "=" + !p.enableFirewall);
        pw.print(indent);
        pw.println("  " + KEY_ACTIVATE_DATASAVER_DISABLED + "=" + !p.enableDataSaver);
        pw.print(indent);
        pw.println("  " + KEY_LAUNCH_BOOST_DISABLED + "=" + p.disableLaunchBoost);
        pw.println(
                "    " + KEY_ADJUST_BRIGHTNESS_DISABLED + "=" + !p.enableAdjustBrightness);
        pw.print(indent);
        pw.println("  " + KEY_ADJUST_BRIGHTNESS_FACTOR + "=" + p.adjustBrightnessFactor);
        pw.print(indent);
        pw.println("  " + KEY_GPS_MODE + "=" + p.locationMode);
        pw.print(indent);
        pw.println("  " + KEY_FORCE_ALL_APPS_STANDBY + "=" + p.forceAllAppsStandby);
        pw.print(indent);
        pw.println("  " + KEY_FORCE_BACKGROUND_CHECK + "=" + p.forceBackgroundCheck);
        pw.println(
                "    " + KEY_OPTIONAL_SENSORS_DISABLED + "=" + p.disableOptionalSensors);
        pw.print(indent);
        pw.println("  " + KEY_AOD_DISABLED + "=" + p.disableAod);
        pw.print(indent);
        pw.println("  " + KEY_SOUNDTRIGGER_DISABLED + "=" + p.disableSoundTrigger);
        pw.print(indent);
        pw.println("  " + KEY_QUICK_DOZE_ENABLED + "=" + p.enableQuickDoze);
        pw.print(indent);
        pw.println("  " + KEY_ENABLE_NIGHT_MODE + "=" + p.enableNightMode);

        pw.print("    Interactive File values:\n");
        dumpMap(pw, "      ", p.filesForInteractive);
        pw.println();

        pw.print("    Noninteractive File values:\n");
        dumpMap(pw, "      ", p.filesForNoninteractive);
    }

    private void dumpMap(PrintWriter pw, String prefix, ArrayMap<String, String> map) {
        if (map == null) {
            return;
        }
        final int size = map.size();
        for (int i = 0; i < size; i++) {
            pw.print(prefix);
            pw.print(map.keyAt(i));
            pw.print(": '");
            pw.print(map.valueAt(i));
            pw.println("'");
        }
    }

    @VisibleForTesting
    public void setAccessibilityEnabledForTest(boolean enabled) {
        synchronized (mLock) {
            mAccessibilityEnabled = enabled;
            updatePolicyDependenciesLocked();
        }
    }
}
