/*
 * Copyright (C) 2018 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 static com.android.server.power.batterysaver.BatterySaverController.reasonToString;

import android.annotation.NonNull;
import android.annotation.StringRes;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.os.BatterySaverPolicyConfig;
import android.os.Handler;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;

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.server.EventLogTags;
import com.android.server.power.BatterySaverStateMachineProto;

import java.io.PrintWriter;
import java.text.NumberFormat;

/**
 * Decides when to enable / disable battery saver.
 *
 * IMPORTANT: This class shares the power manager lock, which is very low in the lock hierarchy.
 * Do not call out with the lock held. (Settings provider is okay.)
 *
 * Test: atest com.android.server.power.batterysaver.BatterySaverStateMachineTest
 *
 * Current state machine. This can be visualized using Graphviz:
   <pre>

   digraph {
     STATE_OFF
     STATE_MANUAL_ON [label="STATE_MANUAL_ON\nTurned on manually by the user"]
     STATE_AUTOMATIC_ON [label="STATE_AUTOMATIC_ON\nTurned on automatically by the system"]
     STATE_OFF_AUTOMATIC_SNOOZED [
       label="STATE_OFF_AUTOMATIC_SNOOZED\nTurned off manually by the user."
           + " The system should not turn it back on automatically."
     ]
     STATE_PENDING_STICKY_ON [
       label="STATE_PENDING_STICKY_ON\n"
           + " Turned on manually by the user and then plugged in. Will turn back on after unplug."
     ]

     STATE_OFF -> STATE_MANUAL_ON [label="manual"]
     STATE_OFF -> STATE_AUTOMATIC_ON [label="Auto on AND charge <= auto threshold"]

     STATE_MANUAL_ON -> STATE_OFF [label="manual\nOR\nPlugged & sticky disabled"]
     STATE_MANUAL_ON -> STATE_PENDING_STICKY_ON [label="Plugged & sticky enabled"]

     STATE_PENDING_STICKY_ON -> STATE_MANUAL_ON [label="Unplugged & sticky enabled"]
     STATE_PENDING_STICKY_ON -> STATE_OFF [
       label="Sticky disabled\nOR\nSticky auto off enabled AND charge >= sticky auto off threshold"
     ]

     STATE_AUTOMATIC_ON -> STATE_OFF [label="Plugged"]
     STATE_AUTOMATIC_ON -> STATE_OFF_AUTOMATIC_SNOOZED [label="Manual"]

     STATE_OFF_AUTOMATIC_SNOOZED -> STATE_OFF [label="Plug\nOR\nCharge > auto threshold"]
     STATE_OFF_AUTOMATIC_SNOOZED -> STATE_MANUAL_ON [label="manual"]

     </pre>
   }
 */
public class BatterySaverStateMachine {
    private static final String TAG = "BatterySaverStateMachine";
    private static final String DYNAMIC_MODE_NOTIF_CHANNEL_ID = "dynamic_mode_notification";
    private static final String BATTERY_SAVER_NOTIF_CHANNEL_ID = "battery_saver_channel";
    private static final int DYNAMIC_MODE_NOTIFICATION_ID = 1992;
    private static final int STICKY_AUTO_DISABLED_NOTIFICATION_ID = 1993;
    private final Object mLock;

    private static final boolean DEBUG = BatterySaverPolicy.DEBUG;

    private static final long ADAPTIVE_CHANGE_TIMEOUT_MS = 24 * 60 * 60 * 1000L;

    /** Turn off adaptive battery saver if the device has charged above this level. */
    private static final int ADAPTIVE_AUTO_DISABLE_BATTERY_LEVEL = 80;

    private static final int STATE_OFF = BatterySaverStateMachineProto.STATE_OFF;

    /** Turned on manually by the user. */
    private static final int STATE_MANUAL_ON = BatterySaverStateMachineProto.STATE_MANUAL_ON;

    /** Turned on automatically by the system. */
    private static final int STATE_AUTOMATIC_ON = BatterySaverStateMachineProto.STATE_AUTOMATIC_ON;

    /** Turned off manually by the user. The system should not turn it back on automatically. */
    private static final int STATE_OFF_AUTOMATIC_SNOOZED =
            BatterySaverStateMachineProto.STATE_OFF_AUTOMATIC_SNOOZED;

    /** Turned on manually by the user and then plugged in. Will turn back on after unplug. */
    private static final int STATE_PENDING_STICKY_ON =
            BatterySaverStateMachineProto.STATE_PENDING_STICKY_ON;

    private final Context mContext;
    private final BatterySaverController mBatterySaverController;

    /** Whether the system has booted. */
    @GuardedBy("mLock")
    private boolean mBootCompleted;

    /** Whether global settings have been loaded already. */
    @GuardedBy("mLock")
    private boolean mSettingsLoaded;

    /** Whether the first battery status has arrived. */
    @GuardedBy("mLock")
    private boolean mBatteryStatusSet;

    @GuardedBy("mLock")
    private int mState;

    /** Whether the device is connected to any power source. */
    @GuardedBy("mLock")
    private boolean mIsPowered;

