content: /*
   * Copyright (C) 2019 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 android.os;
  
  import android.annotation.NonNull;
  import android.annotation.SystemApi;
  import android.text.TextUtils;
  import android.util.ArrayMap;
  
  import java.util.Collections;
  import java.util.Map;
  import java.util.Set;
  
  /**
   * Config to set Battery Saver policy flags.
   *
   * @hide
   */
  @SystemApi
  public final class BatterySaverPolicyConfig implements Parcelable {
      private final float mAdjustBrightnessFactor;
      private final boolean mAdvertiseIsEnabled;
      private final boolean mDeferFullBackup;
      private final boolean mDeferKeyValueBackup;
      @NonNull
      private final Map<String, String> mDeviceSpecificSettings;
      private final boolean mDisableAnimation;
      private final boolean mDisableAod;
      private final boolean mDisableLaunchBoost;
      private final boolean mDisableOptionalSensors;
      private final boolean mDisableSoundTrigger;
      private final boolean mDisableVibration;
      private final boolean mEnableAdjustBrightness;
      private final boolean mEnableDataSaver;
      private final boolean mEnableFirewall;
      private final boolean mEnableNightMode;
      private final boolean mEnableQuickDoze;
      private final boolean mForceAllAppsStandby;
      private final boolean mForceBackgroundCheck;
      private final int mLocationMode;
  
      private BatterySaverPolicyConfig(Builder in) {
          mAdjustBrightnessFactor = Math.max(0, Math.min(in.mAdjustBrightnessFactor, 1f));
          mAdvertiseIsEnabled = in.mAdvertiseIsEnabled;
          mDeferFullBackup = in.mDeferFullBackup;
          mDeferKeyValueBackup = in.mDeferKeyValueBackup;
          mDeviceSpecificSettings = Collections.unmodifiableMap(
                  new ArrayMap<>(in.mDeviceSpecificSettings));
          mDisableAnimation = in.mDisableAnimation;
          mDisableAod = in.mDisableAod;
          mDisableLaunchBoost = in.mDisableLaunchBoost;
          mDisableOptionalSensors = in.mDisableOptionalSensors;
          mDisableSoundTrigger = in.mDisableSoundTrigger;
          mDisableVibration = in.mDisableVibration;
          mEnableAdjustBrightness = in.mEnableAdjustBrightness;
          mEnableDataSaver = in.mEnableDataSaver;
          mEnableFirewall = in.mEnableFirewall;
          mEnableNightMode = in.mEnableNightMode;
          mEnableQuickDoze = in.mEnableQuickDoze;
          mForceAllAppsStandby = in.mForceAllAppsStandby;
          mForceBackgroundCheck = in.mForceBackgroundCheck;
          mLocationMode = Math.max(PowerManager.MIN_LOCATION_MODE,
                  Math.min(in.mLocationMode, PowerManager.MAX_LOCATION_MODE));
      }
  
      private BatterySaverPolicyConfig(Parcel in) {
          mAdjustBrightnessFactor = Math.max(0, Math.min(in.readFloat(), 1f));
          mAdvertiseIsEnabled = in.readBoolean();
          mDeferFullBackup = in.readBoolean();
          mDeferKeyValueBackup = in.readBoolean();
  
          final int size = in.readInt();
          Map<String, String> deviceSpecificSettings = new ArrayMap<>(size);
          for (int i = 0; i < size; ++i) {
              String key = TextUtils.emptyIfNull(in.readString());
              String val = TextUtils.emptyIfNull(in.readString());
              if (key.trim().isEmpty()) {
                  continue;
              }
              deviceSpecificSettings.put(key, val);
          }
          mDeviceSpecificSettings = Collections.unmodifiableMap(deviceSpecificSettings);
  
          mDisableAnimation = in.readBoolean();
          mDisableAod = in.readBoolean();
          mDisableLaunchBoost = in.readBoolean();
          mDisableOptionalSensors = in.readBoolean();
          mDisableSoundTrigger = in.readBoolean();
          mDisableVibration = in.readBoolean();
          mEnableAdjustBrightness = in.readBoolean();
          mEnableDataSaver = in.readBoolean();
          mEnableFirewall = in.readBoolean();
          mEnableNightMode = in.readBoolean();
          mEnableQuickDoze = in.readBoolean();
          mForceAllAppsStandby = in.readBoolean();
          mForceBackgroundCheck = in.readBoolean();
          mLocationMode = Math.max(PowerManager.MIN_LOCATION_MODE,
                  Math.min(in.readInt(), PowerManager.MAX_LOCATION_MODE));
      }
  
      public static final @android.annotation.NonNull Creator<BatterySaverPolicyConfig> CREATOR =
              new Creator<BatterySaverPolicyConfig>() {
                  @Override
                  public BatterySaverPolicyConfig createFromParcel(Parcel in) {
                      return new BatterySaverPolicyConfig(in);
                  }
  
                  @Override
                  public BatterySaverPolicyConfig[] newArray(int size) {
                      return new BatterySaverPolicyConfig[size];
                  }
              };
  
      @Override
      public int describeContents() {
          return 0;
      }
  
      @Override
      public void writeToParcel(Parcel dest, int flags) {
          dest.writeFloat(mAdjustBrightnessFactor);
          dest.writeBoolean(mAdvertiseIsEnabled);
          dest.writeBoolean(mDeferFullBackup);
          dest.writeBoolean(mDeferKeyValueBackup);
  
          final Set<Map.Entry<String, String>> entries = mDeviceSpecificSettings.entrySet();
          final int size = entries.size();
          dest.writeInt(size);
          for (Map.Entry<String, String> entry : entries) {
              dest.writeString(entry.getKey());
              dest.writeString(entry.getValue());
          }
  
          dest.writeBoolean(mDisableAnimation);
          dest.writeBoolean(mDisableAod);
          dest.writeBoolean(mDisableLaunchBoost);
          dest.writeBoolean(mDisableOptionalSensors);
          dest.writeBoolean(mDisableSoundTrigger);
          dest.writeBoolean(mDisableVibration);
          dest.writeBoolean(mEnableAdjustBrightness);
          dest.writeBoolean(mEnableDataSaver);
          dest.writeBoolean(mEnableFirewall);
          dest.writeBoolean(mEnableNightMode);
          dest.writeBoolean(mEnableQuickDoze);
          dest.writeBoolean(mForceAllAppsStandby);
          dest.writeBoolean(mForceBackgroundCheck);
          dest.writeInt(mLocationMode);
      }
  
      @Override
      public String toString() {
          StringBuilder sb = new StringBuilder();
          for (Map.Entry<String, String> entry : mDeviceSpecificSettings.entrySet()) {
              sb.append(entry.getKey()).append("=").append(entry.getValue()).append(",");
          }
          return "adjust_brightness_disabled=" + !mEnableAdjustBrightness + ","
                  + "adjust_brightness_factor=" + mAdjustBrightnessFactor + ","
                  + "advertise_is_enabled=" + mAdvertiseIsEnabled + ","
                  + "animation_disabled=" + mDisableAnimation + ","
                  + "aod_disabled=" + mDisableAod + ","
                  + "datasaver_disabled=" + !mEnableDataSaver + ","
                  + "enable_night_mode=" + mEnableNightMode + ","
                  + "firewall_disabled=" + !mEnableFirewall + ","
                  + "force_all_apps_standby=" + mForceAllAppsStandby + ","
                  + "force_background_check=" + mForceBackgroundCheck + ","
                  + "fullbackup_deferred=" + mDeferFullBackup + ","
                  + "gps_mode=" + mLocationMode + ","
                  + "keyvaluebackup_deferred=" + mDeferKeyValueBackup + ","
                  + "launch_boost_disabled=" + mDisableLaunchBoost + ","
                  + "optional_sensors_disabled=" + mDisableOptionalSensors + ","
                  + "quick_doze_enabled=" + mEnableQuickDoze + ","
                  + "soundtrigger_disabled=" + mDisableSoundTrigger + ","
                  + "vibration_disabled=" + mDisableVibration + ","
                  + sb.toString();
      }
  
      /**
       * How much to adjust the screen brightness while in Battery Saver. This will have no effect
       * if {@link #getEnableAdjustBrightness()} is {@code false}.
       */
      public float getAdjustBrightnessFactor() {
          return mAdjustBrightnessFactor;
      }
  
      /**
       * Whether or not to tell the system (and other apps) that Battery Saver is currently enabled.
       */
      public boolean getAdvertiseIsEnabled() {
          return mAdvertiseIsEnabled;
      }
  
      /** Whether or not to defer full backup while in Battery Saver. */
      public boolean getDeferFullBackup() {
          return mDeferFullBackup;
      }
  
      /** Whether or not to defer key-value backup while in Battery Saver. */
      public boolean getDeferKeyValueBackup() {
          return mDeferKeyValueBackup;
      }
  
      /**
       * Returns the device-specific battery saver constants.
       */
      @NonNull
      public Map<String, String> getDeviceSpecificSettings() {
          return mDeviceSpecificSettings;
      }
  
      /** Whether or not to disable animation while in Battery Saver. */
      public boolean getDisableAnimation() {
          return mDisableAnimation;
      }
  
      /** Whether or not to disable Always On Display while in Battery Saver. */
      public boolean getDisableAod() {
          return mDisableAod;
      }
  
      /** Whether or not to disable launch boost while in Battery Saver. */
      public boolean getDisableLaunchBoost() {
          return mDisableLaunchBoost;
      }
  
      /** Whether or not to disable optional sensors while in Battery Saver. */
      public boolean getDisableOptionalSensors() {
          return mDisableOptionalSensors;
      }
  
      /**
       * Whether or not to disable {@link android.hardware.soundtrigger.SoundTrigger}
       * while in Battery Saver.
       */
      public boolean getDisableSoundTrigger() {
          return mDisableSoundTrigger;
      }
  
      /** Whether or not to disable vibration while in Battery Saver. */
      public boolean getDisableVibration() {
          return mDisableVibration;
      }
  
      /** Whether or not to enable brightness adjustment while in Battery Saver. */
      public boolean getEnableAdjustBrightness() {
          return mEnableAdjustBrightness;
      }
  
      /** Whether or not to enable Data Saver while in Battery Saver. */
      public boolean getEnableDataSaver() {
          return mEnableDataSaver;
      }
  
      /**
       * Whether or not to enable network firewall rules to restrict background network use
       * while in Battery Saver.
       */
      public boolean getEnableFirewall() {
          return mEnableFirewall;
      }
  
      /** Whether or not to enable night mode while in Battery Saver. */
      public boolean getEnableNightMode() {
          return mEnableNightMode;
      }
  
      /** Whether or not to enable Quick Doze while in Battery Saver. */
      public boolean getEnableQuickDoze() {
          return mEnableQuickDoze;
      }
  
      /** Whether or not to force all apps to standby mode while in Battery Saver. */
      public boolean getForceAllAppsStandby() {
          return mForceAllAppsStandby;
      }
  
      /**
       * Whether or not to force background check (disallow background services and manifest
       * broadcast receivers) on all apps (not just apps targeting Android
       * {@link Build.VERSION_CODES#O} and above)
       * while in Battery Saver.
       */
      public boolean getForceBackgroundCheck() {
          return mForceBackgroundCheck;
      }
  
      /** The location mode while in Battery Saver. */
      public int getLocationMode() {
          return mLocationMode;
      }
  
      /** Builder class for constructing {@link BatterySaverPolicyConfig} objects. */
      public static final class Builder {
          private float mAdjustBrightnessFactor = 1f;
          private boolean mAdvertiseIsEnabled = false;
          private boolean mDeferFullBackup = false;
          private boolean mDeferKeyValueBackup = false;
          @NonNull
          private final ArrayMap<String, String> mDeviceSpecificSettings = new ArrayMap<>();
          private boolean mDisableAnimation = false;
          private boolean mDisableAod = false;
          private boolean mDisableLaunchBoost = false;
          private boolean mDisableOptionalSensors = false;
          private boolean mDisableSoundTrigger = false;
          private boolean mDisableVibration = false;
          private boolean mEnableAdjustBrightness = false;
          private boolean mEnableDataSaver = false;
          private boolean mEnableFirewall = false;
          private boolean mEnableNightMode = false;
          private boolean mEnableQuickDoze = false;
          private boolean mForceAllAppsStandby = false;
          private boolean mForceBackgroundCheck = false;
          private int mLocationMode = PowerManager.LOCATION_MODE_NO_CHANGE;
  
          public Builder() {
          }
  
          /**
           * Set how much to adjust the screen brightness while in Battery Saver. The value should
           * be in the [0, 1] range, where 1 will not change the brightness. This will have no
           * effect if {@link #setEnableAdjustBrightness(boolean)} is not called with {@code true}.
           */
          @NonNull
          public Builder setAdjustBrightnessFactor(float adjustBrightnessFactor) {
              mAdjustBrightnessFactor = adjustBrightnessFactor;
              return this;
          }
  
          /**
           * Set whether or not to tell the system (and other apps) that Battery Saver is
           * currently enabled.
           */
          @NonNull
          public Builder setAdvertiseIsEnabled(boolean advertiseIsEnabled) {
              mAdvertiseIsEnabled = advertiseIsEnabled;
              return this;
          }
  
          /** Set whether or not to defer full backup while in Battery Saver. */
          @NonNull
          public Builder setDeferFullBackup(boolean deferFullBackup) {
              mDeferFullBackup = deferFullBackup;
              return this;
          }
  
          /** Set whether or not to defer key-value backup while in Battery Saver. */
          @NonNull
          public Builder setDeferKeyValueBackup(boolean deferKeyValueBackup) {
              mDeferKeyValueBackup = deferKeyValueBackup;
              return this;
          }
  
          /**
           * Adds a key-value pair for device-specific battery saver constants. The supported keys
           * and values are the same as those in
           * {@link android.provider.Settings.Global#BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS}.
           *
           * @throws IllegalArgumentException if the provided key is invalid (empty, null, or all
           * whitespace)
           */
          @NonNull
          public Builder addDeviceSpecificSetting(@NonNull String key, @NonNull String value) {
              if (key == null) {
                  throw new IllegalArgumentException("Key cannot be null");
              }
              key = key.trim();
              if (TextUtils.isEmpty(key)) {
                  throw new IllegalArgumentException("Key cannot be empty");
              }
              mDeviceSpecificSettings.put(key, TextUtils.emptyIfNull(value));
              return this;
          }
  
          /** Set whether or not to disable animation while in Battery Saver. */
          @NonNull
          public Builder setDisableAnimation(boolean disableAnimation) {
              mDisableAnimation = disableAnimation;
              return this;
          }
  
          /** Set whether or not to disable Always On Display while in Battery Saver. */
          @NonNull
          public Builder setDisableAod(boolean disableAod) {
              mDisableAod = disableAod;
              return this;
          }
  
          /** Set whether or not to disable launch boost while in Battery Saver. */
          @NonNull
          public Builder setDisableLaunchBoost(boolean disableLaunchBoost) {
              mDisableLaunchBoost = disableLaunchBoost;
              return this;
          }
  
          /** Set whether or not to disable optional sensors while in Battery Saver. */
          @NonNull
          public Builder setDisableOptionalSensors(boolean disableOptionalSensors) {
              mDisableOptionalSensors = disableOptionalSensors;
              return this;
          }
  
          /**
           * Set whether or not to disable  {@link android.hardware.soundtrigger.SoundTrigger}
           * while in Battery Saver.
           */
          @NonNull
          public Builder setDisableSoundTrigger(boolean disableSoundTrigger) {
              mDisableSoundTrigger = disableSoundTrigger;
              return this;
          }
  
          /** Set whether or not to disable vibration while in Battery Saver. */
          @NonNull
          public Builder setDisableVibration(boolean disableVibration) {
              mDisableVibration = disableVibration;
              return this;
          }
  
          /** Set whether or not to enable brightness adjustment while in Battery Saver. */
          @NonNull
          public Builder setEnableAdjustBrightness(boolean enableAdjustBrightness) {
              mEnableAdjustBrightness = enableAdjustBrightness;
              return this;
          }
  
          /** Set whether or not to enable Data Saver while in Battery Saver. */
          @NonNull
          public Builder setEnableDataSaver(boolean enableDataSaver) {
              mEnableDataSaver = enableDataSaver;
              return this;
          }
  
          /**
           * Set whether or not to enable network firewall rules to restrict background network use
           * while in Battery Saver.
           */
          @NonNull
          public Builder setEnableFirewall(boolean enableFirewall) {
              mEnableFirewall = enableFirewall;
              return this;
          }
  
          /** Set whether or not to enable night mode while in Battery Saver. */
          @NonNull
          public Builder setEnableNightMode(boolean enableNightMode) {
              mEnableNightMode = enableNightMode;
              return this;
          }
  
          /** Set whether or not to enable Quick Doze while in Battery Saver. */
          @NonNull
          public Builder setEnableQuickDoze(boolean enableQuickDoze) {
              mEnableQuickDoze = enableQuickDoze;
              return this;
          }
  
          /** Set whether or not to force all apps to standby mode while in Battery Saver. */
          @NonNull
          public Builder setForceAllAppsStandby(boolean forceAllAppsStandby) {
              mForceAllAppsStandby = forceAllAppsStandby;
              return this;
          }
  
          /**
           * Set whether or not to force background check (disallow background services and manifest
           * broadcast receivers) on all apps (not just apps targeting Android
           * {@link Build.VERSION_CODES#O} and above)
           * while in Battery Saver.
           */
          @NonNull
          public Builder setForceBackgroundCheck(boolean forceBackgroundCheck) {
              mForceBackgroundCheck = forceBackgroundCheck;
              return this;
          }
  
          /** Set the location mode while in Battery Saver. */
          @NonNull
          public Builder setLocationMode(@PowerManager.LocationPowerSaveMode int locationMode) {
              mLocationMode = locationMode;
              return this;
          }
  
          /**
           * Build a {@link BatterySaverPolicyConfig} object using the set parameters. This object
           * is immutable.
           */
          @NonNull
          public BatterySaverPolicyConfig build() {
              return new BatterySaverPolicyConfig(this);
          }
      }
  }
  