1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.server.power.batterysaver;
17 
18 import android.annotation.IntDef;
19 import android.app.UiModeManager;
20 import android.content.ContentResolver;
21 import android.content.Context;
22 import android.content.res.Resources;
23 import android.database.ContentObserver;
24 import android.net.Uri;
25 import android.os.BatterySaverPolicyConfig;
26 import android.os.Handler;
27 import android.os.PowerManager;
28 import android.os.PowerManager.ServiceType;
29 import android.os.PowerSaveState;
30 import android.provider.DeviceConfig;
31 import android.provider.Settings;
32 import android.text.TextUtils;
33 import android.util.ArrayMap;
34 import android.util.IndentingPrintWriter;
35 import android.util.Slog;
36 import android.view.accessibility.AccessibilityManager;
37 
38 import com.android.internal.R;
39 import com.android.internal.annotations.GuardedBy;
40 import com.android.internal.annotations.VisibleForTesting;
41 import com.android.internal.os.BackgroundThread;
42 import com.android.internal.util.ConcurrentUtils;
43 import com.android.server.utils.UserSettingDeviceConfigMediator;
44 
45 import java.io.PrintWriter;
46 import java.lang.annotation.Retention;
47 import java.lang.annotation.RetentionPolicy;
48 import java.util.ArrayList;
49 import java.util.List;
50 import java.util.Map;
51 import java.util.Objects;
52 import java.util.Set;
53 
54 /**
55  * Class to decide whether to turn on battery saver mode for specific services.
56  *
57  * IMPORTANT: This class shares the power manager lock, which is very low in the lock hierarchy.
58  * Do not call out with the lock held, such as AccessibilityManager. (Settings provider is okay.)
59  *
60  * Test: atest com.android.server.power.batterysaver.BatterySaverPolicyTest
61  */
62 public class BatterySaverPolicy extends ContentObserver implements
63         DeviceConfig.OnPropertiesChangedListener {
64     private static final String TAG = "BatterySaverPolicy";
65 
66     static final boolean DEBUG = false; // DO NOT SUBMIT WITH TRUE.
67 
68     @VisibleForTesting
69     static final String KEY_LOCATION_MODE = "location_mode";
70     @VisibleForTesting
71     static final String KEY_DISABLE_VIBRATION = "disable_vibration";
72     @VisibleForTesting
73     static final String KEY_DISABLE_ANIMATION = "disable_animation";
74     @VisibleForTesting
75     static final String KEY_SOUNDTRIGGER_MODE = "soundtrigger_mode";
76 
77     /**
78      * Turn on the network firewall when Battery Saver is turned on.
79      * If set to false, the firewall WILL NOT be turned on when Battery Saver is turned on.
80      * If set to true, the firewall WILL be turned on when Battery Saver is turned on.
81      */
82     @VisibleForTesting
83     static final String KEY_ENABLE_FIREWALL = "enable_firewall";
84 
85     /**
86      * Turn on the special low power screen brightness dimming when Battery Saver is
87      * turned on.
88      * If set to false, the screen brightness dimming WILL NOT be turned on by Battery Saver.
89      * If set to true, the screen brightness WILL be turned on by Battery Saver.
90      */
91     @VisibleForTesting
92     static final String KEY_ENABLE_BRIGHTNESS_ADJUSTMENT = "enable_brightness_adjustment";
93 
94     /**
95      * Turn on Data Saver when Battery Saver is turned on.
96      * If set to false, Data Saver WILL NOT be turned on when Battery Saver is turned on.
97      * If set to true, Data Saver WILL be turned on when Battery Saver is turned on.
98      */
99     @VisibleForTesting
100     static final String KEY_ENABLE_DATASAVER = "enable_datasaver";
101 
102     /**
103      * {@code true} if the Policy should advertise to the rest of the system that battery saver
104      * is enabled. This advertising could cause other system components to change their
105      * behavior. This will not affect other policy flags and what they change.
106      */
107     @VisibleForTesting
108     static final String KEY_ADVERTISE_IS_ENABLED = "advertise_is_enabled";
109 
110     @VisibleForTesting
111     static final String KEY_DISABLE_LAUNCH_BOOST = "disable_launch_boost";
112     @VisibleForTesting
113     static final String KEY_ADJUST_BRIGHTNESS_FACTOR = "adjust_brightness_factor";
114     @VisibleForTesting
115     static final String KEY_DEFER_FULL_BACKUP = "defer_full_backup";
116     @VisibleForTesting
117     static final String KEY_DEFER_KEYVALUE_BACKUP = "defer_keyvalue_backup";
118     @VisibleForTesting
119     static final String KEY_FORCE_ALL_APPS_STANDBY = "force_all_apps_standby";
120     @VisibleForTesting
121     static final String KEY_FORCE_BACKGROUND_CHECK = "force_background_check";
122     @VisibleForTesting
123     static final String KEY_DISABLE_OPTIONAL_SENSORS = "disable_optional_sensors";
124     @VisibleForTesting
125     static final String KEY_DISABLE_AOD = "disable_aod";
126     // Go into deep Doze as soon as the screen turns off.
127     @VisibleForTesting
128     static final String KEY_ENABLE_QUICK_DOZE = "enable_quick_doze";
129     @VisibleForTesting
130     static final String KEY_ENABLE_NIGHT_MODE = "enable_night_mode";
131 
132     /** @deprecated Old key used to set CPU frequency caps directly in sys files. */
133     @Deprecated
134     private static final String KEY_CPU_FREQ_INTERACTIVE = "cpufreq-i";
135     /** @deprecated Old key used to set CPU frequency caps directly in sys files. */
136     @Deprecated
137     private static final String KEY_CPU_FREQ_NONINTERACTIVE = "cpufreq-n";
138 
139     private static final String KEY_SUFFIX_ADAPTIVE = "_adaptive";
140 
141     @VisibleForTesting
142     static final Policy OFF_POLICY = new Policy(
143             1f,    /* adjustBrightnessFactor */
144             false, /* advertiseIsEnabled */
145             false, /* deferFullBackup */
146             false, /* deferKeyValueBackup */
147             false, /* disableAnimation */
148             false, /* disableAod */
149             false, /* disableLaunchBoost */
150             false, /* disableOptionalSensors */
151             false, /* disableVibration */
152             false, /* enableAdjustBrightness */
153             false, /* enableDataSaver */
154             false, /* enableFireWall */
155             false, /* enableNightMode */
156             false, /* enableQuickDoze */
157             false, /* forceAllAppsStandby */
158             false, /* forceBackgroundCheck */
159             PowerManager.LOCATION_MODE_NO_CHANGE, /* locationMode */
160             PowerManager.SOUND_TRIGGER_MODE_ALL_ENABLED /* soundTriggerMode */
161     );
162 
163     private static final Policy DEFAULT_ADAPTIVE_POLICY = OFF_POLICY;
164 
165     /** The base default full policy for the device. */
166     private final Policy DEFAULT_FULL_POLICY;
167 
168     private final Object mLock;
169     private final Handler mHandler;
170 
171     @GuardedBy("mLock")
172     private String mSettings;
173 
174     @GuardedBy("mLock")
175     private String mDeviceSpecificSettings;
176 
177     @GuardedBy("mLock")
178     private String mDeviceSpecificSettingsSource; // For dump() only.
179 
180     @GuardedBy("mLock")
181     private DeviceConfig.Properties mLastDeviceConfigProperties;
182 
183     /**
184      * A short string describing which battery saver is now enabled, which we dump in the eventlog.
185      */
186     @GuardedBy("mLock")
187     private String mEventLogKeys;
188 
189     /**
190      * Whether accessibility is currently enabled or not.
191      */
192     @VisibleForTesting
193     final PolicyBoolean mAccessibilityEnabled = new PolicyBoolean("accessibility");
194 
195     /** Whether the phone has set automotive projection or not. */
196     @VisibleForTesting
197     final PolicyBoolean mAutomotiveProjectionActive = new PolicyBoolean("automotiveProjection");
198 
199     /** The current default adaptive policy. */
200     @GuardedBy("mLock")
201     private Policy mDefaultAdaptivePolicy = DEFAULT_ADAPTIVE_POLICY;
202 
203     /** The policy that will be used for adaptive battery saver. */
204     @GuardedBy("mLock")
205     private Policy mAdaptivePolicy = DEFAULT_ADAPTIVE_POLICY;
206 
207     /** The current default full policy. This may be modified by Settings or DeviceConfig flags. */
208     @GuardedBy("mLock")
209     private Policy mDefaultFullPolicy;
210 
211     /** The policy to be used for full battery saver. */
212     @GuardedBy("mLock")
213     private Policy mFullPolicy;
214 
215     /**
216      * The current effective policy. This is based on the current policy level's policy, with any
217      * required adjustments.
218      */
219     @GuardedBy("mLock")
220     private Policy mEffectivePolicyRaw = OFF_POLICY;
221 
222     @IntDef(prefix = {"POLICY_LEVEL_"}, value = {
223             POLICY_LEVEL_OFF,
224             POLICY_LEVEL_ADAPTIVE,
225             POLICY_LEVEL_FULL,
226     })
227     @Retention(RetentionPolicy.SOURCE)
228     @interface PolicyLevel {}
229 
230     static final int POLICY_LEVEL_OFF = 0;
231     static final int POLICY_LEVEL_ADAPTIVE = 1;
232     static final int POLICY_LEVEL_FULL = 2;
233 
234     @GuardedBy("mLock")
235     private int mPolicyLevel = POLICY_LEVEL_OFF;
236 
237     private final Context mContext;
238     private final ContentResolver mContentResolver;
239     private final BatterySavingStats mBatterySavingStats;
240 
241     private final UiModeManager.OnProjectionStateChangedListener mOnProjectionStateChangedListener =
242             (t, pkgs) -> mAutomotiveProjectionActive.update(!pkgs.isEmpty());
243 
244     @GuardedBy("mLock")
245     private final List<BatterySaverPolicyListener> mListeners = new ArrayList<>();
246 
247     public interface BatterySaverPolicyListener {
onBatterySaverPolicyChanged(BatterySaverPolicy policy)248         void onBatterySaverPolicyChanged(BatterySaverPolicy policy);
249     }
250 
BatterySaverPolicy(Object lock, Context context, BatterySavingStats batterySavingStats)251     public BatterySaverPolicy(Object lock, Context context, BatterySavingStats batterySavingStats) {
252         super(BackgroundThread.getHandler());
253         mLock = lock;
254         mHandler = BackgroundThread.getHandler();
255         mContext = context;
256         mContentResolver = context.getContentResolver();
257         mBatterySavingStats = batterySavingStats;
258 
259         final Resources res = context.getResources();
260         DEFAULT_FULL_POLICY = new Policy(
261                 res.getFloat(R.dimen.config_batterySaver_full_adjustBrightnessFactor),
262                 true,  /* advertiseIsEnabled */
263                 res.getBoolean(R.bool.config_batterySaver_full_deferFullBackup),
264                 res.getBoolean(R.bool.config_batterySaver_full_deferKeyValueBackup),
265                 res.getBoolean(R.bool.config_batterySaver_full_disableAnimation),
266                 res.getBoolean(R.bool.config_batterySaver_full_disableAod),
267                 res.getBoolean(R.bool.config_batterySaver_full_disableLaunchBoost),
268                 res.getBoolean(R.bool.config_batterySaver_full_disableOptionalSensors),
269                 res.getBoolean(R.bool.config_batterySaver_full_disableVibration),
270                 res.getBoolean(R.bool.config_batterySaver_full_enableAdjustBrightness),
271                 res.getBoolean(R.bool.config_batterySaver_full_enableDataSaver),
272                 res.getBoolean(R.bool.config_batterySaver_full_enableFirewall),
273                 res.getBoolean(R.bool.config_batterySaver_full_enableNightMode),
274                 res.getBoolean(R.bool.config_batterySaver_full_enableQuickDoze),
275                 res.getBoolean(R.bool.config_batterySaver_full_forceAllAppsStandby),
276                 res.getBoolean(R.bool.config_batterySaver_full_forceBackgroundCheck),
277                 res.getInteger(R.integer.config_batterySaver_full_locationMode),
278                 res.getInteger(R.integer.config_batterySaver_full_soundTriggerMode)
279         );
280         mDefaultFullPolicy = DEFAULT_FULL_POLICY;
281         mFullPolicy = DEFAULT_FULL_POLICY;
282     }
283 
284     /**
285      * Called by {@link BatterySaverStateMachine#systemReady()}, *with no lock held.*
286      */
systemReady()287     public void systemReady() {
288         ConcurrentUtils.wtfIfLockHeld(TAG, mLock);
289 
290         mContentResolver.registerContentObserver(Settings.Global.getUriFor(
291                 Settings.Global.BATTERY_SAVER_CONSTANTS), false, this);
292         mContentResolver.registerContentObserver(Settings.Global.getUriFor(
293                 Settings.Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS), false, this);
294 
295         final AccessibilityManager acm = mContext.getSystemService(AccessibilityManager.class);
296 
297         acm.addAccessibilityStateChangeListener(enabled -> mAccessibilityEnabled.update(enabled));
298         mAccessibilityEnabled.initialize(acm.isEnabled());
299 
300         UiModeManager uiModeManager = mContext.getSystemService(UiModeManager.class);
301         uiModeManager.addOnProjectionStateChangedListener(UiModeManager.PROJECTION_TYPE_AUTOMOTIVE,
302                 mContext.getMainExecutor(), mOnProjectionStateChangedListener);
303         mAutomotiveProjectionActive.initialize(
304                 uiModeManager.getActiveProjectionTypes() != UiModeManager.PROJECTION_TYPE_NONE);
305 
306         DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_BATTERY_SAVER,
307                 mContext.getMainExecutor(), this);
308         mLastDeviceConfigProperties =
309                 DeviceConfig.getProperties(DeviceConfig.NAMESPACE_BATTERY_SAVER);
310         onChange(true, null);
311     }
312 
313     @VisibleForTesting
addListener(BatterySaverPolicyListener listener)314     public void addListener(BatterySaverPolicyListener listener) {
315         synchronized (mLock) {
316             // TODO: set this in the constructor instead
317             mListeners.add(listener);
318         }
319     }
320 
321     @VisibleForTesting
getGlobalSetting(String key)322     String getGlobalSetting(String key) {
323         return Settings.Global.getString(mContentResolver, key);
324     }
325 
326     @VisibleForTesting
getDeviceSpecificConfigResId()327     int getDeviceSpecificConfigResId() {
328         return R.string.config_batterySaverDeviceSpecificConfig;
329     }
330 
331     @VisibleForTesting
invalidatePowerSaveModeCaches()332     void invalidatePowerSaveModeCaches() {
333         PowerManager.invalidatePowerSaveModeCaches();
334     }
335 
336     /**
337      * Notifies listeners of a policy change on the handler thread only if the current policy level
338      * is not {@link #POLICY_LEVEL_OFF}.
339      */
maybeNotifyListenersOfPolicyChange()340     private void maybeNotifyListenersOfPolicyChange() {
341         final BatterySaverPolicyListener[] listeners;
342         synchronized (mLock) {
343             if (mPolicyLevel == POLICY_LEVEL_OFF) {
344                 // Current policy is OFF, so there's no change to notify listeners of.
345                 return;
346             }
347             // Don't call out to listeners with the lock held.
348             listeners = mListeners.toArray(new BatterySaverPolicyListener[mListeners.size()]);
349         }
350 
351         mHandler.post(() -> {
352             for (BatterySaverPolicyListener listener : listeners) {
353                 listener.onBatterySaverPolicyChanged(this);
354             }
355         });
356     }
357 
358     @Override
onChange(boolean selfChange, Uri uri)359     public void onChange(boolean selfChange, Uri uri) {
360         refreshSettings();
361     }
362 
363     @Override
onPropertiesChanged(DeviceConfig.Properties properties)364     public void onPropertiesChanged(DeviceConfig.Properties properties) {
365         // Need to get all of the flags atomically.
366         mLastDeviceConfigProperties =
367                 DeviceConfig.getProperties(DeviceConfig.NAMESPACE_BATTERY_SAVER);
368         Policy newAdaptivePolicy = null;
369         Policy newFullPolicy = null;
370 
371         boolean changed = false;
372 
373         synchronized (mLock) {
374             for (String name : properties.getKeyset()) {
375                 if (name == null) {
376                     continue;
377                 }
378                 if (name.endsWith(KEY_SUFFIX_ADAPTIVE)) {
379                     if (newAdaptivePolicy == null) {
380                         newAdaptivePolicy = Policy.fromSettings("", "",
381                                 mLastDeviceConfigProperties, KEY_SUFFIX_ADAPTIVE,
382                                 DEFAULT_ADAPTIVE_POLICY);
383                     }
384                 } else if (newFullPolicy == null) {
385                     newFullPolicy = Policy.fromSettings(mSettings, mDeviceSpecificSettings,
386                             mLastDeviceConfigProperties, null, DEFAULT_FULL_POLICY);
387                 }
388             }
389 
390             if (newFullPolicy != null) {
391                 changed |= maybeUpdateDefaultFullPolicy(newFullPolicy);
392             }
393 
394             if (newAdaptivePolicy != null && !mAdaptivePolicy.equals(newAdaptivePolicy)) {
395                 mDefaultAdaptivePolicy = newAdaptivePolicy;
396                 // This will override any config set by an external source. This should be fine
397                 // for now.
398                 // TODO(119261320): make sure it doesn't override what's set externally
399                 mAdaptivePolicy = mDefaultAdaptivePolicy;
400                 changed |= (mPolicyLevel == POLICY_LEVEL_ADAPTIVE);
401             }
402 
403             updatePolicyDependenciesLocked();
404         }
405 
406         if (changed) {
407             maybeNotifyListenersOfPolicyChange();
408         }
409     }
410 
refreshSettings()411     private void refreshSettings() {
412         synchronized (mLock) {
413             // Load the non-device-specific setting.
414             final String setting = getGlobalSetting(Settings.Global.BATTERY_SAVER_CONSTANTS);
415 
416             // Load the device specific setting.
417             // We first check the global setting, and if it's empty or the string "null" is set,
418             // use the default value from config.xml.
419             String deviceSpecificSetting = getGlobalSetting(
420                     Settings.Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS);
421             mDeviceSpecificSettingsSource =
422                     Settings.Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS;
423 
424             if (TextUtils.isEmpty(deviceSpecificSetting) || "null".equals(deviceSpecificSetting)) {
425                 deviceSpecificSetting =
426                         mContext.getString(getDeviceSpecificConfigResId());
427                 mDeviceSpecificSettingsSource = "(overlay)";
428             }
429 
430             if (!updateConstantsLocked(setting, deviceSpecificSetting)) {
431                 // Nothing of note changed.
432                 return;
433             }
434         }
435 
436         maybeNotifyListenersOfPolicyChange();
437     }
438 
439     @GuardedBy("mLock")
440     @VisibleForTesting
441     /** @return true if the currently active policy changed. */
updateConstantsLocked(String setting, String deviceSpecificSetting)442     boolean updateConstantsLocked(String setting, String deviceSpecificSetting) {
443         setting = TextUtils.emptyIfNull(setting);
444         deviceSpecificSetting = TextUtils.emptyIfNull(deviceSpecificSetting);
445 
446         if (setting.equals(mSettings)
447                 && deviceSpecificSetting.equals(mDeviceSpecificSettings)) {
448             return false;
449         }
450 
451         mSettings = setting;
452         mDeviceSpecificSettings = deviceSpecificSetting;
453 
454         if (DEBUG) {
455             Slog.i(TAG, "mSettings=" + mSettings);
456             Slog.i(TAG, "mDeviceSpecificSettings=" + mDeviceSpecificSettings);
457         }
458 
459         boolean changed = maybeUpdateDefaultFullPolicy(
460                 Policy.fromSettings(setting, deviceSpecificSetting,
461                         mLastDeviceConfigProperties, null, DEFAULT_FULL_POLICY));
462 
463         mDefaultAdaptivePolicy = Policy.fromSettings("", "",
464                 mLastDeviceConfigProperties, KEY_SUFFIX_ADAPTIVE, DEFAULT_ADAPTIVE_POLICY);
465         if (mPolicyLevel == POLICY_LEVEL_ADAPTIVE
466                 && !mAdaptivePolicy.equals(mDefaultAdaptivePolicy)) {
467             changed = true;
468         }
469         // This will override any config set by an external source. This should be fine for now.
470         // TODO: make sure it doesn't override what's set externally
471         mAdaptivePolicy = mDefaultAdaptivePolicy;
472 
473         updatePolicyDependenciesLocked();
474 
475         return changed;
476     }
477 
478     @GuardedBy("mLock")
updatePolicyDependenciesLocked()479     private void updatePolicyDependenciesLocked() {
480         final Policy rawPolicy = getCurrentRawPolicyLocked();
481         final int locationMode;
482 
483         invalidatePowerSaveModeCaches();
484         if (mAutomotiveProjectionActive.get()
485                 && rawPolicy.locationMode != PowerManager.LOCATION_MODE_NO_CHANGE
486                 && rawPolicy.locationMode != PowerManager.LOCATION_MODE_FOREGROUND_ONLY) {
487             // If car projection is enabled, ensure that navigation works.
488             locationMode = PowerManager.LOCATION_MODE_FOREGROUND_ONLY;
489         } else {
490             locationMode = rawPolicy.locationMode;
491         }
492 
493         mEffectivePolicyRaw = new Policy(
494                 rawPolicy.adjustBrightnessFactor,
495                 rawPolicy.advertiseIsEnabled,
496                 rawPolicy.deferFullBackup,
497                 rawPolicy.deferKeyValueBackup,
498                 rawPolicy.disableAnimation,
499                 rawPolicy.disableAod,
500                 rawPolicy.disableLaunchBoost,
501                 rawPolicy.disableOptionalSensors,
502                 // Don't disable vibration when accessibility is on.
503                 rawPolicy.disableVibration && !mAccessibilityEnabled.get(),
504                 rawPolicy.enableAdjustBrightness,
505                 rawPolicy.enableDataSaver,
506                 rawPolicy.enableFirewall,
507                 // Don't force night mode when car projection is enabled.
508                 rawPolicy.enableNightMode && !mAutomotiveProjectionActive.get(),
509                 rawPolicy.enableQuickDoze,
510                 rawPolicy.forceAllAppsStandby,
511                 rawPolicy.forceBackgroundCheck,
512                 locationMode,
513                 rawPolicy.soundTriggerMode
514         );
515 
516 
517         final StringBuilder sb = new StringBuilder();
518 
519         if (mEffectivePolicyRaw.forceAllAppsStandby) sb.append("A");
520         if (mEffectivePolicyRaw.forceBackgroundCheck) sb.append("B");
521 
522         if (mEffectivePolicyRaw.disableVibration) sb.append("v");
523         if (mEffectivePolicyRaw.disableAnimation) sb.append("a");
524 
525         sb.append(mEffectivePolicyRaw.soundTriggerMode);
526 
527         if (mEffectivePolicyRaw.deferFullBackup) sb.append("F");
528         if (mEffectivePolicyRaw.deferKeyValueBackup) sb.append("K");
529         if (mEffectivePolicyRaw.enableFirewall) sb.append("f");
530         if (mEffectivePolicyRaw.enableDataSaver) sb.append("d");
531         if (mEffectivePolicyRaw.enableAdjustBrightness) sb.append("b");
532 
533         if (mEffectivePolicyRaw.disableLaunchBoost) sb.append("l");
534         if (mEffectivePolicyRaw.disableOptionalSensors) sb.append("S");
535         if (mEffectivePolicyRaw.disableAod) sb.append("o");
536         if (mEffectivePolicyRaw.enableQuickDoze) sb.append("q");
537 
538         sb.append(mEffectivePolicyRaw.locationMode);
539 
540         mEventLogKeys = sb.toString();
541     }
542 
543     static class Policy {
544         /**
545          * This is the flag to decide the how much to adjust the screen brightness. This is
546          * the float value from 0 to 1 where 1 means don't change brightness.
547          *
548          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
549          * @see #KEY_ADJUST_BRIGHTNESS_FACTOR
550          */
551         public final float adjustBrightnessFactor;
552 
553         /**
554          * {@code true} if the Policy should advertise to the rest of the system that battery saver
555          * is enabled. This advertising could cause other system components to change their
556          * behavior. This will not affect other policy flags and what they change.
557          *
558          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
559          * @see #KEY_ADVERTISE_IS_ENABLED
560          */
561         public final boolean advertiseIsEnabled;
562 
563         /**
564          * {@code true} if full backup is deferred in battery saver mode.
565          *
566          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
567          * @see #KEY_DEFER_FULL_BACKUP
568          */
569         public final boolean deferFullBackup;
570 
571         /**
572          * {@code true} if key value backup is deferred in battery saver mode.
573          *
574          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
575          * @see #KEY_DEFER_KEYVALUE_BACKUP
576          */
577         public final boolean deferKeyValueBackup;
578 
579         /**
580          * {@code true} if animation is disabled in battery saver mode.
581          *
582          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
583          * @see #KEY_DISABLE_ANIMATION
584          */
585         public final boolean disableAnimation;
586 
587         /**
588          * {@code true} if AOD is disabled in battery saver mode.
589          */
590         public final boolean disableAod;
591 
592         /**
593          * {@code true} if launch boost should be disabled on battery saver.
594          */
595         public final boolean disableLaunchBoost;
596 
597         /**
598          * Whether to show non-essential sensors (e.g. edge sensors) or not.
599          */
600         public final boolean disableOptionalSensors;
601 
602         /**
603          * {@code true} if sound trigger is disabled in battery saver mode
604          * in battery saver mode.
605          *
606          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
607          * @see #KEY_SOUNDTRIGGER_MODE
608          */
609         public final int soundTriggerMode;
610 
611         /**
612          * {@code true} if vibration is disabled in battery saver mode.
613          *
614          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
615          * @see #KEY_DISABLE_VIBRATION
616          */
617         public final boolean disableVibration;
618 
619         /**
620          * {@code true} if low power mode brightness adjustment should be turned on in battery saver
621          * mode.
622          *
623          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
624          * @see #KEY_ENABLE_BRIGHTNESS_ADJUSTMENT
625          */
626         public final boolean enableAdjustBrightness;
627 
628         /**
629          * {@code true} if data saver should be turned on in battery saver mode.
630          *
631          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
632          * @see #KEY_ENABLE_DATASAVER
633          */
634         public final boolean enableDataSaver;
635 
636         /**
637          * {@code true} if network policy firewall should be turned on in battery saver mode.
638          *
639          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
640          * @see #KEY_ENABLE_FIREWALL
641          */
642         public final boolean enableFirewall;
643 
644         /**
645          * Whether to enable night mode or not.
646          */
647         public final boolean enableNightMode;
648 
649         /**
650          * Whether Quick Doze is enabled or not.
651          */
652         public final boolean enableQuickDoze;
653 
654         /**
655          * Whether to put all apps in the stand-by mode.
656          */
657         public final boolean forceAllAppsStandby;
658 
659         /**
660          * Whether to force background check.
661          */
662         public final boolean forceBackgroundCheck;
663 
664         /**
665          * This is the flag to decide the location mode in battery saver mode. This was
666          * previously called gpsMode.
667          *
668          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
669          * @see #KEY_LOCATION_MODE
670          */
671         public final int locationMode;
672 
673         private final int mHashCode;
674 
Policy( float adjustBrightnessFactor, boolean advertiseIsEnabled, boolean deferFullBackup, boolean deferKeyValueBackup, boolean disableAnimation, boolean disableAod, boolean disableLaunchBoost, boolean disableOptionalSensors, boolean disableVibration, boolean enableAdjustBrightness, boolean enableDataSaver, boolean enableFirewall, boolean enableNightMode, boolean enableQuickDoze, boolean forceAllAppsStandby, boolean forceBackgroundCheck, int locationMode, int soundTriggerMode)675         Policy(
676                 float adjustBrightnessFactor,
677                 boolean advertiseIsEnabled,
678                 boolean deferFullBackup,
679                 boolean deferKeyValueBackup,
680                 boolean disableAnimation,
681                 boolean disableAod,
682                 boolean disableLaunchBoost,
683                 boolean disableOptionalSensors,
684                 boolean disableVibration,
685                 boolean enableAdjustBrightness,
686                 boolean enableDataSaver,
687                 boolean enableFirewall,
688                 boolean enableNightMode,
689                 boolean enableQuickDoze,
690                 boolean forceAllAppsStandby,
691                 boolean forceBackgroundCheck,
692                 int locationMode,
693                 int soundTriggerMode) {
694 
695             this.adjustBrightnessFactor = Math.min(1, Math.max(0, adjustBrightnessFactor));
696             this.advertiseIsEnabled = advertiseIsEnabled;
697             this.deferFullBackup = deferFullBackup;
698             this.deferKeyValueBackup = deferKeyValueBackup;
699             this.disableAnimation = disableAnimation;
700             this.disableAod = disableAod;
701             this.disableLaunchBoost = disableLaunchBoost;
702             this.disableOptionalSensors = disableOptionalSensors;
703             this.disableVibration = disableVibration;
704             this.enableAdjustBrightness = enableAdjustBrightness;
705             this.enableDataSaver = enableDataSaver;
706             this.enableFirewall = enableFirewall;
707             this.enableNightMode = enableNightMode;
708             this.enableQuickDoze = enableQuickDoze;
709             this.forceAllAppsStandby = forceAllAppsStandby;
710             this.forceBackgroundCheck = forceBackgroundCheck;
711 
712             if (locationMode < PowerManager.MIN_LOCATION_MODE
713                     || PowerManager.MAX_LOCATION_MODE < locationMode) {
714                 Slog.e(TAG, "Invalid location mode: " + locationMode);
715                 this.locationMode = PowerManager.LOCATION_MODE_NO_CHANGE;
716             } else {
717                 this.locationMode = locationMode;
718             }
719 
720             if (soundTriggerMode < PowerManager.MIN_SOUND_TRIGGER_MODE
721                     || soundTriggerMode > PowerManager.MAX_SOUND_TRIGGER_MODE) {
722                 Slog.e(TAG, "Invalid SoundTrigger mode: " + soundTriggerMode);
723                 this.soundTriggerMode = PowerManager.SOUND_TRIGGER_MODE_ALL_ENABLED;
724             } else {
725                 this.soundTriggerMode = soundTriggerMode;
726             }
727 
728             mHashCode = Objects.hash(
729                     adjustBrightnessFactor,
730                     advertiseIsEnabled,
731                     deferFullBackup,
732                     deferKeyValueBackup,
733                     disableAnimation,
734                     disableAod,
735                     disableLaunchBoost,
736                     disableOptionalSensors,
737                     disableVibration,
738                     enableAdjustBrightness,
739                     enableDataSaver,
740                     enableFirewall,
741                     enableNightMode,
742                     enableQuickDoze,
743                     forceAllAppsStandby,
744                     forceBackgroundCheck,
745                     locationMode,
746                     soundTriggerMode);
747         }
748 
fromConfig(BatterySaverPolicyConfig config)749         static Policy fromConfig(BatterySaverPolicyConfig config) {
750             if (config == null) {
751                 Slog.e(TAG, "Null config passed down to BatterySaverPolicy");
752                 return OFF_POLICY;
753             }
754 
755             // Device-specific parameters.
756             Map<String, String> deviceSpecificSettings = config.getDeviceSpecificSettings();
757 
758             return new Policy(
759                     config.getAdjustBrightnessFactor(),
760                     config.getAdvertiseIsEnabled(),
761                     config.getDeferFullBackup(),
762                     config.getDeferKeyValueBackup(),
763                     config.getDisableAnimation(),
764                     config.getDisableAod(),
765                     config.getDisableLaunchBoost(),
766                     config.getDisableOptionalSensors(),
767                     config.getDisableVibration(),
768                     config.getEnableAdjustBrightness(),
769                     config.getEnableDataSaver(),
770                     config.getEnableFirewall(),
771                     config.getEnableNightMode(),
772                     config.getEnableQuickDoze(),
773                     config.getForceAllAppsStandby(),
774                     config.getForceBackgroundCheck(),
775                     config.getLocationMode(),
776                     config.getSoundTriggerMode()
777             );
778         }
779 
toConfig()780         BatterySaverPolicyConfig toConfig() {
781             return new BatterySaverPolicyConfig.Builder()
782                     .setAdjustBrightnessFactor(adjustBrightnessFactor)
783                     .setAdvertiseIsEnabled(advertiseIsEnabled)
784                     .setDeferFullBackup(deferFullBackup)
785                     .setDeferKeyValueBackup(deferKeyValueBackup)
786                     .setDisableAnimation(disableAnimation)
787                     .setDisableAod(disableAod)
788                     .setDisableLaunchBoost(disableLaunchBoost)
789                     .setDisableOptionalSensors(disableOptionalSensors)
790                     .setDisableVibration(disableVibration)
791                     .setEnableAdjustBrightness(enableAdjustBrightness)
792                     .setEnableDataSaver(enableDataSaver)
793                     .setEnableFirewall(enableFirewall)
794                     .setEnableNightMode(enableNightMode)
795                     .setEnableQuickDoze(enableQuickDoze)
796                     .setForceAllAppsStandby(forceAllAppsStandby)
797                     .setForceBackgroundCheck(forceBackgroundCheck)
798                     .setLocationMode(locationMode)
799                     .setSoundTriggerMode(soundTriggerMode)
800                     .build();
801         }
802 
803         @VisibleForTesting
fromSettings(String settings, String deviceSpecificSettings, DeviceConfig.Properties properties, String configSuffix)804         static Policy fromSettings(String settings, String deviceSpecificSettings,
805                 DeviceConfig.Properties properties, String configSuffix) {
806             return fromSettings(settings, deviceSpecificSettings, properties, configSuffix,
807                     OFF_POLICY);
808         }
809 
fromSettings(String settings, String deviceSpecificSettings, DeviceConfig.Properties properties, String configSuffix, Policy defaultPolicy)810         private static Policy fromSettings(String settings, String deviceSpecificSettings,
811                 DeviceConfig.Properties properties, String configSuffix, Policy defaultPolicy) {
812             final UserSettingDeviceConfigMediator userSettingDeviceConfigMediator =
813                     new UserSettingDeviceConfigMediator.SettingsOverridesIndividualMediator(',');
814             configSuffix = TextUtils.emptyIfNull(configSuffix);
815 
816             // Device-specific parameters.
817             try {
818                 userSettingDeviceConfigMediator.setSettingsString(deviceSpecificSettings);
819             } catch (IllegalArgumentException e) {
820                 Slog.wtf(TAG, "Bad device specific battery saver constants: "
821                         + deviceSpecificSettings);
822             }
823 
824             // Non-device-specific parameters.
825             try {
826                 userSettingDeviceConfigMediator.setSettingsString(settings);
827                 userSettingDeviceConfigMediator.setDeviceConfigProperties(properties);
828             } catch (IllegalArgumentException e) {
829                 Slog.wtf(TAG, "Bad battery saver constants: " + settings);
830             }
831 
832             // The Settings value overrides everything, since that will be set by the user.
833             // The DeviceConfig value takes second place, with the default as the last choice.
834             final float adjustBrightnessFactor = userSettingDeviceConfigMediator.getFloat(
835                     KEY_ADJUST_BRIGHTNESS_FACTOR + configSuffix,
836                     defaultPolicy.adjustBrightnessFactor);
837             final boolean advertiseIsEnabled = userSettingDeviceConfigMediator.getBoolean(
838                     KEY_ADVERTISE_IS_ENABLED + configSuffix,
839                     defaultPolicy.advertiseIsEnabled);
840             final boolean deferFullBackup = userSettingDeviceConfigMediator.getBoolean(
841                     KEY_DEFER_FULL_BACKUP + configSuffix, defaultPolicy.deferFullBackup);
842             final boolean deferKeyValueBackup = userSettingDeviceConfigMediator.getBoolean(
843                     KEY_DEFER_KEYVALUE_BACKUP + configSuffix,
844                     defaultPolicy.deferKeyValueBackup);
845             final boolean disableAnimation = userSettingDeviceConfigMediator.getBoolean(
846                     KEY_DISABLE_ANIMATION + configSuffix, defaultPolicy.disableAnimation);
847             final boolean disableAod = userSettingDeviceConfigMediator.getBoolean(
848                     KEY_DISABLE_AOD + configSuffix, defaultPolicy.disableAod);
849             final boolean disableLaunchBoost = userSettingDeviceConfigMediator.getBoolean(
850                     KEY_DISABLE_LAUNCH_BOOST + configSuffix,
851                     defaultPolicy.disableLaunchBoost);
852             final boolean disableOptionalSensors = userSettingDeviceConfigMediator.getBoolean(
853                     KEY_DISABLE_OPTIONAL_SENSORS + configSuffix,
854                     defaultPolicy.disableOptionalSensors);
855             final boolean disableVibrationConfig = userSettingDeviceConfigMediator.getBoolean(
856                     KEY_DISABLE_VIBRATION + configSuffix, defaultPolicy.disableVibration);
857             final boolean enableBrightnessAdjustment = userSettingDeviceConfigMediator.getBoolean(
858                     KEY_ENABLE_BRIGHTNESS_ADJUSTMENT + configSuffix,
859                     defaultPolicy.enableAdjustBrightness);
860             final boolean enableDataSaver = userSettingDeviceConfigMediator.getBoolean(
861                     KEY_ENABLE_DATASAVER + configSuffix, defaultPolicy.enableDataSaver);
862             final boolean enableFirewall = userSettingDeviceConfigMediator.getBoolean(
863                     KEY_ENABLE_FIREWALL + configSuffix, defaultPolicy.enableFirewall);
864             final boolean enableNightMode = userSettingDeviceConfigMediator.getBoolean(
865                     KEY_ENABLE_NIGHT_MODE + configSuffix, defaultPolicy.enableNightMode);
866             final boolean enableQuickDoze = userSettingDeviceConfigMediator.getBoolean(
867                     KEY_ENABLE_QUICK_DOZE + configSuffix, defaultPolicy.enableQuickDoze);
868             final boolean forceAllAppsStandby = userSettingDeviceConfigMediator.getBoolean(
869                     KEY_FORCE_ALL_APPS_STANDBY + configSuffix,
870                     defaultPolicy.forceAllAppsStandby);
871             final boolean forceBackgroundCheck = userSettingDeviceConfigMediator.getBoolean(
872                     KEY_FORCE_BACKGROUND_CHECK + configSuffix,
873                     defaultPolicy.forceBackgroundCheck);
874             final int locationMode = userSettingDeviceConfigMediator.getInt(
875                     KEY_LOCATION_MODE + configSuffix, defaultPolicy.locationMode);
876             final int soundTriggerMode = userSettingDeviceConfigMediator.getInt(
877                     KEY_SOUNDTRIGGER_MODE + configSuffix, defaultPolicy.soundTriggerMode);
878             return new Policy(
879                     adjustBrightnessFactor,
880                     advertiseIsEnabled,
881                     deferFullBackup,
882                     deferKeyValueBackup,
883                     disableAnimation,
884                     disableAod,
885                     disableLaunchBoost,
886                     disableOptionalSensors,
887                     /* disableVibration */
888                     disableVibrationConfig,
889                     enableBrightnessAdjustment,
890                     enableDataSaver,
891                     enableFirewall,
892                     enableNightMode,
893                     enableQuickDoze,
894                     forceAllAppsStandby,
895                     forceBackgroundCheck,
896                     locationMode,
897                     soundTriggerMode
898             );
899         }
900 
901         @Override
equals(Object obj)902         public boolean equals(Object obj) {
903             if (this == obj) return true;
904             if (!(obj instanceof Policy)) return false;
905             Policy other = (Policy) obj;
906             return Float.compare(other.adjustBrightnessFactor, adjustBrightnessFactor) == 0
907                     && advertiseIsEnabled == other.advertiseIsEnabled
908                     && deferFullBackup == other.deferFullBackup
909                     && deferKeyValueBackup == other.deferKeyValueBackup
910                     && disableAnimation == other.disableAnimation
911                     && disableAod == other.disableAod
912                     && disableLaunchBoost == other.disableLaunchBoost
913                     && disableOptionalSensors == other.disableOptionalSensors
914                     && disableVibration == other.disableVibration
915                     && enableAdjustBrightness == other.enableAdjustBrightness
916                     && enableDataSaver == other.enableDataSaver
917                     && enableFirewall == other.enableFirewall
918                     && enableNightMode == other.enableNightMode
919                     && enableQuickDoze == other.enableQuickDoze
920                     && forceAllAppsStandby == other.forceAllAppsStandby
921                     && forceBackgroundCheck == other.forceBackgroundCheck
922                     && locationMode == other.locationMode
923                     && soundTriggerMode == other.soundTriggerMode;
924         }
925 
926         @Override
hashCode()927         public int hashCode() {
928             return mHashCode;
929         }
930     }
931 
932     /**
933      * Get the {@link PowerSaveState} based on the current policy level.
934      * The result will have {@link PowerSaveState#batterySaverEnabled} and some other
935      * parameters when necessary.
936      *
937      * @param type   type of the service, one of {@link ServiceType}
938      * @return State data that contains battery saver data
939      */
getBatterySaverPolicy(@erviceType int type)940     public PowerSaveState getBatterySaverPolicy(@ServiceType int type) {
941         synchronized (mLock) {
942             final Policy currPolicy = getCurrentPolicyLocked();
943             final PowerSaveState.Builder builder = new PowerSaveState.Builder()
944                     .setGlobalBatterySaverEnabled(currPolicy.advertiseIsEnabled);
945             switch (type) {
946                 case ServiceType.LOCATION:
947                     boolean isEnabled = currPolicy.advertiseIsEnabled
948                             || currPolicy.locationMode != PowerManager.LOCATION_MODE_NO_CHANGE;
949                     return builder.setBatterySaverEnabled(isEnabled)
950                             .setLocationMode(currPolicy.locationMode)
951                             .build();
952                 case ServiceType.ANIMATION:
953                     return builder.setBatterySaverEnabled(currPolicy.disableAnimation)
954                             .build();
955                 case ServiceType.FULL_BACKUP:
956                     return builder.setBatterySaverEnabled(currPolicy.deferFullBackup)
957                             .build();
958                 case ServiceType.KEYVALUE_BACKUP:
959                     return builder.setBatterySaverEnabled(currPolicy.deferKeyValueBackup)
960                             .build();
961                 case ServiceType.NETWORK_FIREWALL:
962                     return builder.setBatterySaverEnabled(currPolicy.enableFirewall)
963                             .build();
964                 case ServiceType.SCREEN_BRIGHTNESS:
965                     return builder.setBatterySaverEnabled(currPolicy.enableAdjustBrightness)
966                             .setBrightnessFactor(currPolicy.adjustBrightnessFactor)
967                             .build();
968                 case ServiceType.DATA_SAVER:
969                     return builder.setBatterySaverEnabled(currPolicy.enableDataSaver)
970                             .build();
971                 case ServiceType.SOUND:
972                     boolean soundTriggerBatterySaverEnabled = currPolicy.advertiseIsEnabled
973                             || currPolicy.soundTriggerMode
974                             != PowerManager.SOUND_TRIGGER_MODE_ALL_ENABLED;
975                     return builder.setBatterySaverEnabled(soundTriggerBatterySaverEnabled)
976                             .setSoundTriggerMode(currPolicy.soundTriggerMode)
977                             .build();
978                 case ServiceType.VIBRATION:
979                     return builder.setBatterySaverEnabled(currPolicy.disableVibration)
980                             .build();
981                 case ServiceType.FORCE_ALL_APPS_STANDBY:
982                     return builder.setBatterySaverEnabled(currPolicy.forceAllAppsStandby)
983                             .build();
984                 case ServiceType.FORCE_BACKGROUND_CHECK:
985                     return builder.setBatterySaverEnabled(currPolicy.forceBackgroundCheck)
986                             .build();
987                 case ServiceType.NIGHT_MODE:
988                     return builder.setBatterySaverEnabled(currPolicy.enableNightMode)
989                             .build();
990                 case ServiceType.OPTIONAL_SENSORS:
991                     return builder.setBatterySaverEnabled(currPolicy.disableOptionalSensors)
992                             .build();
993                 case ServiceType.AOD:
994                     return builder.setBatterySaverEnabled(currPolicy.disableAod)
995                             .build();
996                 case ServiceType.QUICK_DOZE:
997                     return builder.setBatterySaverEnabled(currPolicy.enableQuickDoze)
998                             .build();
999                 default:
1000                     return builder.setBatterySaverEnabled(currPolicy.advertiseIsEnabled)
1001                             .build();
1002             }
1003         }
1004     }
1005 
1006     /**
1007      * Sets the current policy.
1008      *
1009      * @return true if the policy level was changed.
1010      */
setPolicyLevel(@olicyLevel int level)1011     boolean setPolicyLevel(@PolicyLevel int level) {
1012         synchronized (mLock) {
1013             if (mPolicyLevel == level) {
1014                 return false;
1015             }
1016             // If we are leaving the full policy level, then any overrides to the full policy set
1017             // through #setFullPolicyLocked should be cleared.
1018             if (mPolicyLevel == POLICY_LEVEL_FULL) {
1019                 mFullPolicy = mDefaultFullPolicy;
1020             }
1021             switch (level) {
1022                 case POLICY_LEVEL_FULL:
1023                 case POLICY_LEVEL_ADAPTIVE:
1024                 case POLICY_LEVEL_OFF:
1025                     mPolicyLevel = level;
1026                     break;
1027                 default:
1028                     Slog.wtf(TAG, "setPolicyLevel invalid level given: " + level);
1029                     return false;
1030             }
1031             updatePolicyDependenciesLocked();
1032             return true;
1033         }
1034     }
1035 
1036     /**
1037      * Get the current policy for the provided policy level.
1038      */
getPolicyLocked(@olicyLevel int policyLevel)1039     Policy getPolicyLocked(@PolicyLevel int policyLevel) {
1040         switch (policyLevel) {
1041             case POLICY_LEVEL_OFF:
1042                 return OFF_POLICY;
1043             case POLICY_LEVEL_ADAPTIVE:
1044                 return mAdaptivePolicy;
1045             case POLICY_LEVEL_FULL:
1046                 return mFullPolicy;
1047         }
1048 
1049         throw new IllegalArgumentException(
1050                 "getPolicyLocked: incorrect policy level provided - " + policyLevel);
1051     }
1052 
1053     /**
1054      * Updates the default policy with the passed in policy.
1055      * If the full policy is not overridden with runtime settings, then the full policy will be
1056      * updated.
1057      *
1058      * @return True if the active policy requires an update, false if not.
1059      */
maybeUpdateDefaultFullPolicy(Policy p)1060     private boolean maybeUpdateDefaultFullPolicy(Policy p) {
1061         boolean fullPolicyChanged = false;
1062         if (!mDefaultFullPolicy.equals(p)) {
1063             // default policy can be overridden by #setFullPolicyLocked
1064             boolean isDefaultFullPolicyOverridden = !mDefaultFullPolicy.equals(mFullPolicy);
1065             if (!isDefaultFullPolicyOverridden) {
1066                 mFullPolicy = p;
1067                 fullPolicyChanged = (mPolicyLevel == POLICY_LEVEL_FULL);
1068             }
1069             mDefaultFullPolicy = p;
1070         }
1071         return fullPolicyChanged;
1072     }
1073 
1074     /** @return true if the current policy changed and the policy level is FULL. */
setFullPolicyLocked(Policy p)1075     boolean setFullPolicyLocked(Policy p) {
1076         if (p == null) {
1077             Slog.wtf(TAG, "setFullPolicy given null policy");
1078             return false;
1079         }
1080         if (mFullPolicy.equals(p)) {
1081             return false;
1082         }
1083 
1084         mFullPolicy = p;
1085         if (mPolicyLevel == POLICY_LEVEL_FULL) {
1086             updatePolicyDependenciesLocked();
1087             return true;
1088         }
1089         return false;
1090     }
1091 
1092     /** @return true if the current policy changed and the policy level is ADAPTIVE. */
setAdaptivePolicyLocked(Policy p)1093     boolean setAdaptivePolicyLocked(Policy p) {
1094         if (p == null) {
1095             Slog.wtf(TAG, "setAdaptivePolicy given null policy");
1096             return false;
1097         }
1098         if (mAdaptivePolicy.equals(p)) {
1099             return false;
1100         }
1101 
1102         mAdaptivePolicy = p;
1103         if (mPolicyLevel == POLICY_LEVEL_ADAPTIVE) {
1104             updatePolicyDependenciesLocked();
1105             return true;
1106         }
1107         return false;
1108     }
1109 
1110     /** @return true if the current policy changed and the policy level is ADAPTIVE. */
resetAdaptivePolicyLocked()1111     boolean resetAdaptivePolicyLocked() {
1112         return setAdaptivePolicyLocked(mDefaultAdaptivePolicy);
1113     }
1114 
getCurrentPolicyLocked()1115     private Policy getCurrentPolicyLocked() {
1116         return mEffectivePolicyRaw;
1117     }
1118 
getCurrentRawPolicyLocked()1119     private Policy getCurrentRawPolicyLocked() {
1120         switch (mPolicyLevel) {
1121             case POLICY_LEVEL_FULL:
1122                 return mFullPolicy;
1123             case POLICY_LEVEL_ADAPTIVE:
1124                 return mAdaptivePolicy;
1125             case POLICY_LEVEL_OFF:
1126             default:
1127                 return OFF_POLICY;
1128         }
1129     }
1130 
getGpsMode()1131     public int getGpsMode() {
1132         synchronized (mLock) {
1133             return getCurrentPolicyLocked().locationMode;
1134         }
1135     }
1136 
isLaunchBoostDisabled()1137     public boolean isLaunchBoostDisabled() {
1138         synchronized (mLock) {
1139             return getCurrentPolicyLocked().disableLaunchBoost;
1140         }
1141     }
1142 
shouldAdvertiseIsEnabled()1143     boolean shouldAdvertiseIsEnabled() {
1144         synchronized (mLock) {
1145             return getCurrentPolicyLocked().advertiseIsEnabled;
1146         }
1147     }
1148 
toEventLogString()1149     public String toEventLogString() {
1150         synchronized (mLock) {
1151             return mEventLogKeys;
1152         }
1153     }
1154 
dump(PrintWriter pw)1155     public void dump(PrintWriter pw) {
1156         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
1157 
1158         synchronized (mLock) {
1159             ipw.println();
1160             mBatterySavingStats.dump(ipw);
1161 
1162             ipw.println();
1163             ipw.println("Battery saver policy (*NOTE* they only apply when battery saver is ON):");
1164             ipw.increaseIndent();
1165             ipw.println("Settings: " + Settings.Global.BATTERY_SAVER_CONSTANTS);
1166             ipw.increaseIndent();
1167             ipw.println("value: " + mSettings);
1168             ipw.decreaseIndent();
1169             ipw.println("Settings: " + mDeviceSpecificSettingsSource);
1170             ipw.increaseIndent();
1171             ipw.println("value: " + mDeviceSpecificSettings);
1172             ipw.decreaseIndent();
1173             ipw.println("DeviceConfig: " + DeviceConfig.NAMESPACE_BATTERY_SAVER);
1174             ipw.increaseIndent();
1175             final Set<String> keys = mLastDeviceConfigProperties.getKeyset();
1176             if (keys.size() == 0) {
1177                 ipw.println("N/A");
1178             } else {
1179                 for (final String key : keys) {
1180                     ipw.print(key);
1181                     ipw.print(": ");
1182                     ipw.println(mLastDeviceConfigProperties.getString(key, null));
1183                 }
1184             }
1185             ipw.decreaseIndent();
1186 
1187             ipw.println("mAccessibilityEnabled=" + mAccessibilityEnabled.get());
1188             ipw.println("mAutomotiveProjectionActive=" + mAutomotiveProjectionActive.get());
1189             ipw.println("mPolicyLevel=" + mPolicyLevel);
1190 
1191             dumpPolicyLocked(ipw, "default full", mDefaultFullPolicy);
1192             dumpPolicyLocked(ipw, "current full", mFullPolicy);
1193             dumpPolicyLocked(ipw, "default adaptive", mDefaultAdaptivePolicy);
1194             dumpPolicyLocked(ipw, "current adaptive", mAdaptivePolicy);
1195             dumpPolicyLocked(ipw, "effective", mEffectivePolicyRaw);
1196 
1197             ipw.decreaseIndent();
1198         }
1199     }
1200 
dumpPolicyLocked(IndentingPrintWriter pw, String label, Policy p)1201     private void dumpPolicyLocked(IndentingPrintWriter pw, String label, Policy p) {
1202         pw.println();
1203         pw.println("Policy '" + label + "'");
1204         pw.increaseIndent();
1205         pw.println(KEY_ADVERTISE_IS_ENABLED + "=" + p.advertiseIsEnabled);
1206         pw.println(KEY_DISABLE_VIBRATION + "=" + p.disableVibration);
1207         pw.println(KEY_DISABLE_ANIMATION + "=" + p.disableAnimation);
1208         pw.println(KEY_DEFER_FULL_BACKUP + "=" + p.deferFullBackup);
1209         pw.println(KEY_DEFER_KEYVALUE_BACKUP + "=" + p.deferKeyValueBackup);
1210         pw.println(KEY_ENABLE_FIREWALL + "=" + p.enableFirewall);
1211         pw.println(KEY_ENABLE_DATASAVER + "=" + p.enableDataSaver);
1212         pw.println(KEY_DISABLE_LAUNCH_BOOST + "=" + p.disableLaunchBoost);
1213         pw.println(KEY_ENABLE_BRIGHTNESS_ADJUSTMENT + "=" + p.enableAdjustBrightness);
1214         pw.println(KEY_ADJUST_BRIGHTNESS_FACTOR + "=" + p.adjustBrightnessFactor);
1215         pw.println(KEY_LOCATION_MODE + "=" + p.locationMode);
1216         pw.println(KEY_FORCE_ALL_APPS_STANDBY + "=" + p.forceAllAppsStandby);
1217         pw.println(KEY_FORCE_BACKGROUND_CHECK + "=" + p.forceBackgroundCheck);
1218         pw.println(KEY_DISABLE_OPTIONAL_SENSORS + "=" + p.disableOptionalSensors);
1219         pw.println(KEY_DISABLE_AOD + "=" + p.disableAod);
1220         pw.println(KEY_SOUNDTRIGGER_MODE + "=" + p.soundTriggerMode);
1221         pw.println(KEY_ENABLE_QUICK_DOZE + "=" + p.enableQuickDoze);
1222         pw.println(KEY_ENABLE_NIGHT_MODE + "=" + p.enableNightMode);
1223 
1224         // Decrease from indent right after "Policy" line
1225         pw.decreaseIndent();
1226     }
1227 
dumpMap(PrintWriter pw, ArrayMap<String, String> map)1228     private void dumpMap(PrintWriter pw, ArrayMap<String, String> map) {
1229         if (map == null || map.size() == 0) {
1230             pw.println("N/A");
1231             return;
1232         }
1233         final int size = map.size();
1234         for (int i = 0; i < size; i++) {
1235             pw.print(map.keyAt(i));
1236             pw.print(": '");
1237             pw.print(map.valueAt(i));
1238             pw.println("'");
1239         }
1240     }
1241 
1242     /**
1243      * A boolean value which should trigger a policy update when it changes.
1244      */
1245     @VisibleForTesting
1246     class PolicyBoolean {
1247         private final String mDebugName;
1248         @GuardedBy("mLock")
1249         private boolean mValue;
1250 
PolicyBoolean(String debugName)1251         private PolicyBoolean(String debugName) {
1252             mDebugName = debugName;
1253         }
1254 
1255         /** Sets the initial value without triggering a policy update. */
initialize(boolean initialValue)1256         private void initialize(boolean initialValue) {
1257             synchronized (mLock) {
1258                 mValue = initialValue;
1259             }
1260         }
1261 
get()1262         private boolean get() {
1263             synchronized (mLock) {
1264                 return mValue;
1265             }
1266         }
1267 
1268         /** Sets a value, which if different from the current value, triggers a policy update. */
1269         @VisibleForTesting
update(boolean newValue)1270         void update(boolean newValue) {
1271             synchronized (mLock) {
1272                 if (mValue != newValue) {
1273                     Slog.d(TAG, mDebugName + " changed to " + newValue + ", updating policy.");
1274                     mValue = newValue;
1275                     updatePolicyDependenciesLocked();
1276                     maybeNotifyListenersOfPolicyChange();
1277                 }
1278             }
1279         }
1280     }
1281 }
1282