    /** Current battery level in %, 0-100. (Currently only used in dumpsys.) */
    @GuardedBy("mLock")
    private int mBatteryLevel;

    /** Whether the battery level is considered to be "low" or not. */
    @GuardedBy("mLock")
    private boolean mIsBatteryLevelLow;

    /** Previously known value of Settings.Global.LOW_POWER_MODE. */
    @GuardedBy("mLock")
    private boolean mSettingBatterySaverEnabled;

    /** Previously known value of Settings.Global.LOW_POWER_MODE_STICKY. */
    @GuardedBy("mLock")
    private boolean mSettingBatterySaverEnabledSticky;

    /** Config flag to track if battery saver's sticky behaviour is disabled. */
    private final boolean mBatterySaverStickyBehaviourDisabled;

    /**
     * Whether or not to end sticky battery saver upon reaching a level specified by
     * {@link #mSettingBatterySaverStickyAutoDisableThreshold}.
     */
    @GuardedBy("mLock")
    private boolean mSettingBatterySaverStickyAutoDisableEnabled;

    /**
     * The battery level at which to end sticky battery saver. Only useful if
     * {@link #mSettingBatterySaverStickyAutoDisableEnabled} is {@code true}.
     */
    @GuardedBy("mLock")
    private int mSettingBatterySaverStickyAutoDisableThreshold;

    /** Config flag to track default disable threshold for Dynamic Power Savings enabled battery
     * saver. */
    @GuardedBy("mLock")
    private final int mDynamicPowerSavingsDefaultDisableThreshold;

    /**
     * Previously known value of Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL.
     * (Currently only used in dumpsys.)
     */
    @GuardedBy("mLock")
    private int mSettingBatterySaverTriggerThreshold;

    /** Previously known value of Settings.Global.AUTOMATIC_POWER_SAVE_MODE. */
    @GuardedBy("mLock")
    private int mSettingAutomaticBatterySaver;

    /** When to disable battery saver again if it was enabled due to an external suggestion.
     *  Corresponds to Settings.Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD.
     */
    @GuardedBy("mLock")
    private int mDynamicPowerSavingsDisableThreshold;

    /**
     * Whether we've received a suggestion that battery saver should be on from an external app.
     * Updates when Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED changes.
     */
    @GuardedBy("mLock")
    private boolean mDynamicPowerSavingsBatterySaver;

    /**
     * Last reason passed to {@link #enableBatterySaverLocked}.
     */
    @GuardedBy("mLock")
    private int mLastChangedIntReason;

    /**
     * Last reason passed to {@link #enableBatterySaverLocked}.
     */
    @GuardedBy("mLock")
    private String mLastChangedStrReason;

    /**
     * The last time adaptive battery saver was changed by an external service, using elapsed
     * realtime as the timebase.
     */
    @GuardedBy("mLock")
    private long mLastAdaptiveBatterySaverChangedExternallyElapsed;

    private final ContentObserver mSettingsObserver = new ContentObserver(null) {
        @Override
        public void onChange(boolean selfChange) {
            synchronized (mLock) {
                refreshSettingsLocked();
            }
        }
    };

