BatterySaverPolicy.java revision 076218bfc0094c17f95c2e8afa4d5b2480f03f73
1a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen/*
2a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen * Copyright (C) 2017 The Android Open Source Project
3a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen *
4a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen * Licensed under the Apache License, Version 2.0 (the "License");
5a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen * you may not use this file except in compliance with the License.
6a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen * You may obtain a copy of the License at
7a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen *
8a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen *      http://www.apache.org/licenses/LICENSE-2.0
9a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen *
10a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen * Unless required by applicable law or agreed to in writing, software
11a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen * distributed under the License is distributed on an "AS IS" BASIS,
12a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen * See the License for the specific language governing permissions and
14a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen * limitations under the License.
15a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen */
16a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenpackage com.android.server.power;
17a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
18a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport android.content.ContentResolver;
19a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport android.content.Context;
20a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport android.database.ContentObserver;
21a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport android.net.Uri;
22859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohenimport android.os.Handler;
23a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport android.os.PowerManager;
24a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport android.os.PowerManager.ServiceType;
25a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport android.os.PowerSaveState;
26a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport android.provider.Settings;
27a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport android.provider.Settings.Global;
28a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport android.text.TextUtils;
29a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport android.util.ArrayMap;
30a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport android.util.KeyValueListParser;
31a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport android.util.Slog;
32a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
33a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport com.android.internal.R;
34a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport com.android.internal.annotations.GuardedBy;
35a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport com.android.internal.annotations.VisibleForTesting;
36a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport com.android.server.power.batterysaver.BatterySavingStats;
37a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport com.android.server.power.batterysaver.CpuFrequencies;
38a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
39a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport java.io.PrintWriter;
40a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport java.util.ArrayList;
41a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenimport java.util.List;
42a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
43a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen/**
44a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen * Class to decide whether to turn on battery saver mode for specific service
45a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen *
46a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen * Test:
47a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen atest ${ANDROID_BUILD_TOP}/frameworks/base/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java
48a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen */
49a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohenpublic class BatterySaverPolicy extends ContentObserver {
50a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private static final String TAG = "BatterySaverPolicy";
51a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
52a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    public static final boolean DEBUG = false; // DO NOT SUBMIT WITH TRUE.
53a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
54a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    // Secure setting for GPS behavior when battery saver mode is on.
55a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    public static final String SECURE_KEY_GPS_MODE = "batterySaverGpsMode";
56a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
57a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private static final String KEY_GPS_MODE = "gps_mode";
58a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private static final String KEY_VIBRATION_DISABLED = "vibration_disabled";
59a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private static final String KEY_ANIMATION_DISABLED = "animation_disabled";
60a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private static final String KEY_SOUNDTRIGGER_DISABLED = "soundtrigger_disabled";
61a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private static final String KEY_FIREWALL_DISABLED = "firewall_disabled";
62a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private static final String KEY_ADJUST_BRIGHTNESS_DISABLED = "adjust_brightness_disabled";
63a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private static final String KEY_DATASAVER_DISABLED = "datasaver_disabled";
64a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private static final String KEY_LAUNCH_BOOST_DISABLED = "launch_boost_disabled";
65a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private static final String KEY_ADJUST_BRIGHTNESS_FACTOR = "adjust_brightness_factor";
66a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private static final String KEY_FULLBACKUP_DEFERRED = "fullbackup_deferred";
67a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private static final String KEY_KEYVALUE_DEFERRED = "keyvaluebackup_deferred";
68a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private static final String KEY_FORCE_ALL_APPS_STANDBY = "force_all_apps_standby";
69a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private static final String KEY_FORCE_BACKGROUND_CHECK = "force_background_check";
70a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private static final String KEY_OPTIONAL_SENSORS_DISABLED = "optional_sensors_disabled";
71a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
72a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private static final String KEY_CPU_FREQ_INTERACTIVE = "cpufreq-i";
73a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private static final String KEY_CPU_FREQ_NONINTERACTIVE = "cpufreq-n";
74a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
75a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private final Object mLock = new Object();
76a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
77a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
78a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private String mSettings;
79a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
80a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
81a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private String mDeviceSpecificSettings;
82a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
83a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
84a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private String mDeviceSpecificSettingsSource; // For dump() only.
85a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
86a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    /**
87a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * A short string describing which battery saver is now enabled, which we dump in the eventlog.
88a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     */
89a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
90a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private String mEventLogKeys;
91a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
92a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    /**
93a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * {@code true} if vibration is disabled in battery saver mode.
94a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     *
95a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * @see Settings.Global#BATTERY_SAVER_CONSTANTS
96a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * @see #KEY_VIBRATION_DISABLED
97a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     */
98a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
99a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private boolean mVibrationDisabled;
100a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
101a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    /**
102a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * {@code true} if animation is disabled in battery saver mode.
103a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     *
104a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * @see Settings.Global#BATTERY_SAVER_CONSTANTS
105a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * @see #KEY_ANIMATION_DISABLED
106a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     */
107a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
108a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private boolean mAnimationDisabled;
109a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
110a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    /**
111a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * {@code true} if sound trigger is disabled in battery saver mode
112a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * in battery saver mode.
113a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     *
114a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * @see Settings.Global#BATTERY_SAVER_CONSTANTS
115a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * @see #KEY_SOUNDTRIGGER_DISABLED
116a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     */
117a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
118a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private boolean mSoundTriggerDisabled;
119859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen
120859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen    /**
121859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen     * {@code true} if full backup is deferred in battery saver mode.
122859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen     *
123859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen     * @see Settings.Global#BATTERY_SAVER_CONSTANTS
124859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen     * @see #KEY_FULLBACKUP_DEFERRED
125859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen     */
126859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen    @GuardedBy("mLock")
127859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen    private boolean mFullBackupDeferred;
128a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
129a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    /**
130859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen     * {@code true} if key value backup is deferred in battery saver mode.
131a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     *
132a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * @see Settings.Global#BATTERY_SAVER_CONSTANTS
133a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * @see #KEY_KEYVALUE_DEFERRED
134a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     */
135a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
136a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private boolean mKeyValueBackupDeferred;
137a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
138a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    /**
139859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen     * {@code true} if network policy firewall is disabled in battery saver mode.
140a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     *
141a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * @see Settings.Global#BATTERY_SAVER_CONSTANTS
142a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * @see #KEY_FIREWALL_DISABLED
143a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     */
144a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
145a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private boolean mFireWallDisabled;
146a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
147a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    /**
148a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * {@code true} if adjust brightness is disabled in battery saver mode.
149a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     *
150a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * @see Settings.Global#BATTERY_SAVER_CONSTANTS
151a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * @see #KEY_ADJUST_BRIGHTNESS_DISABLED
152a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     */
153a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
154859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen    private boolean mAdjustBrightnessDisabled;
155859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen
156a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    /**
157a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * {@code true} if data saver is disabled in battery saver mode.
158a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     *
159a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * @see Settings.Global#BATTERY_SAVER_CONSTANTS
160a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * @see #KEY_DATASAVER_DISABLED
161a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     */
162a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
163a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private boolean mDataSaverDisabled;
164c7bd5101fe7f964bbaaa74b5b6e9bb8ad876fa7cEtan Cohen
165c7bd5101fe7f964bbaaa74b5b6e9bb8ad876fa7cEtan Cohen    /**
166c7bd5101fe7f964bbaaa74b5b6e9bb8ad876fa7cEtan Cohen     * {@code true} if launch boost should be disabled on battery saver.
167c7bd5101fe7f964bbaaa74b5b6e9bb8ad876fa7cEtan Cohen     */
168c7bd5101fe7f964bbaaa74b5b6e9bb8ad876fa7cEtan Cohen    @GuardedBy("mLock")
169c7bd5101fe7f964bbaaa74b5b6e9bb8ad876fa7cEtan Cohen    private boolean mLaunchBoostDisabled;
170c7bd5101fe7f964bbaaa74b5b6e9bb8ad876fa7cEtan Cohen
171c7bd5101fe7f964bbaaa74b5b6e9bb8ad876fa7cEtan Cohen    /**
172c7bd5101fe7f964bbaaa74b5b6e9bb8ad876fa7cEtan Cohen     * This is the flag to decide the gps mode in battery saver mode.
173c7bd5101fe7f964bbaaa74b5b6e9bb8ad876fa7cEtan Cohen     *
174a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * @see Settings.Global#BATTERY_SAVER_CONSTANTS
175a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * @see #KEY_GPS_MODE
176a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     */
177a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
178a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private int mGpsMode;
179a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
180a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    /**
181a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * This is the flag to decide the how much to adjust the screen brightness. This is
182a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * the float value from 0 to 1 where 1 means don't change brightness.
183a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     *
184a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * @see Settings.Global#BATTERY_SAVER_CONSTANTS
185a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * @see #KEY_ADJUST_BRIGHTNESS_FACTOR
186a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     */
187a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
188a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private float mAdjustBrightnessFactor;
189859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen
190a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    /**
191a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * Whether to put all apps in the stand-by mode.
192a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     */
193a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
194a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private boolean mForceAllAppsStandby;
195a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
196523a425083f3045cb27cea2796a89f7488a1c5c2Etan Cohen    /**
197523a425083f3045cb27cea2796a89f7488a1c5c2Etan Cohen     * Whether to put all apps in the stand-by mode.
198523a425083f3045cb27cea2796a89f7488a1c5c2Etan Cohen     */
199a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
200a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private boolean mForceBackgroundCheck;
201a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
202a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    /**
203a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * Weather to show non-essential sensors (e.g. edge sensors) or not.
204a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     */
205a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
206a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private boolean mOptionalSensorsDisabled;
207a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
208a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
209a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private Context mContext;
210a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
211a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
212a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private ContentResolver mContentResolver;
213a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
214a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
215859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen    private final List<BatterySaverPolicyListener> mListeners = new ArrayList<>();
216a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
217a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    /**
218a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * List of [Filename -> content] that should be written when battery saver is activated
219a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * and the device is interactive.
220a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     *
221a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * We use this to change the max CPU frequencies.
222a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     */
223a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
224a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private ArrayMap<String, String> mFilesForInteractive;
225a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
226a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    /**
227a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * List of [Filename -> content] that should be written when battery saver is activated
228a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * and the device is non-interactive.
229a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     *
230a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     * We use this to change the max CPU frequencies.
231a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen     */
232a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @GuardedBy("mLock")
233a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    private ArrayMap<String, String> mFilesForNoninteractive;
234a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
235a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    public interface BatterySaverPolicyListener {
236a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen        void onBatterySaverPolicyChanged(BatterySaverPolicy policy);
237a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    }
238a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
239a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    public BatterySaverPolicy(Handler handler) {
240859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen        super(handler);
241859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen    }
242a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
243a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    public void systemReady(Context context) {
244a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen        synchronized (mLock) {
245a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen            mContext = context;
246a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen            mContentResolver = context.getContentResolver();
247a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
248a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen            mContentResolver.registerContentObserver(Settings.Global.getUriFor(
249a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen                    Settings.Global.BATTERY_SAVER_CONSTANTS), false, this);
250a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen            mContentResolver.registerContentObserver(Settings.Global.getUriFor(
251a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen                    Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS), false, this);
252a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen        }
253a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen        onChange(true, null);
254a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    }
255a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
256a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    public void addListener(BatterySaverPolicyListener listener) {
257a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen        synchronized (mLock) {
258a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen            mListeners.add(listener);
259859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen        }
260a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    }
261a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen
262a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @VisibleForTesting
263859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen    String getGlobalSetting(String key) {
264859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen        final ContentResolver cr;
265859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen        synchronized (mLock) {
266859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen            cr = mContentResolver;
267859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen        }
268859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen        return Settings.Global.getString(cr, key);
269859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen    }
270859748f08c42ddff5693c48d17bed633cbfe9cceEtan Cohen
271a5028455a4b7592091f12c80d4b4d42c9c866d66Etan Cohen    @VisibleForTesting
272    int getDeviceSpecificConfigResId() {
273        return R.string.config_batterySaverDeviceSpecificConfig;
274    }
275
276    @Override
277    public void onChange(boolean selfChange, Uri uri) {
278        final BatterySaverPolicyListener[] listeners;
279        synchronized (mLock) {
280            // Load the non-device-specific setting.
281            final String setting = getGlobalSetting(Settings.Global.BATTERY_SAVER_CONSTANTS);
282
283            // Load the device specific setting.
284            // We first check the global setting, and if it's empty or the string "null" is set,
285            // use the default value from config.xml.
286            String deviceSpecificSetting = getGlobalSetting(
287                    Settings.Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS);
288            mDeviceSpecificSettingsSource =
289                    Settings.Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS;
290
291            if (TextUtils.isEmpty(deviceSpecificSetting) || "null".equals(deviceSpecificSetting)) {
292                deviceSpecificSetting =
293                        mContext.getString(getDeviceSpecificConfigResId());
294                mDeviceSpecificSettingsSource = "(overlay)";
295            }
296
297            // Update.
298            updateConstantsLocked(setting, deviceSpecificSetting);
299
300            listeners = mListeners.toArray(new BatterySaverPolicyListener[mListeners.size()]);
301        }
302
303        // Notify the listeners.
304        for (BatterySaverPolicyListener listener : listeners) {
305            listener.onBatterySaverPolicyChanged(this);
306        }
307    }
308
309    @VisibleForTesting
310    void updateConstantsLocked(final String setting, final String deviceSpecificSetting) {
311        mSettings = setting;
312        mDeviceSpecificSettings = deviceSpecificSetting;
313
314        if (DEBUG) {
315            Slog.i(TAG, "mSettings=" + mSettings);
316            Slog.i(TAG, "mDeviceSpecificSettings=" + mDeviceSpecificSettings);
317        }
318
319        final KeyValueListParser parser = new KeyValueListParser(',');
320
321        // Non-device-specific parameters.
322        try {
323            parser.setString(setting);
324        } catch (IllegalArgumentException e) {
325            Slog.wtf(TAG, "Bad battery saver constants: " + setting);
326        }
327
328        mVibrationDisabled = parser.getBoolean(KEY_VIBRATION_DISABLED, true);
329        mAnimationDisabled = parser.getBoolean(KEY_ANIMATION_DISABLED, false);
330        mSoundTriggerDisabled = parser.getBoolean(KEY_SOUNDTRIGGER_DISABLED, true);
331        mFullBackupDeferred = parser.getBoolean(KEY_FULLBACKUP_DEFERRED, true);
332        mKeyValueBackupDeferred = parser.getBoolean(KEY_KEYVALUE_DEFERRED, true);
333        mFireWallDisabled = parser.getBoolean(KEY_FIREWALL_DISABLED, false);
334        mAdjustBrightnessDisabled = parser.getBoolean(KEY_ADJUST_BRIGHTNESS_DISABLED, true);
335        mAdjustBrightnessFactor = parser.getFloat(KEY_ADJUST_BRIGHTNESS_FACTOR, 0.5f);
336        mDataSaverDisabled = parser.getBoolean(KEY_DATASAVER_DISABLED, true);
337        mLaunchBoostDisabled = parser.getBoolean(KEY_LAUNCH_BOOST_DISABLED, true);
338        mForceAllAppsStandby = parser.getBoolean(KEY_FORCE_ALL_APPS_STANDBY, true);
339        mForceBackgroundCheck = parser.getBoolean(KEY_FORCE_BACKGROUND_CHECK, true);
340        mOptionalSensorsDisabled = parser.getBoolean(KEY_OPTIONAL_SENSORS_DISABLED, true);
341
342        // Get default value from Settings.Secure
343        final int defaultGpsMode = Settings.Secure.getInt(mContentResolver, SECURE_KEY_GPS_MODE,
344                PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF);
345        mGpsMode = parser.getInt(KEY_GPS_MODE, defaultGpsMode);
346
347        // Non-device-specific parameters.
348        try {
349            parser.setString(deviceSpecificSetting);
350        } catch (IllegalArgumentException e) {
351            Slog.wtf(TAG, "Bad device specific battery saver constants: "
352                    + deviceSpecificSetting);
353        }
354
355        mFilesForInteractive = (new CpuFrequencies()).parseString(
356                parser.getString(KEY_CPU_FREQ_INTERACTIVE, "")).toSysFileMap();
357
358        mFilesForNoninteractive = (new CpuFrequencies()).parseString(
359                parser.getString(KEY_CPU_FREQ_NONINTERACTIVE, "")).toSysFileMap();
360
361        final StringBuilder sb = new StringBuilder();
362
363        if (mForceAllAppsStandby) sb.append("A");
364        if (mForceBackgroundCheck) sb.append("B");
365
366        if (mVibrationDisabled) sb.append("v");
367        if (mAnimationDisabled) sb.append("a");
368        if (mSoundTriggerDisabled) sb.append("s");
369        if (mFullBackupDeferred) sb.append("F");
370        if (mKeyValueBackupDeferred) sb.append("K");
371        if (!mFireWallDisabled) sb.append("f");
372        if (!mDataSaverDisabled) sb.append("d");
373        if (!mAdjustBrightnessDisabled) sb.append("b");
374
375        if (mLaunchBoostDisabled) sb.append("l");
376        if (mOptionalSensorsDisabled) sb.append("S");
377
378        sb.append(mGpsMode);
379
380        mEventLogKeys = sb.toString();
381    }
382
383    /**
384     * Get the {@link PowerSaveState} based on {@paramref type} and {@paramref realMode}.
385     * The result will have {@link PowerSaveState#batterySaverEnabled} and some other
386     * parameters when necessary.
387     *
388     * @param type     type of the service, one of {@link ServiceType}
389     * @param realMode whether the battery saver is on by default
390     * @return State data that contains battery saver data
391     */
392    public PowerSaveState getBatterySaverPolicy(@ServiceType int type, boolean realMode) {
393        synchronized (mLock) {
394            final PowerSaveState.Builder builder = new PowerSaveState.Builder()
395                    .setGlobalBatterySaverEnabled(realMode);
396            if (!realMode) {
397                return builder.setBatterySaverEnabled(realMode)
398                        .build();
399            }
400            switch (type) {
401                case ServiceType.GPS:
402                    return builder.setBatterySaverEnabled(realMode)
403                            .setGpsMode(mGpsMode)
404                            .build();
405                case ServiceType.ANIMATION:
406                    return builder.setBatterySaverEnabled(mAnimationDisabled)
407                            .build();
408                case ServiceType.FULL_BACKUP:
409                    return builder.setBatterySaverEnabled(mFullBackupDeferred)
410                            .build();
411                case ServiceType.KEYVALUE_BACKUP:
412                    return builder.setBatterySaverEnabled(mKeyValueBackupDeferred)
413                            .build();
414                case ServiceType.NETWORK_FIREWALL:
415                    return builder.setBatterySaverEnabled(!mFireWallDisabled)
416                            .build();
417                case ServiceType.SCREEN_BRIGHTNESS:
418                    return builder.setBatterySaverEnabled(!mAdjustBrightnessDisabled)
419                            .setBrightnessFactor(mAdjustBrightnessFactor)
420                            .build();
421                case ServiceType.DATA_SAVER:
422                    return builder.setBatterySaverEnabled(!mDataSaverDisabled)
423                            .build();
424                case ServiceType.SOUND:
425                    return builder.setBatterySaverEnabled(mSoundTriggerDisabled)
426                            .build();
427                case ServiceType.VIBRATION:
428                    return builder.setBatterySaverEnabled(mVibrationDisabled)
429                            .build();
430                case ServiceType.FORCE_ALL_APPS_STANDBY:
431                    return builder.setBatterySaverEnabled(mForceAllAppsStandby)
432                            .build();
433                case ServiceType.FORCE_BACKGROUND_CHECK:
434                    return builder.setBatterySaverEnabled(mForceBackgroundCheck)
435                            .build();
436                case ServiceType.OPTIONAL_SENSORS:
437                    return builder.setBatterySaverEnabled(mOptionalSensorsDisabled)
438                            .build();
439                default:
440                    return builder.setBatterySaverEnabled(realMode)
441                            .build();
442            }
443        }
444    }
445
446    public int getGpsMode() {
447        synchronized (mLock) {
448            return mGpsMode;
449        }
450    }
451
452    public ArrayMap<String, String> getFileValues(boolean interactive) {
453        synchronized (mLock) {
454            return interactive ? mFilesForInteractive : mFilesForNoninteractive;
455        }
456    }
457
458    public boolean isLaunchBoostDisabled() {
459        synchronized (mLock) {
460            return mLaunchBoostDisabled;
461        }
462    }
463
464    public String toEventLogString() {
465        synchronized (mLock) {
466            return mEventLogKeys;
467        }
468    }
469
470    public void dump(PrintWriter pw) {
471        synchronized (mLock) {
472            pw.println();
473            pw.println("Battery saver policy");
474            pw.println("  Settings: " + Settings.Global.BATTERY_SAVER_CONSTANTS);
475            pw.println("    value: " + mSettings);
476            pw.println("  Settings: " + mDeviceSpecificSettingsSource);
477            pw.println("    value: " + mDeviceSpecificSettings);
478
479            pw.println();
480            pw.println("  " + KEY_VIBRATION_DISABLED + "=" + mVibrationDisabled);
481            pw.println("  " + KEY_ANIMATION_DISABLED + "=" + mAnimationDisabled);
482            pw.println("  " + KEY_FULLBACKUP_DEFERRED + "=" + mFullBackupDeferred);
483            pw.println("  " + KEY_KEYVALUE_DEFERRED + "=" + mKeyValueBackupDeferred);
484            pw.println("  " + KEY_FIREWALL_DISABLED + "=" + mFireWallDisabled);
485            pw.println("  " + KEY_DATASAVER_DISABLED + "=" + mDataSaverDisabled);
486            pw.println("  " + KEY_LAUNCH_BOOST_DISABLED + "=" + mLaunchBoostDisabled);
487            pw.println("  " + KEY_ADJUST_BRIGHTNESS_DISABLED + "=" + mAdjustBrightnessDisabled);
488            pw.println("  " + KEY_ADJUST_BRIGHTNESS_FACTOR + "=" + mAdjustBrightnessFactor);
489            pw.println("  " + KEY_GPS_MODE + "=" + mGpsMode);
490            pw.println("  " + KEY_FORCE_ALL_APPS_STANDBY + "=" + mForceAllAppsStandby);
491            pw.println("  " + KEY_FORCE_BACKGROUND_CHECK + "=" + mForceBackgroundCheck);
492            pw.println("  " + KEY_OPTIONAL_SENSORS_DISABLED + "=" + mOptionalSensorsDisabled);
493            pw.println();
494
495            pw.print("  Interactive File values:\n");
496            dumpMap(pw, "    ", mFilesForInteractive);
497            pw.println();
498
499            pw.print("  Noninteractive File values:\n");
500            dumpMap(pw, "    ", mFilesForNoninteractive);
501            pw.println();
502            pw.println();
503            BatterySavingStats.getInstance().dump(pw, "  ");
504        }
505    }
506
507    private void dumpMap(PrintWriter pw, String prefix, ArrayMap<String, String> map) {
508        if (map == null) {
509            return;
510        }
511        final int size = map.size();
512        for (int i = 0; i < size; i++) {
513            pw.print(prefix);
514            pw.print(map.keyAt(i));
515            pw.print(": '");
516            pw.print(map.valueAt(i));
517            pw.println("'");
518        }
519    }
520}
521