    public BatterySaverStateMachine(Object lock,
            Context context, BatterySaverController batterySaverController) {
        mLock = lock;
        mContext = context;
        mBatterySaverController = batterySaverController;
        mState = STATE_OFF;

        mBatterySaverStickyBehaviourDisabled = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_batterySaverStickyBehaviourDisabled);
        mDynamicPowerSavingsDefaultDisableThreshold = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_dynamicPowerSavingsDefaultDisableThreshold);
    }

    /** @return true if the automatic percentage based mode should be used */
    private boolean isAutomaticModeActiveLocked() {
        return mSettingAutomaticBatterySaver == PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE
                && mSettingBatterySaverTriggerThreshold > 0;
    }

    /**
     * The returned value won't necessarily make sense if {@link #isAutomaticModeActiveLocked()}
     * returns {@code false}.
     *
     * @return true if the battery level is below automatic's threshold.
     */
    private boolean isInAutomaticLowZoneLocked() {
        return mIsBatteryLevelLow;
    }

    /** @return true if the dynamic mode should be used */
    private boolean isDynamicModeActiveLocked() {
        return mSettingAutomaticBatterySaver == PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC
                && mDynamicPowerSavingsBatterySaver;
    }

    /**
     * The returned value won't necessarily make sense if {@link #isDynamicModeActiveLocked()}
     * returns {@code false}.
     *
     * @return true if the battery level is below dynamic's threshold.
     */
    private boolean isInDynamicLowZoneLocked() {
        return mBatteryLevel <= mDynamicPowerSavingsDisableThreshold;
    }

    /**
     * {@link com.android.server.power.PowerManagerService} calls it when the system is booted.
     */
    public void onBootCompleted() {
        if (DEBUG) {
            Slog.d(TAG, "onBootCompleted");
        }
        // Just booted. We don't want LOW_POWER_MODE to be persisted, so just always clear it.
        putGlobalSetting(Settings.Global.LOW_POWER_MODE, 0);

        // This is called with the power manager lock held. Don't do anything that may call to
        // upper services. (e.g. don't call into AM directly)
        // So use a BG thread.
        runOnBgThread(() -> {

            final ContentResolver cr = mContext.getContentResolver();
            cr.registerContentObserver(Settings.Global.getUriFor(
                    Settings.Global.LOW_POWER_MODE),
                    false, mSettingsObserver, UserHandle.USER_SYSTEM);
            cr.registerContentObserver(Settings.Global.getUriFor(
                    Settings.Global.LOW_POWER_MODE_STICKY),
                    false, mSettingsObserver, UserHandle.USER_SYSTEM);
            cr.registerContentObserver(Settings.Global.getUriFor(
                    Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
                    false, mSettingsObserver, UserHandle.USER_SYSTEM);
            cr.registerContentObserver(Settings.Global.getUriFor(
                    Settings.Global.AUTOMATIC_POWER_SAVE_MODE),
                    false, mSettingsObserver, UserHandle.USER_SYSTEM);
            cr.registerContentObserver(Settings.Global.getUriFor(
                    Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED),
                    false, mSettingsObserver, UserHandle.USER_SYSTEM);
            cr.registerContentObserver(Settings.Global.getUriFor(
                    Settings.Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD),
                    false, mSettingsObserver, UserHandle.USER_SYSTEM);
            cr.registerContentObserver(Settings.Global.getUriFor(
                    Settings.Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED),
                    false, mSettingsObserver, UserHandle.USER_SYSTEM);
            cr.registerContentObserver(Settings.Global.getUriFor(
                    Settings.Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL),
                    false, mSettingsObserver, UserHandle.USER_SYSTEM);


            synchronized (mLock) {
                final boolean lowPowerModeEnabledSticky = getGlobalSetting(
                        Settings.Global.LOW_POWER_MODE_STICKY, 0) != 0;

                if (lowPowerModeEnabledSticky) {
                    mState = STATE_PENDING_STICKY_ON;
                }

                mBootCompleted = true;

                refreshSettingsLocked();

                doAutoBatterySaverLocked();
            }
        });
    }

    /**
     * Run a {@link Runnable} on a background handler.
     */
    @VisibleForTesting
    void runOnBgThread(Runnable r) {
        BackgroundThread.getHandler().post(r);
    }

    /**
     * Run a {@link Runnable} on a background handler, but lazily. If the same {@link Runnable} is
     * already registered, it'll be first removed before being re-posted.
     */
    @VisibleForTesting
    void runOnBgThreadLazy(Runnable r, int delayMillis) {
        final Handler h = BackgroundThread.getHandler();
        h.removeCallbacks(r);
        h.postDelayed(r, delayMillis);
    }

    @GuardedBy("mLock")
    private void refreshSettingsLocked() {
        final boolean lowPowerModeEnabled = getGlobalSetting(
                Settings.Global.LOW_POWER_MODE, 0) != 0;
        final boolean lowPowerModeEnabledSticky = getGlobalSetting(
                Settings.Global.LOW_POWER_MODE_STICKY, 0) != 0;
        final boolean dynamicPowerSavingsBatterySaver = getGlobalSetting(
                Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0) != 0;
        final int lowPowerModeTriggerLevel = getGlobalSetting(
                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
        final int automaticBatterySaverMode = getGlobalSetting(
                Settings.Global.AUTOMATIC_POWER_SAVE_MODE,
                PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
        final int dynamicPowerSavingsDisableThreshold = getGlobalSetting(
                Settings.Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD,
                mDynamicPowerSavingsDefaultDisableThreshold);
        final boolean isStickyAutoDisableEnabled = getGlobalSetting(
                Settings.Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED, 1) != 0;
        final int stickyAutoDisableThreshold = getGlobalSetting(
                Settings.Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL, 90);

        setSettingsLocked(lowPowerModeEnabled, lowPowerModeEnabledSticky,
                lowPowerModeTriggerLevel,
                isStickyAutoDisableEnabled, stickyAutoDisableThreshold,
                automaticBatterySaverMode,
                dynamicPowerSavingsBatterySaver, dynamicPowerSavingsDisableThreshold);
    }

    /**
     * {@link com.android.server.power.PowerManagerService} calls it when relevant global settings
     * have changed.
     *
     * Note this will be called before {@link #onBootCompleted} too.
     */
    @GuardedBy("mLock")
    @VisibleForTesting
    void setSettingsLocked(boolean batterySaverEnabled, boolean batterySaverEnabledSticky,
            int batterySaverTriggerThreshold,
            boolean isStickyAutoDisableEnabled, int stickyAutoDisableThreshold,
            int automaticBatterySaver,
            boolean dynamicPowerSavingsBatterySaver, int dynamicPowerSavingsDisableThreshold) {
        if (DEBUG) {
            Slog.d(TAG, "setSettings: enabled=" + batterySaverEnabled
                    + " sticky=" + batterySaverEnabledSticky
                    + " threshold=" + batterySaverTriggerThreshold
                    + " stickyAutoDisableEnabled=" + isStickyAutoDisableEnabled
                    + " stickyAutoDisableThreshold=" + stickyAutoDisableThreshold
                    + " automaticBatterySaver=" + automaticBatterySaver
                    + " dynamicPowerSavingsBatterySaver=" + dynamicPowerSavingsBatterySaver
                    + " dynamicPowerSavingsDisableThreshold="
                    + dynamicPowerSavingsDisableThreshold);
        }

        mSettingsLoaded = true;

        // Set sensible limits.
        stickyAutoDisableThreshold = Math.max(stickyAutoDisableThreshold,
                batterySaverTriggerThreshold);

        final boolean enabledChanged = mSettingBatterySaverEnabled != batterySaverEnabled;
        final boolean stickyChanged =
                mSettingBatterySaverEnabledSticky != batterySaverEnabledSticky;
        final boolean thresholdChanged
                = mSettingBatterySaverTriggerThreshold != batterySaverTriggerThreshold;
        final boolean stickyAutoDisableEnabledChanged =
                mSettingBatterySaverStickyAutoDisableEnabled != isStickyAutoDisableEnabled;
        final boolean stickyAutoDisableThresholdChanged =
                mSettingBatterySaverStickyAutoDisableThreshold != stickyAutoDisableThreshold;
        final boolean automaticModeChanged = mSettingAutomaticBatterySaver != automaticBatterySaver;
        final boolean dynamicPowerSavingsThresholdChanged =
                mDynamicPowerSavingsDisableThreshold != dynamicPowerSavingsDisableThreshold;
        final boolean dynamicPowerSavingsBatterySaverChanged =
                mDynamicPowerSavingsBatterySaver != dynamicPowerSavingsBatterySaver;

        if (!(enabledChanged || stickyChanged || thresholdChanged || automaticModeChanged
                || stickyAutoDisableEnabledChanged || stickyAutoDisableThresholdChanged
                || dynamicPowerSavingsThresholdChanged || dynamicPowerSavingsBatterySaverChanged)) {
            return;
        }

        mSettingBatterySaverEnabled = batterySaverEnabled;
        mSettingBatterySaverEnabledSticky = batterySaverEnabledSticky;
        mSettingBatterySaverTriggerThreshold = batterySaverTriggerThreshold;
        mSettingBatterySaverStickyAutoDisableEnabled = isStickyAutoDisableEnabled;
        mSettingBatterySaverStickyAutoDisableThreshold = stickyAutoDisableThreshold;
        mSettingAutomaticBatterySaver = automaticBatterySaver;
        mDynamicPowerSavingsDisableThreshold = dynamicPowerSavingsDisableThreshold;
        mDynamicPowerSavingsBatterySaver = dynamicPowerSavingsBatterySaver;

        if (thresholdChanged) {
            // To avoid spamming the event log, we throttle logging here.
            runOnBgThreadLazy(mThresholdChangeLogger, 2000);
        }

        if (!mSettingBatterySaverStickyAutoDisableEnabled) {
            hideStickyDisabledNotification();
        }

        if (enabledChanged) {
            final String reason = batterySaverEnabled
                    ? "Global.low_power changed to 1" : "Global.low_power changed to 0";
            enableBatterySaverLocked(/*enable=*/ batterySaverEnabled, /*manual=*/ true,
                    BatterySaverController.REASON_SETTING_CHANGED, reason);
        } else {
            doAutoBatterySaverLocked();
        }
    }

    private final Runnable mThresholdChangeLogger = () -> {
        EventLogTags.writeBatterySaverSetting(mSettingBatterySaverTriggerThreshold);
    };

    /**
     * {@link com.android.server.power.PowerManagerService} calls it when battery state changes.
     *
     * Note this may be called before {@link #onBootCompleted} too.
     */
    public void setBatteryStatus(boolean newPowered, int newLevel, boolean newBatteryLevelLow) {
        if (DEBUG) {
            Slog.d(TAG, "setBatteryStatus: powered=" + newPowered + " level=" + newLevel
                    + " low=" + newBatteryLevelLow);
        }
        synchronized (mLock) {
            mBatteryStatusSet = true;

            final boolean poweredChanged = mIsPowered != newPowered;
            final boolean levelChanged = mBatteryLevel != newLevel;
            final boolean lowChanged = mIsBatteryLevelLow != newBatteryLevelLow;

            if (!(poweredChanged || levelChanged || lowChanged)) {
                return;
            }

            mIsPowered = newPowered;
            mBatteryLevel = newLevel;
            mIsBatteryLevelLow = newBatteryLevelLow;

            doAutoBatterySaverLocked();
        }
    }

    /**
     * Enable or disable the current adaptive battery saver policy. This may not change what's in
     * effect if full battery saver is also enabled.
     */
    public boolean setAdaptiveBatterySaverEnabled(boolean enabled) {
        if (DEBUG) {
            Slog.d(TAG, "setAdaptiveBatterySaverEnabled: enabled=" + enabled);
        }
        synchronized (mLock) {
            mLastAdaptiveBatterySaverChangedExternallyElapsed = SystemClock.elapsedRealtime();
            return mBatterySaverController.setAdaptivePolicyEnabledLocked(
                    enabled, BatterySaverController.REASON_ADAPTIVE_DYNAMIC_POWER_SAVINGS_CHANGED);
        }
    }

    /**
     * Change the adaptive battery saver policy.
     */
    public boolean setAdaptiveBatterySaverPolicy(BatterySaverPolicyConfig config) {
        if (DEBUG) {
            Slog.d(TAG, "setAdaptiveBatterySaverPolicy: config=" + config);
        }

        synchronized (mLock) {
            mLastAdaptiveBatterySaverChangedExternallyElapsed = SystemClock.elapsedRealtime();
            return mBatterySaverController.setAdaptivePolicyLocked(config,
                    BatterySaverController.REASON_ADAPTIVE_DYNAMIC_POWER_SAVINGS_CHANGED);
        }
    }

    /**
     * Decide whether to auto-start / stop battery saver.
     */
    @GuardedBy("mLock")
    private void doAutoBatterySaverLocked() {
        if (DEBUG) {
            Slog.d(TAG, "doAutoBatterySaverLocked: mBootCompleted=" + mBootCompleted
                    + " mSettingsLoaded=" + mSettingsLoaded
                    + " mBatteryStatusSet=" + mBatteryStatusSet
                    + " mState=" + mState
                    + " mIsBatteryLevelLow=" + mIsBatteryLevelLow
                    + " mIsPowered=" + mIsPowered
                    + " mSettingAutomaticBatterySaver=" + mSettingAutomaticBatterySaver
                    + " mSettingBatterySaverEnabledSticky=" + mSettingBatterySaverEnabledSticky
                    + " mSettingBatterySaverStickyAutoDisableEnabled="
                    + mSettingBatterySaverStickyAutoDisableEnabled);
        }
        if (!(mBootCompleted && mSettingsLoaded && mBatteryStatusSet)) {
            return; // Not fully initialized yet.
        }

        updateStateLocked(false, false);

        // Adaptive control.
        if (SystemClock.elapsedRealtime() - mLastAdaptiveBatterySaverChangedExternallyElapsed
                > ADAPTIVE_CHANGE_TIMEOUT_MS) {
            mBatterySaverController.setAdaptivePolicyEnabledLocked(
                    false, BatterySaverController.REASON_TIMEOUT);
            mBatterySaverController.resetAdaptivePolicyLocked(
                    BatterySaverController.REASON_TIMEOUT);
        } else if (mIsPowered && mBatteryLevel >= ADAPTIVE_AUTO_DISABLE_BATTERY_LEVEL) {
            mBatterySaverController.setAdaptivePolicyEnabledLocked(false,
                    BatterySaverController.REASON_PLUGGED_IN);
        }
    }

    /**
     * Update the state machine based on the current settings and battery/charge status.
     *
     * @param manual Whether the change was made by the user.
     * @param enable Whether the user wants to turn battery saver on or off. Is only used if {@param
     *               manual} is true.
     */
    @GuardedBy("mLock")
    private void updateStateLocked(boolean manual, boolean enable) {
        if (!manual && !(mBootCompleted && mSettingsLoaded && mBatteryStatusSet)) {
            return; // Not fully initialized yet.
        }

        switch (mState) {
            case STATE_OFF: {
                if (!mIsPowered) {
                    if (manual) {
                        if (!enable) {
                            Slog.e(TAG, "Tried to disable BS when it's already OFF");
                            return;
                        }
                        enableBatterySaverLocked(/*enable*/ true, /*manual*/ true,
                                BatterySaverController.REASON_MANUAL_ON);
                        hideStickyDisabledNotification();
                        mState = STATE_MANUAL_ON;
                    } else if (isAutomaticModeActiveLocked() && isInAutomaticLowZoneLocked()) {
                        enableBatterySaverLocked(/*enable*/ true, /*manual*/ false,
                                BatterySaverController.REASON_PERCENTAGE_AUTOMATIC_ON);
                        hideStickyDisabledNotification();
                        mState = STATE_AUTOMATIC_ON;
                    } else if (isDynamicModeActiveLocked() && isInDynamicLowZoneLocked()) {
                        enableBatterySaverLocked(/*enable*/ true, /*manual*/ false,
                                BatterySaverController.REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_ON);
                        hideStickyDisabledNotification();
                        mState = STATE_AUTOMATIC_ON;
                    }
                }
                break;
            }

            case STATE_MANUAL_ON: {
                if (manual) {
                    if (enable) {
                        Slog.e(TAG, "Tried to enable BS when it's already MANUAL_ON");
                        return;
                    }
                    enableBatterySaverLocked(/*enable*/ false, /*manual*/ true,
                            BatterySaverController.REASON_MANUAL_OFF);
                    mState = STATE_OFF;
                } else if (mIsPowered) {
                    enableBatterySaverLocked(/*enable*/ false, /*manual*/ false,
                            BatterySaverController.REASON_PLUGGED_IN);
                    if (mSettingBatterySaverEnabledSticky
                            && !mBatterySaverStickyBehaviourDisabled) {
                        mState = STATE_PENDING_STICKY_ON;
                    } else {
                        mState = STATE_OFF;
                    }
                }
                break;
            }

            case STATE_AUTOMATIC_ON: {
                if (mIsPowered) {
                    enableBatterySaverLocked(/*enable*/ false, /*manual*/ false,
                            BatterySaverController.REASON_PLUGGED_IN);
                    mState = STATE_OFF;
                } else if (manual) {
                    if (enable) {
                        Slog.e(TAG, "Tried to enable BS when it's already AUTO_ON");
                        return;
                    }
                    enableBatterySaverLocked(/*enable*/ false, /*manual*/ true,
                            BatterySaverController.REASON_MANUAL_OFF);
                    // When battery saver is disabled manually (while battery saver is enabled)
                    // when the battery level is low, we "snooze" BS -- i.e. disable auto battery
                    // saver.
                    // We resume auto-BS once the battery level is not low, or the device is
                    // plugged in.
                    mState = STATE_OFF_AUTOMATIC_SNOOZED;
                } else if (isAutomaticModeActiveLocked() && !isInAutomaticLowZoneLocked()) {
                    enableBatterySaverLocked(/*enable*/ false, /*manual*/ false,
                            BatterySaverController.REASON_PERCENTAGE_AUTOMATIC_OFF);
                    mState = STATE_OFF;
                } else if (isDynamicModeActiveLocked() && !isInDynamicLowZoneLocked()) {
                    enableBatterySaverLocked(/*enable*/ false, /*manual*/ false,
                            BatterySaverController.REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_OFF);
                    mState = STATE_OFF;
                } else if (!isAutomaticModeActiveLocked() && !isDynamicModeActiveLocked()) {
                    enableBatterySaverLocked(/*enable*/ false, /*manual*/ false,
                            BatterySaverController.REASON_SETTING_CHANGED);
                    mState = STATE_OFF;
                }
                break;
            }

            case STATE_OFF_AUTOMATIC_SNOOZED: {
                if (manual) {
                    if (!enable) {
                        Slog.e(TAG, "Tried to disable BS when it's already AUTO_SNOOZED");
                        return;
                    }
                    enableBatterySaverLocked(/*enable*/ true, /*manual*/ true,
                            BatterySaverController.REASON_MANUAL_ON);
                    mState = STATE_MANUAL_ON;
                } else if (mIsPowered // Plugging in resets snooze.
                        || (isAutomaticModeActiveLocked() && !isInAutomaticLowZoneLocked())
                        || (isDynamicModeActiveLocked() && !isInDynamicLowZoneLocked())
                        || (!isAutomaticModeActiveLocked() && !isDynamicModeActiveLocked())) {
                    mState = STATE_OFF;
                }
                break;
            }

            case STATE_PENDING_STICKY_ON: {
                if (manual) {
                    // This shouldn't be possible. We'll only be in this state when the device is
                    // plugged in, so the user shouldn't be able to manually change state.
                    Slog.e(TAG, "Tried to manually change BS state from PENDING_STICKY_ON");
                    return;
                }
                final boolean shouldTurnOffSticky = mSettingBatterySaverStickyAutoDisableEnabled
                        && mBatteryLevel >= mSettingBatterySaverStickyAutoDisableThreshold;
                final boolean isStickyDisabled =
                        mBatterySaverStickyBehaviourDisabled || !mSettingBatterySaverEnabledSticky;
                if (isStickyDisabled || shouldTurnOffSticky) {
                    mState = STATE_OFF;
                    setStickyActive(false);
                    triggerStickyDisabledNotification();
                } else if (!mIsPowered) {
                    // Re-enable BS.
                    enableBatterySaverLocked(/*enable*/ true, /*manual*/ true,
                            BatterySaverController.REASON_STICKY_RESTORE);
                    mState = STATE_MANUAL_ON;
                }
                break;
            }

            default:
                Slog.wtf(TAG, "Unknown state: " + mState);
                break;
        }
    }

    @VisibleForTesting
    int getState() {
        synchronized (mLock) {
            return mState;
        }
    }

    /**
     * {@link com.android.server.power.PowerManagerService} calls it when
     * {@link android.os.PowerManager#setPowerSaveModeEnabled} is called.
     *
     * Note this could? be called before {@link #onBootCompleted} too.
     */
    public void setBatterySaverEnabledManually(boolean enabled) {
        if (DEBUG) {
            Slog.d(TAG, "setBatterySaverEnabledManually: enabled=" + enabled);
        }
        synchronized (mLock) {
            updateStateLocked(true, enabled);
            // TODO: maybe turn off adaptive if it's on and advertiseIsEnabled is true and
            //  enabled is false
        }
    }

    @GuardedBy("mLock")
    private void enableBatterySaverLocked(boolean enable, boolean manual, int intReason) {
        enableBatterySaverLocked(enable, manual, intReason, reasonToString(intReason));
    }

    /**
     * Actually enable / disable battery saver. Write the new state to the global settings
     * and propagate it to {@link #mBatterySaverController}.
     */
    @GuardedBy("mLock")
    private void enableBatterySaverLocked(boolean enable, boolean manual, int intReason,
            String strReason) {
        if (DEBUG) {
            Slog.d(TAG, "enableBatterySaver: enable=" + enable + " manual=" + manual
                    + " reason=" + strReason + "(" + intReason + ")");
        }
        final boolean wasEnabled = mBatterySaverController.isFullEnabled();

        if (wasEnabled == enable) {
            if (DEBUG) {
                Slog.d(TAG, "Already " + (enable ? "enabled" : "disabled"));
            }
            return;
        }
        if (enable && mIsPowered) {
            if (DEBUG) Slog.d(TAG, "Can't enable: isPowered");
            return;
        }
        mLastChangedIntReason = intReason;
        mLastChangedStrReason = strReason;

        mSettingBatterySaverEnabled = enable;
        putGlobalSetting(Settings.Global.LOW_POWER_MODE, enable ? 1 : 0);

        if (manual) {
            setStickyActive(!mBatterySaverStickyBehaviourDisabled && enable);
        }
        mBatterySaverController.enableBatterySaver(enable, intReason);

        // Handle triggering the notification to show/hide when appropriate
        if (intReason == BatterySaverController.REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_ON) {
            runOnBgThread(this::triggerDynamicModeNotification);
        } else if (!enable) {
            runOnBgThread(this::hideDynamicModeNotification);
        }

        if (DEBUG) {
            Slog.d(TAG, "Battery saver: Enabled=" + enable
                    + " manual=" + manual
                    + " reason=" + strReason + "(" + intReason + ")");
        }
    }

    @VisibleForTesting
    void triggerDynamicModeNotification() {
        NotificationManager manager = mContext.getSystemService(NotificationManager.class);
        ensureNotificationChannelExists(manager, DYNAMIC_MODE_NOTIF_CHANNEL_ID,
                R.string.dynamic_mode_notification_channel_name);

        manager.notifyAsUser(TAG, DYNAMIC_MODE_NOTIFICATION_ID,
                buildNotification(DYNAMIC_MODE_NOTIF_CHANNEL_ID,
                        mContext.getResources().getString(R.string.dynamic_mode_notification_title),
                        R.string.dynamic_mode_notification_summary,
                        Intent.ACTION_POWER_USAGE_SUMMARY),
                UserHandle.ALL);
    }

    @VisibleForTesting
    void triggerStickyDisabledNotification() {
        NotificationManager manager = mContext.getSystemService(NotificationManager.class);
        ensureNotificationChannelExists(manager, BATTERY_SAVER_NOTIF_CHANNEL_ID,
                R.string.battery_saver_notification_channel_name);

        final String percentage = NumberFormat.getPercentInstance()
                .format((double) mBatteryLevel / 100.0);
        manager.notifyAsUser(TAG, STICKY_AUTO_DISABLED_NOTIFICATION_ID,
                buildNotification(BATTERY_SAVER_NOTIF_CHANNEL_ID,
                        mContext.getResources().getString(
                                R.string.battery_saver_charged_notification_title, percentage),
                        R.string.battery_saver_off_notification_summary,
                        Settings.ACTION_BATTERY_SAVER_SETTINGS),
                UserHandle.ALL);
    }

    private void ensureNotificationChannelExists(NotificationManager manager,
            @NonNull String channelId, @StringRes int nameId) {
        NotificationChannel channel = new NotificationChannel(
                channelId, mContext.getText(nameId), NotificationManager.IMPORTANCE_DEFAULT);
        channel.setSound(null, null);
        channel.setBlockableSystem(true);
        manager.createNotificationChannel(channel);
    }

    private Notification buildNotification(@NonNull String channelId, @NonNull String title,
            @StringRes int summaryId, @NonNull String intentAction) {
        Resources res = mContext.getResources();
        Intent intent = new Intent(intentAction);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        PendingIntent batterySaverIntent = PendingIntent.getActivity(
                mContext, 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        final String summary = res.getString(summaryId);

        return new Notification.Builder(mContext, channelId)
                .setSmallIcon(R.drawable.ic_battery)
                .setContentTitle(title)
                .setContentText(summary)
                .setContentIntent(batterySaverIntent)
                .setStyle(new Notification.BigTextStyle().bigText(summary))
                .setOnlyAlertOnce(true)
                .setAutoCancel(true)
                .build();
    }

    private void hideDynamicModeNotification() {
        hideNotification(DYNAMIC_MODE_NOTIFICATION_ID);
    }

    private void hideStickyDisabledNotification() {
        hideNotification(STICKY_AUTO_DISABLED_NOTIFICATION_ID);
    }

    private void hideNotification(int notificationId) {
        NotificationManager manager = mContext.getSystemService(NotificationManager.class);
        manager.cancel(notificationId);
    }

    private void setStickyActive(boolean active) {
        mSettingBatterySaverEnabledSticky = active;
        putGlobalSetting(Settings.Global.LOW_POWER_MODE_STICKY,
                mSettingBatterySaverEnabledSticky ? 1 : 0);
    }

    @VisibleForTesting
    protected void putGlobalSetting(String key, int value) {
        Settings.Global.putInt(mContext.getContentResolver(), key, value);
    }

    @VisibleForTesting
    protected int getGlobalSetting(String key, int defValue) {
        return Settings.Global.getInt(mContext.getContentResolver(), key, defValue);
    }

    public void dump(PrintWriter pw) {
        synchronized (mLock) {
            pw.println();
            pw.println("Battery saver state machine:");

            pw.print("  Enabled=");
            pw.println(mBatterySaverController.isEnabled());
            pw.print("    full=");
            pw.println(mBatterySaverController.isFullEnabled());
            pw.print("    adaptive=");
            pw.print(mBatterySaverController.isAdaptiveEnabled());
            if (mBatterySaverController.isAdaptiveEnabled()) {
                pw.print(" (advertise=");
                pw.print(
                        mBatterySaverController.getBatterySaverPolicy().shouldAdvertiseIsEnabled());
                pw.print(")");
            }
            pw.println();
            pw.print("  mState=");
            pw.println(mState);

            pw.print("  mLastChangedIntReason=");
            pw.println(mLastChangedIntReason);
            pw.print("  mLastChangedStrReason=");
            pw.println(mLastChangedStrReason);

            pw.print("  mBootCompleted=");
            pw.println(mBootCompleted);
            pw.print("  mSettingsLoaded=");
            pw.println(mSettingsLoaded);
            pw.print("  mBatteryStatusSet=");
            pw.println(mBatteryStatusSet);

            pw.print("  mIsPowered=");
            pw.println(mIsPowered);
            pw.print("  mBatteryLevel=");
            pw.println(mBatteryLevel);
            pw.print("  mIsBatteryLevelLow=");
            pw.println(mIsBatteryLevelLow);

            pw.print("  mSettingBatterySaverEnabled=");
            pw.println(mSettingBatterySaverEnabled);
            pw.print("  mSettingBatterySaverEnabledSticky=");
            pw.println(mSettingBatterySaverEnabledSticky);
            pw.print("  mSettingBatterySaverStickyAutoDisableEnabled=");
            pw.println(mSettingBatterySaverStickyAutoDisableEnabled);
            pw.print("  mSettingBatterySaverStickyAutoDisableThreshold=");
            pw.println(mSettingBatterySaverStickyAutoDisableThreshold);
            pw.print("  mSettingBatterySaverTriggerThreshold=");
            pw.println(mSettingBatterySaverTriggerThreshold);
            pw.print("  mBatterySaverStickyBehaviourDisabled=");
            pw.println(mBatterySaverStickyBehaviourDisabled);

            pw.print("  mLastAdaptiveBatterySaverChangedExternallyElapsed=");
            pw.println(mLastAdaptiveBatterySaverChangedExternallyElapsed);
        }
    }

    public void dumpProto(ProtoOutputStream proto, long tag) {
        synchronized (mLock) {
            final long token = proto.start(tag);

            proto.write(BatterySaverStateMachineProto.ENABLED,
                    mBatterySaverController.isEnabled());
            proto.write(BatterySaverStateMachineProto.STATE, mState);
            proto.write(BatterySaverStateMachineProto.IS_FULL_ENABLED,
                    mBatterySaverController.isFullEnabled());
            proto.write(BatterySaverStateMachineProto.IS_ADAPTIVE_ENABLED,
                    mBatterySaverController.isAdaptiveEnabled());
            proto.write(BatterySaverStateMachineProto.SHOULD_ADVERTISE_IS_ENABLED,
                    mBatterySaverController.getBatterySaverPolicy().shouldAdvertiseIsEnabled());

            proto.write(BatterySaverStateMachineProto.BOOT_COMPLETED, mBootCompleted);
            proto.write(BatterySaverStateMachineProto.SETTINGS_LOADED, mSettingsLoaded);
            proto.write(BatterySaverStateMachineProto.BATTERY_STATUS_SET, mBatteryStatusSet);


            proto.write(BatterySaverStateMachineProto.IS_POWERED, mIsPowered);
            proto.write(BatterySaverStateMachineProto.BATTERY_LEVEL, mBatteryLevel);
            proto.write(BatterySaverStateMachineProto.IS_BATTERY_LEVEL_LOW, mIsBatteryLevelLow);

            proto.write(BatterySaverStateMachineProto.SETTING_BATTERY_SAVER_ENABLED,
                    mSettingBatterySaverEnabled);
            proto.write(BatterySaverStateMachineProto.SETTING_BATTERY_SAVER_ENABLED_STICKY,
                    mSettingBatterySaverEnabledSticky);
            proto.write(BatterySaverStateMachineProto.SETTING_BATTERY_SAVER_TRIGGER_THRESHOLD,
                    mSettingBatterySaverTriggerThreshold);
            proto.write(
                    BatterySaverStateMachineProto.SETTING_BATTERY_SAVER_STICKY_AUTO_DISABLE_ENABLED,
                    mSettingBatterySaverStickyAutoDisableEnabled);
            proto.write(
                    BatterySaverStateMachineProto
                            .SETTING_BATTERY_SAVER_STICKY_AUTO_DISABLE_THRESHOLD,
                    mSettingBatterySaverStickyAutoDisableThreshold);

            proto.write(
                    BatterySaverStateMachineProto
                            .LAST_ADAPTIVE_BATTERY_SAVER_CHANGED_EXTERNALLY_ELAPSED,
                    mLastAdaptiveBatterySaverChangedExternallyElapsed);

            proto.end(token);
        }
    }
}
