blob: 3ab3c349c57b737c136969531722ed74b59a202e [file] [log] [blame]
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001/*
2 * Copyright (C) 2015 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
17package com.android.server;
18
Amith Yamasaniaf575b92015-05-29 15:35:26 -070019import android.Manifest;
Sudheer Shankadc589ac2016-11-10 15:30:17 -080020import android.app.ActivityManager;
Dianne Hackborn85e35642017-01-12 15:10:57 -080021import android.app.ActivityManagerInternal;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070022import android.app.AlarmManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070023import android.content.BroadcastReceiver;
Adam Lesinski31c05d12015-06-09 17:34:04 -070024import android.content.ContentResolver;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070025import android.content.Context;
26import android.content.Intent;
27import android.content.IntentFilter;
28import android.content.pm.ApplicationInfo;
29import android.content.pm.PackageManager;
Amith Yamasaniaf575b92015-05-29 15:35:26 -070030import android.content.pm.PackageManager.NameNotFoundException;
Adam Lesinski31c05d12015-06-09 17:34:04 -070031import android.database.ContentObserver;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070032import android.hardware.Sensor;
Nick Vaccaro20feaea2015-09-17 17:22:44 -070033import android.hardware.SensorEvent;
34import android.hardware.SensorEventListener;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070035import android.hardware.SensorManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070036import android.hardware.TriggerEvent;
37import android.hardware.TriggerEventListener;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -070038import android.location.Location;
39import android.location.LocationListener;
40import android.location.LocationManager;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070041import android.location.LocationRequest;
Dianne Hackborn88c41352016-04-07 15:18:58 -070042import android.net.ConnectivityManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070043import android.net.INetworkPolicyManager;
Dianne Hackborn88c41352016-04-07 15:18:58 -070044import android.net.NetworkInfo;
Adam Lesinski31c05d12015-06-09 17:34:04 -070045import android.net.Uri;
Robin Lee204cb222018-12-07 15:17:44 +010046import android.os.BatteryManager;
Dianne Hackbornfd854ee2015-07-13 18:00:37 -070047import android.os.BatteryStats;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070048import android.os.Binder;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -070049import android.os.Bundle;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070050import android.os.Environment;
51import android.os.FileUtils;
52import android.os.Handler;
53import android.os.IDeviceIdleController;
Yao Chenca5edbb2016-01-13 14:44:36 -080054import android.os.IMaintenanceActivityListener;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070055import android.os.Looper;
56import android.os.Message;
57import android.os.PowerManager;
Kweku Adamsb396ccf2018-09-17 16:37:15 -070058import android.os.PowerManager.ServiceType;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070059import android.os.PowerManagerInternal;
Dianne Hackbornb6683c42015-06-18 17:40:33 -070060import android.os.Process;
Yao Chenca5edbb2016-01-13 14:44:36 -080061import android.os.RemoteCallbackList;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070062import android.os.RemoteException;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070063import android.os.ResultReceiver;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070064import android.os.ServiceManager;
Dianne Hackborn354736e2016-08-22 17:00:05 -070065import android.os.ShellCallback;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070066import android.os.ShellCommand;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070067import android.os.SystemClock;
68import android.os.UserHandle;
Adam Lesinski31c05d12015-06-09 17:34:04 -070069import android.provider.Settings;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070070import android.util.ArrayMap;
71import android.util.ArraySet;
Adam Lesinski31c05d12015-06-09 17:34:04 -070072import android.util.KeyValueListParser;
Dianne Hackbornfd854ee2015-07-13 18:00:37 -070073import android.util.MutableLong;
74import android.util.Pair;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070075import android.util.Slog;
Dianne Hackbornfd854ee2015-07-13 18:00:37 -070076import android.util.SparseArray;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070077import android.util.SparseBooleanArray;
78import android.util.TimeUtils;
79import android.util.Xml;
Amith Yamasani520d8f22015-05-08 16:36:21 -070080
Sudheer Shanka326b3112017-11-27 14:40:57 -080081import com.android.internal.annotations.GuardedBy;
Kweku Adams00e3a372018-09-28 16:57:09 -070082import com.android.internal.annotations.VisibleForTesting;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070083import com.android.internal.app.IBatteryStats;
84import com.android.internal.os.AtomicFile;
85import com.android.internal.os.BackgroundThread;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060086import com.android.internal.util.DumpUtils;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070087import com.android.internal.util.FastXmlSerializer;
88import com.android.internal.util.XmlUtils;
89import com.android.server.am.BatteryStatsService;
Robin Lee876b88542018-11-13 17:22:24 +010090import com.android.server.deviceidle.ConstraintController;
91import com.android.server.deviceidle.DeviceIdleConstraintTracker;
92import com.android.server.deviceidle.IDeviceIdleConstraint;
93import com.android.server.deviceidle.TvConstraintController;
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -070094import com.android.server.net.NetworkPolicyManagerInternal;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070095import com.android.server.wm.ActivityTaskManagerInternal;
Amith Yamasani520d8f22015-05-08 16:36:21 -070096
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070097import org.xmlpull.v1.XmlPullParser;
98import org.xmlpull.v1.XmlPullParserException;
99import org.xmlpull.v1.XmlSerializer;
100
101import java.io.ByteArrayOutputStream;
102import java.io.File;
103import java.io.FileDescriptor;
104import java.io.FileInputStream;
105import java.io.FileNotFoundException;
106import java.io.FileOutputStream;
107import java.io.IOException;
108import java.io.PrintWriter;
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +0100109import java.nio.charset.StandardCharsets;
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700110import java.util.Arrays;
Robin Lee876b88542018-11-13 17:22:24 +0100111import java.util.stream.Collectors;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700112
113/**
114 * Keeps track of device idleness and drives low power mode based on that.
Kweku Adams00e3a372018-09-28 16:57:09 -0700115 *
116 * Test: atest com.android.server.DeviceIdleControllerTest
Kweku Adamsf596cfc2018-10-04 15:15:22 -0700117 *
118 * Current idling state machine (as of Android 9 Pie). This can be visualized using Graphviz:
119
120 digraph {
121 subgraph deep {
122 label="deep";
123
124 STATE_ACTIVE [label="STATE_ACTIVE\nScreen on OR Charging OR Alarm going off soon"]
125 STATE_INACTIVE [label="STATE_INACTIVE\nScreen off AND Not charging"]
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700126 STATE_QUICK_DOZE_DELAY [
127 label="STATE_QUICK_DOZE_DELAY\n"
128 + "Screen off AND Not charging\n"
129 + "Location, motion detection, and significant motion monitoring turned off"
130 ]
Kweku Adamsf596cfc2018-10-04 15:15:22 -0700131 STATE_IDLE_PENDING [
132 label="STATE_IDLE_PENDING\nSignificant motion monitoring turned on"
133 ]
134 STATE_SENSING [label="STATE_SENSING\nMonitoring for ANY motion"]
135 STATE_LOCATING [
136 label="STATE_LOCATING\nRequesting location, motion monitoring still on"
137 ]
138 STATE_IDLE [
139 label="STATE_IDLE\nLocation and motion detection turned off\n"
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700140 + "Significant motion monitoring state unchanged"
Kweku Adamsf596cfc2018-10-04 15:15:22 -0700141 ]
142 STATE_IDLE_MAINTENANCE [label="STATE_IDLE_MAINTENANCE\n"]
143
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700144 STATE_ACTIVE -> STATE_INACTIVE [
145 label="becomeInactiveIfAppropriateLocked() AND Quick Doze not enabled"
146 ]
147 STATE_ACTIVE -> STATE_QUICK_DOZE_DELAY [
148 label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled"
149 ]
Kweku Adamsf596cfc2018-10-04 15:15:22 -0700150
151 STATE_INACTIVE -> STATE_ACTIVE [
152 label="handleMotionDetectedLocked(), becomeActiveLocked()"
153 ]
154 STATE_INACTIVE -> STATE_IDLE_PENDING [label="stepIdleStateLocked()"]
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700155 STATE_INACTIVE -> STATE_QUICK_DOZE_DELAY [
156 label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled"
157 ]
Kweku Adamsf596cfc2018-10-04 15:15:22 -0700158
159 STATE_IDLE_PENDING -> STATE_ACTIVE [
160 label="handleMotionDetectedLocked(), becomeActiveLocked()"
161 ]
162 STATE_IDLE_PENDING -> STATE_SENSING [label="stepIdleStateLocked()"]
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700163 STATE_IDLE_PENDING -> STATE_QUICK_DOZE_DELAY [
164 label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled"
165 ]
Kweku Adamsf596cfc2018-10-04 15:15:22 -0700166
167 STATE_SENSING -> STATE_ACTIVE [
168 label="handleMotionDetectedLocked(), becomeActiveLocked()"
169 ]
170 STATE_SENSING -> STATE_LOCATING [label="stepIdleStateLocked()"]
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700171 STATE_SENSING -> STATE_QUICK_DOZE_DELAY [
172 label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled"
173 ]
Kweku Adamsf596cfc2018-10-04 15:15:22 -0700174 STATE_SENSING -> STATE_IDLE [
175 label="stepIdleStateLocked()\n"
176 + "No Location Manager OR (no Network provider AND no GPS provider)"
177 ]
178
179 STATE_LOCATING -> STATE_ACTIVE [
180 label="handleMotionDetectedLocked(), becomeActiveLocked()"
181 ]
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700182 STATE_LOCATING -> STATE_QUICK_DOZE_DELAY [
183 label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled"
184 ]
Kweku Adamsf596cfc2018-10-04 15:15:22 -0700185 STATE_LOCATING -> STATE_IDLE [label="stepIdleStateLocked()"]
186
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700187 STATE_QUICK_DOZE_DELAY -> STATE_ACTIVE [
188 label="handleMotionDetectedLocked(), becomeActiveLocked()"
189 ]
190 STATE_QUICK_DOZE_DELAY -> STATE_IDLE [label="stepIdleStateLocked()"]
191
Kweku Adamsf596cfc2018-10-04 15:15:22 -0700192 STATE_IDLE -> STATE_ACTIVE [label="handleMotionDetectedLocked(), becomeActiveLocked()"]
193 STATE_IDLE -> STATE_IDLE_MAINTENANCE [label="stepIdleStateLocked()"]
194
195 STATE_IDLE_MAINTENANCE -> STATE_ACTIVE [
196 label="handleMotionDetectedLocked(), becomeActiveLocked()"
197 ]
198 STATE_IDLE_MAINTENANCE -> STATE_IDLE [
199 label="stepIdleStateLocked(), exitMaintenanceEarlyIfNeededLocked()"
200 ]
201 }
202
203 subgraph light {
204 label="light"
205
206 LIGHT_STATE_ACTIVE [
207 label="LIGHT_STATE_ACTIVE\nScreen on OR Charging OR Alarm going off soon"
208 ]
209 LIGHT_STATE_INACTIVE [label="LIGHT_STATE_INACTIVE\nScreen off AND Not charging"]
210 LIGHT_STATE_PRE_IDLE [
211 label="LIGHT_STATE_PRE_IDLE\n"
212 + "Delay going into LIGHT_STATE_IDLE due to some running jobs or alarms"
213 ]
214 LIGHT_STATE_IDLE [label="LIGHT_STATE_IDLE\n"]
215 LIGHT_STATE_WAITING_FOR_NETWORK [
216 label="LIGHT_STATE_WAITING_FOR_NETWORK\n"
217 + "Coming out of LIGHT_STATE_IDLE, waiting for network"
218 ]
219 LIGHT_STATE_IDLE_MAINTENANCE [label="LIGHT_STATE_IDLE_MAINTENANCE\n"]
220 LIGHT_STATE_OVERRIDE [
221 label="LIGHT_STATE_OVERRIDE\nDevice in deep doze, light no longer changing states"
222 ]
223
224 LIGHT_STATE_ACTIVE -> LIGHT_STATE_INACTIVE [
225 label="becomeInactiveIfAppropriateLocked()"
226 ]
227 LIGHT_STATE_ACTIVE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"]
228
229 LIGHT_STATE_INACTIVE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"]
230 LIGHT_STATE_INACTIVE -> LIGHT_STATE_PRE_IDLE [label="active jobs"]
231 LIGHT_STATE_INACTIVE -> LIGHT_STATE_IDLE [label="no active jobs"]
232 LIGHT_STATE_INACTIVE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"]
233
234 LIGHT_STATE_PRE_IDLE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"]
235 LIGHT_STATE_PRE_IDLE -> LIGHT_STATE_IDLE [
236 label="stepLightIdleStateLocked(), exitMaintenanceEarlyIfNeededLocked()"
237 ]
238 LIGHT_STATE_PRE_IDLE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"]
239
240 LIGHT_STATE_IDLE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"]
241 LIGHT_STATE_IDLE -> LIGHT_STATE_WAITING_FOR_NETWORK [label="no network"]
242 LIGHT_STATE_IDLE -> LIGHT_STATE_IDLE_MAINTENANCE
243 LIGHT_STATE_IDLE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"]
244
245 LIGHT_STATE_WAITING_FOR_NETWORK -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"]
246 LIGHT_STATE_WAITING_FOR_NETWORK -> LIGHT_STATE_IDLE_MAINTENANCE
247 LIGHT_STATE_WAITING_FOR_NETWORK -> LIGHT_STATE_OVERRIDE [
248 label="deep goes to STATE_IDLE"
249 ]
250
251 LIGHT_STATE_IDLE_MAINTENANCE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"]
252 LIGHT_STATE_IDLE_MAINTENANCE -> LIGHT_STATE_IDLE [
253 label="stepLightIdleStateLocked(), exitMaintenanceEarlyIfNeededLocked()"
254 ]
255 LIGHT_STATE_IDLE_MAINTENANCE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"]
256
257 LIGHT_STATE_OVERRIDE -> LIGHT_STATE_ACTIVE [
258 label="handleMotionDetectedLocked(), becomeActiveLocked()"
259 ]
260 }
261 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700262 */
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700263public class DeviceIdleController extends SystemService
264 implements AnyMotionDetector.DeviceIdleCallback {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700265 private static final String TAG = "DeviceIdleController";
266
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700267 private static final boolean DEBUG = false;
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700268
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700269 private static final boolean COMPRESS_TIME = false;
Amith Yamasani520d8f22015-05-08 16:36:21 -0700270
Dianne Hackborn953fc942016-03-29 15:36:24 -0700271 private static final int EVENT_BUFFER_SIZE = 100;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800272
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700273 private AlarmManager mAlarmManager;
Kweku Adamsb7ce1902019-01-30 10:55:34 -0800274 private AlarmManagerInternal mLocalAlarmManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700275 private IBatteryStats mBatteryStats;
Dianne Hackborn85e35642017-01-12 15:10:57 -0800276 private ActivityManagerInternal mLocalActivityManager;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700277 private ActivityTaskManagerInternal mLocalActivityTaskManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700278 private PowerManagerInternal mLocalPowerManager;
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700279 private PowerManager mPowerManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700280 private INetworkPolicyManager mNetworkPolicyManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700281 private SensorManager mSensorManager;
Robin Leec4d424c2018-12-07 15:09:13 +0100282 private final boolean mUseMotionSensor;
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700283 private Sensor mMotionSensor;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700284 private LocationRequest mLocationRequest;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700285 private Intent mIdleIntent;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700286 private Intent mLightIdleIntent;
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700287 private AnyMotionDetector mAnyMotionDetector;
Makoto Onukie4918212018-02-06 11:30:15 -0800288 private final AppStateTracker mAppStateTracker;
Dianne Hackbornb6843652016-02-22 12:20:13 -0800289 private boolean mLightEnabled;
290 private boolean mDeepEnabled;
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700291 private boolean mQuickDozeActivated;
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700292 private boolean mForceIdle;
Dianne Hackborn88c41352016-04-07 15:18:58 -0700293 private boolean mNetworkConnected;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700294 private boolean mScreenOn;
295 private boolean mCharging;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700296 private boolean mNotMoving;
297 private boolean mLocating;
298 private boolean mLocated;
Joe LaPenna23d681b2015-08-27 15:12:11 -0700299 private boolean mHasGps;
300 private boolean mHasNetworkLocation;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700301 private Location mLastGenericLocation;
302 private Location mLastGpsLocation;
Amith Yamasani396a10c2018-01-19 10:58:07 -0800303 // Current locked state of the screen
304 private boolean mScreenLocked;
Robin Lee876b88542018-11-13 17:22:24 +0100305 private int mNumBlockingConstraints = 0;
306
307 /**
308 * Constraints are the "handbrakes" that stop the device from moving into a lower state until
309 * every one is released at the same time.
310 *
311 * @see #registerDeviceIdleConstraintInternal(IDeviceIdleConstraint, String, int)
312 */
313 private final ArrayMap<IDeviceIdleConstraint, DeviceIdleConstraintTracker>
314 mConstraints = new ArrayMap<>();
315 private ConstraintController mConstraintController;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700316
317 /** Device is currently active. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700318 @VisibleForTesting
319 static final int STATE_ACTIVE = 0;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700320 /** Device is inactive (screen off, no motion) and we are waiting to for idle. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700321 @VisibleForTesting
322 static final int STATE_INACTIVE = 1;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700323 /** Device is past the initial inactive period, and waiting for the next idle period. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700324 @VisibleForTesting
325 static final int STATE_IDLE_PENDING = 2;
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700326 /** Device is currently sensing motion. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700327 @VisibleForTesting
328 static final int STATE_SENSING = 3;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700329 /** Device is currently finding location (and may still be sensing). */
Kweku Adams00e3a372018-09-28 16:57:09 -0700330 @VisibleForTesting
331 static final int STATE_LOCATING = 4;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700332 /** Device is in the idle state, trying to stay asleep as much as possible. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700333 @VisibleForTesting
334 static final int STATE_IDLE = 5;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700335 /** Device is in the idle state, but temporarily out of idle to do regular maintenance. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700336 @VisibleForTesting
337 static final int STATE_IDLE_MAINTENANCE = 6;
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700338 /**
339 * Device is inactive and should go straight into idle (foregoing motion and location
340 * monitoring), but allow some time for current work to complete first.
341 */
342 @VisibleForTesting
343 static final int STATE_QUICK_DOZE_DELAY = 7;
Amith Yamasani396a10c2018-01-19 10:58:07 -0800344
Denny cy Leec5a7c292019-01-01 17:37:55 +0800345 private static final int ACTIVE_REASON_UNKNOWN = 0;
346 private static final int ACTIVE_REASON_MOTION = 1;
347 private static final int ACTIVE_REASON_SCREEN = 2;
348 private static final int ACTIVE_REASON_CHARGING = 3;
349 private static final int ACTIVE_REASON_UNLOCKED = 4;
350 private static final int ACTIVE_REASON_FROM_BINDER_CALL = 5;
351 private static final int ACTIVE_REASON_FORCED = 6;
352 private static final int ACTIVE_REASON_ALARM = 7;
353 @VisibleForTesting
354 static final int SET_IDLE_FACTOR_RESULT_UNINIT = -1;
355 @VisibleForTesting
356 static final int SET_IDLE_FACTOR_RESULT_IGNORED = 0;
357 @VisibleForTesting
358 static final int SET_IDLE_FACTOR_RESULT_OK = 1;
359 @VisibleForTesting
360 static final int SET_IDLE_FACTOR_RESULT_NOT_SUPPORT = 2;
361 @VisibleForTesting
362 static final int SET_IDLE_FACTOR_RESULT_INVALID = 3;
363 @VisibleForTesting
364 static final long MIN_STATE_STEP_ALARM_CHANGE = 60 * 1000;
365 @VisibleForTesting
366 static final float MIN_PRE_IDLE_FACTOR_CHANGE = 0.05f;
367
Kweku Adams00e3a372018-09-28 16:57:09 -0700368 @VisibleForTesting
369 static String stateToString(int state) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700370 switch (state) {
371 case STATE_ACTIVE: return "ACTIVE";
372 case STATE_INACTIVE: return "INACTIVE";
373 case STATE_IDLE_PENDING: return "IDLE_PENDING";
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700374 case STATE_SENSING: return "SENSING";
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700375 case STATE_LOCATING: return "LOCATING";
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700376 case STATE_IDLE: return "IDLE";
377 case STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE";
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700378 case STATE_QUICK_DOZE_DELAY: return "QUICK_DOZE_DELAY";
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700379 default: return Integer.toString(state);
380 }
381 }
382
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700383 /** Device is currently active. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700384 @VisibleForTesting
385 static final int LIGHT_STATE_ACTIVE = 0;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700386 /** Device is inactive (screen off) and we are waiting to for the first light idle. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700387 @VisibleForTesting
388 static final int LIGHT_STATE_INACTIVE = 1;
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700389 /** Device is about to go idle for the first time, wait for current work to complete. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700390 @VisibleForTesting
391 static final int LIGHT_STATE_PRE_IDLE = 3;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700392 /** Device is in the light idle state, trying to stay asleep as much as possible. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700393 @VisibleForTesting
394 static final int LIGHT_STATE_IDLE = 4;
Dianne Hackborn88c41352016-04-07 15:18:58 -0700395 /** Device is in the light idle state, we want to go in to idle maintenance but are
396 * waiting for network connectivity before doing so. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700397 @VisibleForTesting
398 static final int LIGHT_STATE_WAITING_FOR_NETWORK = 5;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700399 /** Device is in the light idle state, but temporarily out of idle to do regular maintenance. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700400 @VisibleForTesting
401 static final int LIGHT_STATE_IDLE_MAINTENANCE = 6;
Dianne Hackbornb6843652016-02-22 12:20:13 -0800402 /** Device light idle state is overriden, now applying deep doze state. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700403 @VisibleForTesting
404 static final int LIGHT_STATE_OVERRIDE = 7;
405
406 @VisibleForTesting
407 static String lightStateToString(int state) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700408 switch (state) {
409 case LIGHT_STATE_ACTIVE: return "ACTIVE";
410 case LIGHT_STATE_INACTIVE: return "INACTIVE";
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700411 case LIGHT_STATE_PRE_IDLE: return "PRE_IDLE";
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700412 case LIGHT_STATE_IDLE: return "IDLE";
Dianne Hackborn88c41352016-04-07 15:18:58 -0700413 case LIGHT_STATE_WAITING_FOR_NETWORK: return "WAITING_FOR_NETWORK";
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700414 case LIGHT_STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE";
415 case LIGHT_STATE_OVERRIDE: return "OVERRIDE";
416 default: return Integer.toString(state);
417 }
418 }
419
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700420 private int mState;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700421 private int mLightState;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700422
423 private long mInactiveTimeout;
424 private long mNextAlarmTime;
425 private long mNextIdlePendingDelay;
426 private long mNextIdleDelay;
Dianne Hackborn953fc942016-03-29 15:36:24 -0700427 private long mNextLightIdleDelay;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700428 private long mNextLightAlarmTime;
Kevin Gabayan92f15e62016-04-04 17:52:22 -0700429 private long mNextSensingTimeoutAlarmTime;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800430 private long mCurIdleBudget;
431 private long mMaintenanceStartTime;
Denny cy Leec5a7c292019-01-01 17:37:55 +0800432 private long mIdleStartTime;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700433
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800434 private int mActiveIdleOpCount;
Joe Onorato8f0e9ced2016-12-08 17:48:49 -0800435 private PowerManager.WakeLock mActiveIdleWakeLock; // held when there are operations in progress
436 private PowerManager.WakeLock mGoingIdleWakeLock; // held when we are going idle so hardware
437 // (especially NetworkPolicyManager) can shut
438 // down.
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800439 private boolean mJobsActive;
440 private boolean mAlarmsActive;
Yao Chenca5edbb2016-01-13 14:44:36 -0800441 private boolean mReportedMaintenanceActivity;
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800442
Denny cy Leec5a7c292019-01-01 17:37:55 +0800443 /* Factor to apply to INACTIVE_TIMEOUT and IDLE_AFTER_INACTIVE_TIMEOUT in order to enter
444 * STATE_IDLE faster or slower. Don't apply this to SENSING_TIMEOUT or LOCATING_TIMEOUT because:
445 * - Both of them are shorter
446 * - Device sensor might take time be to become be stabilized
447 * Also don't apply the factor if the device is in motion because device motion provides a
448 * stronger signal than a prediction algorithm.
449 */
450 private float mPreIdleFactor;
451 private float mLastPreIdleFactor;
452 private int mActiveReason;
453
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700454 public final AtomicFile mConfigFile;
455
Yao Chenca5edbb2016-01-13 14:44:36 -0800456 private final RemoteCallbackList<IMaintenanceActivityListener> mMaintenanceActivityListeners =
457 new RemoteCallbackList<IMaintenanceActivityListener>();
458
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700459 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700460 * Package names the system has white-listed to opt out of power save restrictions,
461 * except for device idle mode.
462 */
463 private final ArrayMap<String, Integer> mPowerSaveWhitelistAppsExceptIdle = new ArrayMap<>();
464
465 /**
Sudheer Shanka3f4d7702017-04-28 17:38:03 -0700466 * Package names the user has white-listed using commandline option to opt out of
467 * power save restrictions, except for device idle mode.
468 */
469 private final ArraySet<String> mPowerSaveWhitelistUserAppsExceptIdle = new ArraySet<>();
470
471 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700472 * Package names the system has white-listed to opt out of power save restrictions for
473 * all modes.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700474 */
475 private final ArrayMap<String, Integer> mPowerSaveWhitelistApps = new ArrayMap<>();
476
477 /**
478 * Package names the user has white-listed to opt out of power save restrictions.
479 */
480 private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>();
481
482 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700483 * App IDs of built-in system apps that have been white-listed except for idle modes.
484 */
485 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIdsExceptIdle
486 = new SparseBooleanArray();
487
488 /**
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700489 * App IDs of built-in system apps that have been white-listed.
490 */
491 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray();
492
493 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700494 * App IDs that have been white-listed to opt out of power save restrictions, except
495 * for device idle modes.
496 */
497 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
498
499 /**
500 * Current app IDs that are in the complete power save white list, but shouldn't be
501 * excluded from idle modes. This array can be shared with others because it will not be
502 * modified once set.
503 */
504 private int[] mPowerSaveWhitelistExceptIdleAppIdArray = new int[0];
505
506 /**
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700507 * App IDs that have been white-listed to opt out of power save restrictions.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700508 */
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700509 private final SparseBooleanArray mPowerSaveWhitelistAllAppIds = new SparseBooleanArray();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700510
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700511 /**
512 * Current app IDs that are in the complete power save white list. This array can
513 * be shared with others because it will not be modified once set.
514 */
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700515 private int[] mPowerSaveWhitelistAllAppIdArray = new int[0];
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700516
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700517 /**
Dianne Hackborn262ae5c2016-02-10 16:28:29 -0800518 * App IDs that have been white-listed by the user to opt out of power save restrictions.
519 */
520 private final SparseBooleanArray mPowerSaveWhitelistUserAppIds = new SparseBooleanArray();
521
522 /**
523 * Current app IDs that are in the user power save white list. This array can
524 * be shared with others because it will not be modified once set.
525 */
526 private int[] mPowerSaveWhitelistUserAppIdArray = new int[0];
527
528 /**
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700529 * List of end times for UIDs that are temporarily marked as being allowed to access
530 * the network and acquire wakelocks. Times are in milliseconds.
531 */
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700532 private final SparseArray<Pair<MutableLong, String>> mTempWhitelistAppIdEndTimes
533 = new SparseArray<>();
534
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -0700535 private NetworkPolicyManagerInternal mNetworkPolicyManagerInternal;
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700536
537 /**
538 * Current app IDs of temporarily whitelist apps for high-priority messages.
539 */
540 private int[] mTempWhitelistAppIdArray = new int[0];
541
Suprabh Shukla08105642017-09-26 14:45:30 -0700542 /**
543 * Apps in the system whitelist that have been taken out (probably because the user wanted to).
544 * They can be restored back by calling restoreAppToSystemWhitelist(String).
545 */
546 private ArrayMap<String, Integer> mRemovedFromSystemWhitelistApps = new ArrayMap<>();
547
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800548 private static final int EVENT_NULL = 0;
549 private static final int EVENT_NORMAL = 1;
550 private static final int EVENT_LIGHT_IDLE = 2;
551 private static final int EVENT_LIGHT_MAINTENANCE = 3;
Dianne Hackbornb6843652016-02-22 12:20:13 -0800552 private static final int EVENT_DEEP_IDLE = 4;
553 private static final int EVENT_DEEP_MAINTENANCE = 5;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800554
Dianne Hackbornef3aa6e2016-04-29 18:18:08 -0700555 private final int[] mEventCmds = new int[EVENT_BUFFER_SIZE];
556 private final long[] mEventTimes = new long[EVENT_BUFFER_SIZE];
Amith Yamasaniac6517a2018-04-23 12:19:34 -0700557 private final String[] mEventReasons = new String[EVENT_BUFFER_SIZE];
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800558
Amith Yamasaniac6517a2018-04-23 12:19:34 -0700559 private void addEvent(int cmd, String reason) {
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800560 if (mEventCmds[0] != cmd) {
561 System.arraycopy(mEventCmds, 0, mEventCmds, 1, EVENT_BUFFER_SIZE - 1);
562 System.arraycopy(mEventTimes, 0, mEventTimes, 1, EVENT_BUFFER_SIZE - 1);
Amith Yamasaniac6517a2018-04-23 12:19:34 -0700563 System.arraycopy(mEventReasons, 0, mEventReasons, 1, EVENT_BUFFER_SIZE - 1);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800564 mEventCmds[0] = cmd;
565 mEventTimes[0] = SystemClock.elapsedRealtime();
Amith Yamasaniac6517a2018-04-23 12:19:34 -0700566 mEventReasons[0] = reason;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800567 }
568 }
569
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700570 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
571 @Override public void onReceive(Context context, Intent intent) {
Dianne Hackborn88c41352016-04-07 15:18:58 -0700572 switch (intent.getAction()) {
573 case ConnectivityManager.CONNECTIVITY_ACTION: {
Dianne Hackborn4cb96ca2016-05-17 13:55:29 -0700574 updateConnectivityState(intent);
Dianne Hackborn88c41352016-04-07 15:18:58 -0700575 } break;
576 case Intent.ACTION_BATTERY_CHANGED: {
Robin Lee204cb222018-12-07 15:17:44 +0100577 boolean present = intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, true);
578 boolean plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
Dianne Hackborn88c41352016-04-07 15:18:58 -0700579 synchronized (DeviceIdleController.this) {
Robin Lee204cb222018-12-07 15:17:44 +0100580 updateChargingLocked(present && plugged);
Dianne Hackborn88c41352016-04-07 15:18:58 -0700581 }
582 } break;
583 case Intent.ACTION_PACKAGE_REMOVED: {
584 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
585 Uri data = intent.getData();
586 String ssp;
587 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
588 removePowerSaveWhitelistAppInternal(ssp);
589 }
590 }
591 } break;
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700592 }
593 }
594 };
595
596 private final AlarmManager.OnAlarmListener mLightAlarmListener
597 = new AlarmManager.OnAlarmListener() {
598 @Override
599 public void onAlarm() {
600 synchronized (DeviceIdleController.this) {
601 stepLightIdleStateLocked("s:alarm");
602 }
603 }
604 };
605
Kevin Gabayan92f15e62016-04-04 17:52:22 -0700606 private final AlarmManager.OnAlarmListener mSensingTimeoutAlarmListener
607 = new AlarmManager.OnAlarmListener() {
608 @Override
609 public void onAlarm() {
610 if (mState == STATE_SENSING) {
611 synchronized (DeviceIdleController.this) {
Kweku Adams00e3a372018-09-28 16:57:09 -0700612 // Restart the device idle progression in case the device moved but the screen
613 // didn't turn on.
Kevin Gabayan92f15e62016-04-04 17:52:22 -0700614 becomeInactiveIfAppropriateLocked();
615 }
616 }
617 }
618 };
619
Kweku Adamsb7ce1902019-01-30 10:55:34 -0800620 @VisibleForTesting
621 final AlarmManager.OnAlarmListener mDeepAlarmListener
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700622 = new AlarmManager.OnAlarmListener() {
623 @Override
624 public void onAlarm() {
625 synchronized (DeviceIdleController.this) {
626 stepIdleStateLocked("s:alarm");
627 }
628 }
629 };
630
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800631 private final BroadcastReceiver mIdleStartedDoneReceiver = new BroadcastReceiver() {
632 @Override public void onReceive(Context context, Intent intent) {
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700633 // When coming out of a deep idle, we will add in some delay before we allow
634 // the system to settle down and finish the maintenance window. This is
635 // to give a chance for any pending work to be scheduled.
636 if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(intent.getAction())) {
637 mHandler.sendEmptyMessageDelayed(MSG_FINISH_IDLE_OP,
638 mConstants.MIN_DEEP_MAINTENANCE_TIME);
639 } else {
640 mHandler.sendEmptyMessageDelayed(MSG_FINISH_IDLE_OP,
641 mConstants.MIN_LIGHT_MAINTENANCE_TIME);
642 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800643 }
644 };
645
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -0700646 private final BroadcastReceiver mInteractivityReceiver = new BroadcastReceiver() {
647 @Override
648 public void onReceive(Context context, Intent intent) {
Dianne Hackborn9b5ebc92017-09-08 13:45:35 -0700649 synchronized (DeviceIdleController.this) {
650 updateInteractivityLocked();
651 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700652 }
653 };
654
Kweku Adams00e3a372018-09-28 16:57:09 -0700655 @VisibleForTesting
656 final class MotionListener extends TriggerEventListener
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700657 implements SensorEventListener {
658
659 boolean active = false;
660
Kweku Adams00e3a372018-09-28 16:57:09 -0700661 public boolean isActive() {
662 return active;
663 }
664
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700665 @Override
666 public void onTrigger(TriggerEvent event) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700667 synchronized (DeviceIdleController.this) {
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700668 active = false;
669 motionLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700670 }
671 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700672
673 @Override
674 public void onSensorChanged(SensorEvent event) {
675 synchronized (DeviceIdleController.this) {
676 mSensorManager.unregisterListener(this, mMotionSensor);
677 active = false;
678 motionLocked();
679 }
680 }
681
682 @Override
683 public void onAccuracyChanged(Sensor sensor, int accuracy) {}
684
685 public boolean registerLocked() {
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700686 boolean success;
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700687 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
688 success = mSensorManager.requestTriggerSensor(mMotionListener, mMotionSensor);
689 } else {
690 success = mSensorManager.registerListener(
691 mMotionListener, mMotionSensor, SensorManager.SENSOR_DELAY_NORMAL);
692 }
693 if (success) {
694 active = true;
695 } else {
696 Slog.e(TAG, "Unable to register for " + mMotionSensor);
697 }
698 return success;
699 }
700
701 public void unregisterLocked() {
702 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
703 mSensorManager.cancelTriggerSensor(mMotionListener, mMotionSensor);
704 } else {
705 mSensorManager.unregisterListener(mMotionListener);
706 }
707 active = false;
708 }
709 }
Kweku Adams00e3a372018-09-28 16:57:09 -0700710 @VisibleForTesting final MotionListener mMotionListener = new MotionListener();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700711
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700712 private final LocationListener mGenericLocationListener = new LocationListener() {
713 @Override
714 public void onLocationChanged(Location location) {
715 synchronized (DeviceIdleController.this) {
716 receivedGenericLocationLocked(location);
717 }
718 }
719
720 @Override
721 public void onStatusChanged(String provider, int status, Bundle extras) {
722 }
723
724 @Override
725 public void onProviderEnabled(String provider) {
726 }
727
728 @Override
729 public void onProviderDisabled(String provider) {
730 }
731 };
732
733 private final LocationListener mGpsLocationListener = new LocationListener() {
734 @Override
735 public void onLocationChanged(Location location) {
736 synchronized (DeviceIdleController.this) {
737 receivedGpsLocationLocked(location);
738 }
739 }
740
741 @Override
742 public void onStatusChanged(String provider, int status, Bundle extras) {
743 }
744
745 @Override
746 public void onProviderEnabled(String provider) {
747 }
748
749 @Override
750 public void onProviderDisabled(String provider) {
751 }
752 };
753
Adam Lesinski31c05d12015-06-09 17:34:04 -0700754 /**
755 * All times are in milliseconds. These constants are kept synchronized with the system
756 * global Settings. Any access to this class or its fields should be done while
757 * holding the DeviceIdleController lock.
758 */
Robin Lee876b88542018-11-13 17:22:24 +0100759 public final class Constants extends ContentObserver {
Adam Lesinski31c05d12015-06-09 17:34:04 -0700760 // Key names stored in the settings value.
Dianne Hackborn953fc942016-03-29 15:36:24 -0700761 private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT
762 = "light_after_inactive_to";
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700763 private static final String KEY_LIGHT_PRE_IDLE_TIMEOUT = "light_pre_idle_to";
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700764 private static final String KEY_LIGHT_IDLE_TIMEOUT = "light_idle_to";
Dianne Hackborn953fc942016-03-29 15:36:24 -0700765 private static final String KEY_LIGHT_IDLE_FACTOR = "light_idle_factor";
766 private static final String KEY_LIGHT_MAX_IDLE_TIMEOUT = "light_max_idle_to";
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800767 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET
768 = "light_idle_maintenance_min_budget";
769 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET
770 = "light_idle_maintenance_max_budget";
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700771 private static final String KEY_MIN_LIGHT_MAINTENANCE_TIME = "min_light_maintenance_time";
772 private static final String KEY_MIN_DEEP_MAINTENANCE_TIME = "min_deep_maintenance_time";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700773 private static final String KEY_INACTIVE_TIMEOUT = "inactive_to";
774 private static final String KEY_SENSING_TIMEOUT = "sensing_to";
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700775 private static final String KEY_LOCATING_TIMEOUT = "locating_to";
776 private static final String KEY_LOCATION_ACCURACY = "location_accuracy";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700777 private static final String KEY_MOTION_INACTIVE_TIMEOUT = "motion_inactive_to";
778 private static final String KEY_IDLE_AFTER_INACTIVE_TIMEOUT = "idle_after_inactive_to";
779 private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to";
780 private static final String KEY_MAX_IDLE_PENDING_TIMEOUT = "max_idle_pending_to";
781 private static final String KEY_IDLE_PENDING_FACTOR = "idle_pending_factor";
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700782 private static final String KEY_QUICK_DOZE_DELAY_TIMEOUT = "quick_doze_delay_to";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700783 private static final String KEY_IDLE_TIMEOUT = "idle_to";
784 private static final String KEY_MAX_IDLE_TIMEOUT = "max_idle_to";
785 private static final String KEY_IDLE_FACTOR = "idle_factor";
786 private static final String KEY_MIN_TIME_TO_ALARM = "min_time_to_alarm";
787 private static final String KEY_MAX_TEMP_APP_WHITELIST_DURATION =
788 "max_temp_app_whitelist_duration";
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700789 private static final String KEY_MMS_TEMP_APP_WHITELIST_DURATION =
790 "mms_temp_app_whitelist_duration";
Dianne Hackborn451c3462015-07-21 17:39:46 -0700791 private static final String KEY_SMS_TEMP_APP_WHITELIST_DURATION =
792 "sms_temp_app_whitelist_duration";
Felipe Lemea1b79bf2016-05-24 13:06:54 -0700793 private static final String KEY_NOTIFICATION_WHITELIST_DURATION =
794 "notification_whitelist_duration";
Amith Yamasani396a10c2018-01-19 10:58:07 -0800795 /**
796 * Whether to wait for the user to unlock the device before causing screen-on to
797 * exit doze. Default = true
798 */
799 private static final String KEY_WAIT_FOR_UNLOCK = "wait_for_unlock";
Denny cy Leec5a7c292019-01-01 17:37:55 +0800800 private static final String KEY_PRE_IDLE_FACTOR_LONG =
801 "pre_idle_factor_long";
802 private static final String KEY_PRE_IDLE_FACTOR_SHORT =
803 "pre_idle_factor_short";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700804
805 /**
Dianne Hackborn953fc942016-03-29 15:36:24 -0700806 * This is the time, after becoming inactive, that we go in to the first
807 * light-weight idle mode.
808 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
809 * @see #KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT
810 */
811 public long LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT;
812
813 /**
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700814 * This is amount of time we will wait from the point where we decide we would
815 * like to go idle until we actually do, while waiting for jobs and other current
816 * activity to finish.
817 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
818 * @see #KEY_LIGHT_PRE_IDLE_TIMEOUT
819 */
820 public long LIGHT_PRE_IDLE_TIMEOUT;
821
822 /**
Dianne Hackborn953fc942016-03-29 15:36:24 -0700823 * This is the initial time that we will run in idle maintenance mode.
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700824 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
825 * @see #KEY_LIGHT_IDLE_TIMEOUT
826 */
827 public long LIGHT_IDLE_TIMEOUT;
828
829 /**
Dianne Hackborn953fc942016-03-29 15:36:24 -0700830 * Scaling factor to apply to the light idle mode time each time we complete a cycle.
831 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
832 * @see #KEY_LIGHT_IDLE_FACTOR
833 */
834 public float LIGHT_IDLE_FACTOR;
835
836 /**
Kweku Adams00e3a372018-09-28 16:57:09 -0700837 * This is the maximum time we will run in idle maintenance mode.
Dianne Hackborn953fc942016-03-29 15:36:24 -0700838 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
839 * @see #KEY_LIGHT_MAX_IDLE_TIMEOUT
840 */
841 public long LIGHT_MAX_IDLE_TIMEOUT;
842
843 /**
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800844 * This is the minimum amount of time we want to make available for maintenance mode
845 * when lightly idling. That is, we will always have at least this amount of time
846 * available maintenance before timing out and cutting off maintenance mode.
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700847 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800848 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700849 */
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800850 public long LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
851
852 /**
853 * This is the maximum amount of time we want to make available for maintenance mode
854 * when lightly idling. That is, if the system isn't using up its minimum maintenance
855 * budget and this time is being added to the budget reserve, this is the maximum
856 * reserve size we will allow to grow and thus the maximum amount of time we will
857 * allow for the maintenance window.
858 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
859 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET
860 */
861 public long LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700862
863 /**
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700864 * This is the minimum amount of time that we will stay in maintenance mode after
865 * a light doze. We have this minimum to allow various things to respond to switching
866 * in to maintenance mode and scheduling their work -- otherwise we may
Dianne Hackborn7ab40252016-06-15 17:30:24 -0700867 * see there is nothing to do (no jobs pending) and go out of maintenance
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700868 * mode immediately.
869 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
870 * @see #KEY_MIN_LIGHT_MAINTENANCE_TIME
871 */
872 public long MIN_LIGHT_MAINTENANCE_TIME;
873
874 /**
875 * This is the minimum amount of time that we will stay in maintenance mode after
876 * a full doze. We have this minimum to allow various things to respond to switching
877 * in to maintenance mode and scheduling their work -- otherwise we may
Dianne Hackborn7ab40252016-06-15 17:30:24 -0700878 * see there is nothing to do (no jobs pending) and go out of maintenance
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700879 * mode immediately.
880 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
881 * @see #KEY_MIN_DEEP_MAINTENANCE_TIME
882 */
883 public long MIN_DEEP_MAINTENANCE_TIME;
884
885 /**
Adam Lesinski31c05d12015-06-09 17:34:04 -0700886 * This is the time, after becoming inactive, at which we start looking at the
887 * motion sensor to determine if the device is being left alone. We don't do this
888 * immediately after going inactive just because we don't want to be continually running
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700889 * the motion sensor whenever the screen is off.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700890 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
891 * @see #KEY_INACTIVE_TIMEOUT
892 */
893 public long INACTIVE_TIMEOUT;
894
895 /**
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700896 * If we don't receive a callback from AnyMotion in this amount of time +
897 * {@link #LOCATING_TIMEOUT}, we will change from
Adam Lesinski31c05d12015-06-09 17:34:04 -0700898 * STATE_SENSING to STATE_INACTIVE, and any AnyMotion callbacks while not in STATE_SENSING
899 * will be ignored.
900 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
901 * @see #KEY_SENSING_TIMEOUT
902 */
903 public long SENSING_TIMEOUT;
904
905 /**
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700906 * This is how long we will wait to try to get a good location fix before going in to
907 * idle mode.
908 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
909 * @see #KEY_LOCATING_TIMEOUT
910 */
911 public long LOCATING_TIMEOUT;
912
913 /**
914 * The desired maximum accuracy (in meters) we consider the location to be good enough to go
915 * on to idle. We will be trying to get an accuracy fix at least this good or until
916 * {@link #LOCATING_TIMEOUT} expires.
917 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
918 * @see #KEY_LOCATION_ACCURACY
919 */
920 public float LOCATION_ACCURACY;
921
922 /**
Adam Lesinski31c05d12015-06-09 17:34:04 -0700923 * This is the time, after seeing motion, that we wait after becoming inactive from
924 * that until we start looking for motion again.
925 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
926 * @see #KEY_MOTION_INACTIVE_TIMEOUT
927 */
928 public long MOTION_INACTIVE_TIMEOUT;
929
930 /**
931 * This is the time, after the inactive timeout elapses, that we will wait looking
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700932 * for motion until we truly consider the device to be idle.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700933 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
934 * @see #KEY_IDLE_AFTER_INACTIVE_TIMEOUT
935 */
936 public long IDLE_AFTER_INACTIVE_TIMEOUT;
937
938 /**
939 * This is the initial time, after being idle, that we will allow ourself to be back
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700940 * in the IDLE_MAINTENANCE state allowing the system to run normally until we return to
941 * idle.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700942 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
943 * @see #KEY_IDLE_PENDING_TIMEOUT
944 */
945 public long IDLE_PENDING_TIMEOUT;
946
947 /**
948 * Maximum pending idle timeout (time spent running) we will be allowed to use.
949 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
950 * @see #KEY_MAX_IDLE_PENDING_TIMEOUT
951 */
952 public long MAX_IDLE_PENDING_TIMEOUT;
953
954 /**
955 * Scaling factor to apply to current pending idle timeout each time we cycle through
956 * that state.
957 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
958 * @see #KEY_IDLE_PENDING_FACTOR
959 */
960 public float IDLE_PENDING_FACTOR;
961
962 /**
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700963 * This is amount of time we will wait from the point where we go into
964 * STATE_QUICK_DOZE_DELAY until we actually go into STATE_IDLE, while waiting for jobs
965 * and other current activity to finish.
966 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
967 * @see #KEY_QUICK_DOZE_DELAY_TIMEOUT
968 */
969 public long QUICK_DOZE_DELAY_TIMEOUT;
970
971 /**
Adam Lesinski31c05d12015-06-09 17:34:04 -0700972 * This is the initial time that we want to sit in the idle state before waking up
973 * again to return to pending idle and allowing normal work to run.
974 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
975 * @see #KEY_IDLE_TIMEOUT
976 */
977 public long IDLE_TIMEOUT;
978
979 /**
980 * Maximum idle duration we will be allowed to use.
981 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
982 * @see #KEY_MAX_IDLE_TIMEOUT
983 */
984 public long MAX_IDLE_TIMEOUT;
985
986 /**
987 * Scaling factor to apply to current idle timeout each time we cycle through that state.
988 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
989 * @see #KEY_IDLE_FACTOR
990 */
991 public float IDLE_FACTOR;
992
993 /**
994 * This is the minimum time we will allow until the next upcoming alarm for us to
995 * actually go in to idle mode.
996 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
997 * @see #KEY_MIN_TIME_TO_ALARM
998 */
999 public long MIN_TIME_TO_ALARM;
1000
1001 /**
1002 * Max amount of time to temporarily whitelist an app when it receives a high priority
1003 * tickle.
1004 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
1005 * @see #KEY_MAX_TEMP_APP_WHITELIST_DURATION
1006 */
1007 public long MAX_TEMP_APP_WHITELIST_DURATION;
1008
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001009 /**
1010 * Amount of time we would like to whitelist an app that is receiving an MMS.
1011 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
1012 * @see #KEY_MMS_TEMP_APP_WHITELIST_DURATION
1013 */
1014 public long MMS_TEMP_APP_WHITELIST_DURATION;
1015
Dianne Hackborn451c3462015-07-21 17:39:46 -07001016 /**
1017 * Amount of time we would like to whitelist an app that is receiving an SMS.
1018 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
1019 * @see #KEY_SMS_TEMP_APP_WHITELIST_DURATION
1020 */
1021 public long SMS_TEMP_APP_WHITELIST_DURATION;
1022
Felipe Lemea1b79bf2016-05-24 13:06:54 -07001023 /**
1024 * Amount of time we would like to whitelist an app that is handling a
1025 * {@link android.app.PendingIntent} triggered by a {@link android.app.Notification}.
1026 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
1027 * @see #KEY_NOTIFICATION_WHITELIST_DURATION
1028 */
1029 public long NOTIFICATION_WHITELIST_DURATION;
1030
Denny cy Leec5a7c292019-01-01 17:37:55 +08001031 /**
1032 * Pre idle time factor use to make idle delay longer
1033 */
1034 public float PRE_IDLE_FACTOR_LONG;
1035
1036 /**
1037 * Pre idle time factor use to make idle delay shorter
1038 */
1039 public float PRE_IDLE_FACTOR_SHORT;
1040
Amith Yamasani396a10c2018-01-19 10:58:07 -08001041 public boolean WAIT_FOR_UNLOCK;
1042
Adam Lesinski31c05d12015-06-09 17:34:04 -07001043 private final ContentResolver mResolver;
shreerag597da8a2017-07-21 14:24:14 -07001044 private final boolean mSmallBatteryDevice;
Adam Lesinski31c05d12015-06-09 17:34:04 -07001045 private final KeyValueListParser mParser = new KeyValueListParser(',');
1046
1047 public Constants(Handler handler, ContentResolver resolver) {
1048 super(handler);
1049 mResolver = resolver;
shreerag597da8a2017-07-21 14:24:14 -07001050 mSmallBatteryDevice = ActivityManager.isSmallBatteryDevice();
1051 mResolver.registerContentObserver(
1052 Settings.Global.getUriFor(Settings.Global.DEVICE_IDLE_CONSTANTS),
Joe LaPennaf33b5bf2016-03-23 15:19:47 -07001053 false, this);
Adam Lesinski31c05d12015-06-09 17:34:04 -07001054 updateConstants();
1055 }
1056
1057 @Override
1058 public void onChange(boolean selfChange, Uri uri) {
1059 updateConstants();
1060 }
1061
1062 private void updateConstants() {
1063 synchronized (DeviceIdleController.this) {
1064 try {
1065 mParser.setString(Settings.Global.getString(mResolver,
shreerag597da8a2017-07-21 14:24:14 -07001066 Settings.Global.DEVICE_IDLE_CONSTANTS));
Adam Lesinski31c05d12015-06-09 17:34:04 -07001067 } catch (IllegalArgumentException e) {
1068 // Failed to parse the settings string, log this and move on
1069 // with defaults.
1070 Slog.e(TAG, "Bad device idle settings", e);
1071 }
1072
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001073 LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getDurationMillis(
Dianne Hackborn953fc942016-03-29 15:36:24 -07001074 KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
Suprabh Shukla85fff7d2018-05-08 17:39:24 -07001075 !COMPRESS_TIME ? 3 * 60 * 1000L : 15 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001076 LIGHT_PRE_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_LIGHT_PRE_IDLE_TIMEOUT,
Suprabh Shukla85fff7d2018-05-08 17:39:24 -07001077 !COMPRESS_TIME ? 3 * 60 * 1000L : 30 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001078 LIGHT_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_LIGHT_IDLE_TIMEOUT,
Dianne Hackborn953fc942016-03-29 15:36:24 -07001079 !COMPRESS_TIME ? 5 * 60 * 1000L : 15 * 1000L);
1080 LIGHT_IDLE_FACTOR = mParser.getFloat(KEY_LIGHT_IDLE_FACTOR,
1081 2f);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001082 LIGHT_MAX_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_LIGHT_MAX_IDLE_TIMEOUT,
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001083 !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001084 LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = mParser.getDurationMillis(
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001085 KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET,
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001086 !COMPRESS_TIME ? 1 * 60 * 1000L : 15 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001087 LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = mParser.getDurationMillis(
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001088 KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET,
1089 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001090 MIN_LIGHT_MAINTENANCE_TIME = mParser.getDurationMillis(
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001091 KEY_MIN_LIGHT_MAINTENANCE_TIME,
1092 !COMPRESS_TIME ? 5 * 1000L : 1 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001093 MIN_DEEP_MAINTENANCE_TIME = mParser.getDurationMillis(
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001094 KEY_MIN_DEEP_MAINTENANCE_TIME,
1095 !COMPRESS_TIME ? 30 * 1000L : 5 * 1000L);
Michael Kwan88871462017-08-21 13:13:37 -07001096 long inactiveTimeoutDefault = (mSmallBatteryDevice ? 15 : 30) * 60 * 1000L;
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001097 INACTIVE_TIMEOUT = mParser.getDurationMillis(KEY_INACTIVE_TIMEOUT,
Joe LaPenna0c5d3e92016-03-24 13:29:56 -07001098 !COMPRESS_TIME ? inactiveTimeoutDefault : (inactiveTimeoutDefault / 10));
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001099 SENSING_TIMEOUT = mParser.getDurationMillis(KEY_SENSING_TIMEOUT,
Kweku Adams9da2bb92018-12-20 06:34:39 -08001100 !COMPRESS_TIME ? 4 * 60 * 1000L : 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001101 LOCATING_TIMEOUT = mParser.getDurationMillis(KEY_LOCATING_TIMEOUT,
Kweku Adams9da2bb92018-12-20 06:34:39 -08001102 !COMPRESS_TIME ? 30 * 1000L : 15 * 1000L);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001103 LOCATION_ACCURACY = mParser.getFloat(KEY_LOCATION_ACCURACY, 20);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001104 MOTION_INACTIVE_TIMEOUT = mParser.getDurationMillis(KEY_MOTION_INACTIVE_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001105 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
Michael Kwan88871462017-08-21 13:13:37 -07001106 long idleAfterInactiveTimeout = (mSmallBatteryDevice ? 15 : 30) * 60 * 1000L;
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001107 IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getDurationMillis(
1108 KEY_IDLE_AFTER_INACTIVE_TIMEOUT,
Joe LaPenna0c5d3e92016-03-24 13:29:56 -07001109 !COMPRESS_TIME ? idleAfterInactiveTimeout
1110 : (idleAfterInactiveTimeout / 10));
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001111 IDLE_PENDING_TIMEOUT = mParser.getDurationMillis(KEY_IDLE_PENDING_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001112 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001113 MAX_IDLE_PENDING_TIMEOUT = mParser.getDurationMillis(KEY_MAX_IDLE_PENDING_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001114 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
1115 IDLE_PENDING_FACTOR = mParser.getFloat(KEY_IDLE_PENDING_FACTOR,
1116 2f);
Kweku Adamsb396ccf2018-09-17 16:37:15 -07001117 QUICK_DOZE_DELAY_TIMEOUT = mParser.getDurationMillis(
1118 KEY_QUICK_DOZE_DELAY_TIMEOUT, !COMPRESS_TIME ? 60 * 1000L : 15 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001119 IDLE_TIMEOUT = mParser.getDurationMillis(KEY_IDLE_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001120 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001121 MAX_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_MAX_IDLE_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001122 !COMPRESS_TIME ? 6 * 60 * 60 * 1000L : 30 * 60 * 1000L);
1123 IDLE_FACTOR = mParser.getFloat(KEY_IDLE_FACTOR,
1124 2f);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001125 MIN_TIME_TO_ALARM = mParser.getDurationMillis(KEY_MIN_TIME_TO_ALARM,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001126 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001127 MAX_TEMP_APP_WHITELIST_DURATION = mParser.getDurationMillis(
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001128 KEY_MAX_TEMP_APP_WHITELIST_DURATION, 5 * 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001129 MMS_TEMP_APP_WHITELIST_DURATION = mParser.getDurationMillis(
Dianne Hackborn0b6134b2015-07-14 18:48:07 -07001130 KEY_MMS_TEMP_APP_WHITELIST_DURATION, 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001131 SMS_TEMP_APP_WHITELIST_DURATION = mParser.getDurationMillis(
Dianne Hackborn451c3462015-07-21 17:39:46 -07001132 KEY_SMS_TEMP_APP_WHITELIST_DURATION, 20 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001133 NOTIFICATION_WHITELIST_DURATION = mParser.getDurationMillis(
Felipe Lemea1b79bf2016-05-24 13:06:54 -07001134 KEY_NOTIFICATION_WHITELIST_DURATION, 30 * 1000L);
Kweku Adams43fabba2019-03-07 15:47:37 -08001135 WAIT_FOR_UNLOCK = mParser.getBoolean(KEY_WAIT_FOR_UNLOCK, true);
Denny cy Leec5a7c292019-01-01 17:37:55 +08001136 PRE_IDLE_FACTOR_LONG = mParser.getFloat(KEY_PRE_IDLE_FACTOR_LONG, 1.67f);
1137 PRE_IDLE_FACTOR_SHORT = mParser.getFloat(KEY_PRE_IDLE_FACTOR_SHORT, 0.33f);
Adam Lesinski31c05d12015-06-09 17:34:04 -07001138 }
1139 }
1140
1141 void dump(PrintWriter pw) {
1142 pw.println(" Settings:");
1143
Dianne Hackborn953fc942016-03-29 15:36:24 -07001144 pw.print(" "); pw.print(KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("=");
1145 TimeUtils.formatDuration(LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT, pw);
1146 pw.println();
1147
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001148 pw.print(" "); pw.print(KEY_LIGHT_PRE_IDLE_TIMEOUT); pw.print("=");
1149 TimeUtils.formatDuration(LIGHT_PRE_IDLE_TIMEOUT, pw);
1150 pw.println();
1151
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001152 pw.print(" "); pw.print(KEY_LIGHT_IDLE_TIMEOUT); pw.print("=");
1153 TimeUtils.formatDuration(LIGHT_IDLE_TIMEOUT, pw);
1154 pw.println();
1155
Dianne Hackborn953fc942016-03-29 15:36:24 -07001156 pw.print(" "); pw.print(KEY_LIGHT_IDLE_FACTOR); pw.print("=");
1157 pw.print(LIGHT_IDLE_FACTOR);
1158 pw.println();
1159
1160 pw.print(" "); pw.print(KEY_LIGHT_MAX_IDLE_TIMEOUT); pw.print("=");
1161 TimeUtils.formatDuration(LIGHT_MAX_IDLE_TIMEOUT, pw);
1162 pw.println();
1163
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001164 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET); pw.print("=");
1165 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MIN_BUDGET, pw);
1166 pw.println();
1167
1168 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET); pw.print("=");
1169 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MAX_BUDGET, pw);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001170 pw.println();
1171
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001172 pw.print(" "); pw.print(KEY_MIN_LIGHT_MAINTENANCE_TIME); pw.print("=");
1173 TimeUtils.formatDuration(MIN_LIGHT_MAINTENANCE_TIME, pw);
1174 pw.println();
1175
1176 pw.print(" "); pw.print(KEY_MIN_DEEP_MAINTENANCE_TIME); pw.print("=");
1177 TimeUtils.formatDuration(MIN_DEEP_MAINTENANCE_TIME, pw);
1178 pw.println();
1179
Dianne Hackborna750a632015-06-16 17:18:23 -07001180 pw.print(" "); pw.print(KEY_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001181 TimeUtils.formatDuration(INACTIVE_TIMEOUT, pw);
1182 pw.println();
1183
Dianne Hackborna750a632015-06-16 17:18:23 -07001184 pw.print(" "); pw.print(KEY_SENSING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001185 TimeUtils.formatDuration(SENSING_TIMEOUT, pw);
1186 pw.println();
1187
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001188 pw.print(" "); pw.print(KEY_LOCATING_TIMEOUT); pw.print("=");
1189 TimeUtils.formatDuration(LOCATING_TIMEOUT, pw);
1190 pw.println();
1191
1192 pw.print(" "); pw.print(KEY_LOCATION_ACCURACY); pw.print("=");
1193 pw.print(LOCATION_ACCURACY); pw.print("m");
1194 pw.println();
1195
Dianne Hackborna750a632015-06-16 17:18:23 -07001196 pw.print(" "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001197 TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT, pw);
1198 pw.println();
1199
Dianne Hackborna750a632015-06-16 17:18:23 -07001200 pw.print(" "); pw.print(KEY_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001201 TimeUtils.formatDuration(IDLE_AFTER_INACTIVE_TIMEOUT, pw);
1202 pw.println();
1203
Dianne Hackborna750a632015-06-16 17:18:23 -07001204 pw.print(" "); pw.print(KEY_IDLE_PENDING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001205 TimeUtils.formatDuration(IDLE_PENDING_TIMEOUT, pw);
1206 pw.println();
1207
Dianne Hackborna750a632015-06-16 17:18:23 -07001208 pw.print(" "); pw.print(KEY_MAX_IDLE_PENDING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001209 TimeUtils.formatDuration(MAX_IDLE_PENDING_TIMEOUT, pw);
1210 pw.println();
1211
Dianne Hackborna750a632015-06-16 17:18:23 -07001212 pw.print(" "); pw.print(KEY_IDLE_PENDING_FACTOR); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001213 pw.println(IDLE_PENDING_FACTOR);
1214
Kweku Adamsb396ccf2018-09-17 16:37:15 -07001215 pw.print(" "); pw.print(KEY_QUICK_DOZE_DELAY_TIMEOUT); pw.print("=");
1216 TimeUtils.formatDuration(QUICK_DOZE_DELAY_TIMEOUT, pw);
1217 pw.println();
1218
Dianne Hackborna750a632015-06-16 17:18:23 -07001219 pw.print(" "); pw.print(KEY_IDLE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001220 TimeUtils.formatDuration(IDLE_TIMEOUT, pw);
1221 pw.println();
1222
Dianne Hackborna750a632015-06-16 17:18:23 -07001223 pw.print(" "); pw.print(KEY_MAX_IDLE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001224 TimeUtils.formatDuration(MAX_IDLE_TIMEOUT, pw);
1225 pw.println();
1226
Dianne Hackborna750a632015-06-16 17:18:23 -07001227 pw.print(" "); pw.print(KEY_IDLE_FACTOR); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001228 pw.println(IDLE_FACTOR);
1229
Dianne Hackborna750a632015-06-16 17:18:23 -07001230 pw.print(" "); pw.print(KEY_MIN_TIME_TO_ALARM); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001231 TimeUtils.formatDuration(MIN_TIME_TO_ALARM, pw);
1232 pw.println();
1233
Dianne Hackborna750a632015-06-16 17:18:23 -07001234 pw.print(" "); pw.print(KEY_MAX_TEMP_APP_WHITELIST_DURATION); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001235 TimeUtils.formatDuration(MAX_TEMP_APP_WHITELIST_DURATION, pw);
1236 pw.println();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001237
1238 pw.print(" "); pw.print(KEY_MMS_TEMP_APP_WHITELIST_DURATION); pw.print("=");
1239 TimeUtils.formatDuration(MMS_TEMP_APP_WHITELIST_DURATION, pw);
1240 pw.println();
Dianne Hackborn451c3462015-07-21 17:39:46 -07001241
1242 pw.print(" "); pw.print(KEY_SMS_TEMP_APP_WHITELIST_DURATION); pw.print("=");
1243 TimeUtils.formatDuration(SMS_TEMP_APP_WHITELIST_DURATION, pw);
1244 pw.println();
Felipe Lemea1b79bf2016-05-24 13:06:54 -07001245
1246 pw.print(" "); pw.print(KEY_NOTIFICATION_WHITELIST_DURATION); pw.print("=");
1247 TimeUtils.formatDuration(NOTIFICATION_WHITELIST_DURATION, pw);
1248 pw.println();
Amith Yamasani396a10c2018-01-19 10:58:07 -08001249
1250 pw.print(" "); pw.print(KEY_WAIT_FOR_UNLOCK); pw.print("=");
1251 pw.println(WAIT_FOR_UNLOCK);
Denny cy Leec5a7c292019-01-01 17:37:55 +08001252
1253 pw.print(" "); pw.print(KEY_PRE_IDLE_FACTOR_LONG); pw.print("=");
1254 pw.println(PRE_IDLE_FACTOR_LONG);
1255
1256 pw.print(" "); pw.print(KEY_PRE_IDLE_FACTOR_SHORT); pw.print("=");
1257 pw.println(PRE_IDLE_FACTOR_SHORT);
Adam Lesinski31c05d12015-06-09 17:34:04 -07001258 }
1259 }
1260
1261 private Constants mConstants;
1262
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001263 @Override
1264 public void onAnyMotionResult(int result) {
1265 if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")");
Kevin Gabayan92f15e62016-04-04 17:52:22 -07001266 if (result != AnyMotionDetector.RESULT_UNKNOWN) {
1267 synchronized (this) {
1268 cancelSensingTimeoutAlarmLocked();
1269 }
1270 }
Kevin Gabayandcf47012016-07-08 10:41:24 -07001271 if ((result == AnyMotionDetector.RESULT_MOVED) ||
1272 (result == AnyMotionDetector.RESULT_UNKNOWN)) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001273 synchronized (this) {
Kevin Gabayandcf47012016-07-08 10:41:24 -07001274 handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "non_stationary");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001275 }
1276 } else if (result == AnyMotionDetector.RESULT_STATIONARY) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001277 if (mState == STATE_SENSING) {
1278 // If we are currently sensing, it is time to move to locating.
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001279 synchronized (this) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001280 mNotMoving = true;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001281 stepIdleStateLocked("s:stationary");
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001282 }
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001283 } else if (mState == STATE_LOCATING) {
1284 // If we are currently locating, note that we are not moving and step
1285 // if we have located the position.
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001286 synchronized (this) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001287 mNotMoving = true;
1288 if (mLocated) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001289 stepIdleStateLocked("s:stationary");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001290 }
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001291 }
1292 }
1293 }
1294 }
1295
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001296 private static final int MSG_WRITE_CONFIG = 1;
1297 private static final int MSG_REPORT_IDLE_ON = 2;
1298 private static final int MSG_REPORT_IDLE_ON_LIGHT = 3;
1299 private static final int MSG_REPORT_IDLE_OFF = 4;
1300 private static final int MSG_REPORT_ACTIVE = 5;
1301 private static final int MSG_TEMP_APP_WHITELIST_TIMEOUT = 6;
1302 private static final int MSG_REPORT_MAINTENANCE_ACTIVITY = 7;
1303 private static final int MSG_FINISH_IDLE_OP = 8;
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07001304 private static final int MSG_REPORT_TEMP_APP_WHITELIST_CHANGED = 9;
Robin Lee876b88542018-11-13 17:22:24 +01001305 private static final int MSG_SEND_CONSTRAINT_MONITORING = 10;
Denny cy Leec5a7c292019-01-01 17:37:55 +08001306 private static final int MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR = 11;
1307 private static final int MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR = 12;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001308
1309 final class MyHandler extends Handler {
1310 MyHandler(Looper looper) {
1311 super(looper);
1312 }
1313
1314 @Override public void handleMessage(Message msg) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001315 if (DEBUG) Slog.d(TAG, "handleMessage(" + msg.what + ")");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001316 switch (msg.what) {
1317 case MSG_WRITE_CONFIG: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001318 // Does not hold a wakelock. Just let this happen whenever.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001319 handleWriteConfigFile();
1320 } break;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001321 case MSG_REPORT_IDLE_ON:
1322 case MSG_REPORT_IDLE_ON_LIGHT: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001323 // mGoingIdleWakeLock is held at this point
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001324 EventLogTags.writeDeviceIdleOnStart();
Dianne Hackbornb6843652016-02-22 12:20:13 -08001325 final boolean deepChanged;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001326 final boolean lightChanged;
1327 if (msg.what == MSG_REPORT_IDLE_ON) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08001328 deepChanged = mLocalPowerManager.setDeviceIdleMode(true);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001329 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
1330 } else {
Dianne Hackbornb6843652016-02-22 12:20:13 -08001331 deepChanged = mLocalPowerManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001332 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(true);
1333 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001334 try {
1335 mNetworkPolicyManager.setDeviceIdleMode(true);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001336 mBatteryStats.noteDeviceIdleMode(msg.what == MSG_REPORT_IDLE_ON
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001337 ? BatteryStats.DEVICE_IDLE_MODE_DEEP
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001338 : BatteryStats.DEVICE_IDLE_MODE_LIGHT, null, Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001339 } catch (RemoteException e) {
1340 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08001341 if (deepChanged) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001342 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
1343 }
1344 if (lightChanged) {
1345 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL);
1346 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001347 EventLogTags.writeDeviceIdleOnComplete();
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001348 mGoingIdleWakeLock.release();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001349 } break;
1350 case MSG_REPORT_IDLE_OFF: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001351 // mActiveIdleWakeLock is held at this point
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001352 EventLogTags.writeDeviceIdleOffStart("unknown");
Dianne Hackbornb6843652016-02-22 12:20:13 -08001353 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001354 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001355 try {
1356 mNetworkPolicyManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001357 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF,
1358 null, Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001359 } catch (RemoteException e) {
1360 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08001361 if (deepChanged) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001362 incActiveIdleOps();
1363 getContext().sendOrderedBroadcastAsUser(mIdleIntent, UserHandle.ALL,
1364 null, mIdleStartedDoneReceiver, null, 0, null, null);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001365 }
1366 if (lightChanged) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001367 incActiveIdleOps();
1368 getContext().sendOrderedBroadcastAsUser(mLightIdleIntent, UserHandle.ALL,
1369 null, mIdleStartedDoneReceiver, null, 0, null, null);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001370 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001371 // Always start with one active op for the message being sent here.
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001372 // Now we are done!
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001373 decActiveIdleOps();
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001374 EventLogTags.writeDeviceIdleOffComplete();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001375 } break;
1376 case MSG_REPORT_ACTIVE: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001377 // The device is awake at this point, so no wakelock necessary.
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001378 String activeReason = (String)msg.obj;
1379 int activeUid = msg.arg1;
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001380 EventLogTags.writeDeviceIdleOffStart(
1381 activeReason != null ? activeReason : "unknown");
Dianne Hackbornb6843652016-02-22 12:20:13 -08001382 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001383 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001384 try {
1385 mNetworkPolicyManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001386 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF,
1387 activeReason, activeUid);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001388 } catch (RemoteException e) {
1389 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08001390 if (deepChanged) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001391 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
1392 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001393 if (lightChanged) {
1394 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL);
1395 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001396 EventLogTags.writeDeviceIdleOffComplete();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001397 } break;
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001398 case MSG_TEMP_APP_WHITELIST_TIMEOUT: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001399 // TODO: What is keeping the device awake at this point? Does it need to be?
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001400 int uid = msg.arg1;
1401 checkTempAppWhitelistTimeout(uid);
1402 } break;
Yao Chenca5edbb2016-01-13 14:44:36 -08001403 case MSG_REPORT_MAINTENANCE_ACTIVITY: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001404 // TODO: What is keeping the device awake at this point? Does it need to be?
Yao Chenca5edbb2016-01-13 14:44:36 -08001405 boolean active = (msg.arg1 == 1);
1406 final int size = mMaintenanceActivityListeners.beginBroadcast();
1407 try {
1408 for (int i = 0; i < size; i++) {
1409 try {
1410 mMaintenanceActivityListeners.getBroadcastItem(i)
1411 .onMaintenanceActivityChanged(active);
1412 } catch (RemoteException ignored) {
1413 }
1414 }
1415 } finally {
1416 mMaintenanceActivityListeners.finishBroadcast();
1417 }
1418 } break;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001419 case MSG_FINISH_IDLE_OP: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001420 // mActiveIdleWakeLock is held at this point
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001421 decActiveIdleOps();
1422 } break;
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07001423 case MSG_REPORT_TEMP_APP_WHITELIST_CHANGED: {
1424 final int appId = msg.arg1;
1425 final boolean added = (msg.arg2 == 1);
1426 mNetworkPolicyManagerInternal.onTempPowerSaveWhitelistChange(appId, added);
1427 } break;
Robin Lee876b88542018-11-13 17:22:24 +01001428 case MSG_SEND_CONSTRAINT_MONITORING: {
1429 final IDeviceIdleConstraint constraint = (IDeviceIdleConstraint) msg.obj;
1430 final boolean monitoring = (msg.arg1 == 1);
1431 if (monitoring) {
1432 constraint.startMonitoring();
1433 } else {
1434 constraint.stopMonitoring();
1435 }
1436 } break;
Denny cy Leec5a7c292019-01-01 17:37:55 +08001437 case MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR: {
1438 updatePreIdleFactor();
1439 } break;
1440 case MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR: {
1441 updatePreIdleFactor();
1442 maybeDoImmediateMaintenance();
1443 } break;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001444 }
1445 }
1446 }
1447
1448 final MyHandler mHandler;
1449
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001450 BinderService mBinderService;
1451
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001452 private final class BinderService extends IDeviceIdleController.Stub {
1453 @Override public void addPowerSaveWhitelistApp(String name) {
Eugene Susla6a7006a2017-03-13 12:57:58 -07001454 if (DEBUG) {
1455 Slog.i(TAG, "addPowerSaveWhitelistApp(name = " + name + ")");
1456 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001457 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1458 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001459 long ident = Binder.clearCallingIdentity();
1460 try {
1461 addPowerSaveWhitelistAppInternal(name);
1462 } finally {
1463 Binder.restoreCallingIdentity(ident);
1464 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001465 }
1466
1467 @Override public void removePowerSaveWhitelistApp(String name) {
Eugene Susla6a7006a2017-03-13 12:57:58 -07001468 if (DEBUG) {
1469 Slog.i(TAG, "removePowerSaveWhitelistApp(name = " + name + ")");
1470 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001471 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1472 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001473 long ident = Binder.clearCallingIdentity();
1474 try {
1475 removePowerSaveWhitelistAppInternal(name);
1476 } finally {
1477 Binder.restoreCallingIdentity(ident);
1478 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001479 }
1480
Suprabh Shukla08105642017-09-26 14:45:30 -07001481 @Override public void removeSystemPowerWhitelistApp(String name) {
1482 if (DEBUG) {
1483 Slog.d(TAG, "removeAppFromSystemWhitelist(name = " + name + ")");
1484 }
1485 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1486 null);
1487 long ident = Binder.clearCallingIdentity();
1488 try {
1489 removeSystemPowerWhitelistAppInternal(name);
1490 } finally {
1491 Binder.restoreCallingIdentity(ident);
1492 }
1493 }
1494
1495 @Override public void restoreSystemPowerWhitelistApp(String name) {
1496 if (DEBUG) {
1497 Slog.d(TAG, "restoreAppToSystemWhitelist(name = " + name + ")");
1498 }
1499 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1500 null);
1501 long ident = Binder.clearCallingIdentity();
1502 try {
1503 restoreSystemPowerWhitelistAppInternal(name);
1504 } finally {
1505 Binder.restoreCallingIdentity(ident);
1506 }
1507 }
1508
1509 public String[] getRemovedSystemPowerWhitelistApps() {
1510 return getRemovedSystemPowerWhitelistAppsInternal();
1511 }
1512
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001513 @Override public String[] getSystemPowerWhitelistExceptIdle() {
1514 return getSystemPowerWhitelistExceptIdleInternal();
1515 }
1516
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001517 @Override public String[] getSystemPowerWhitelist() {
1518 return getSystemPowerWhitelistInternal();
1519 }
1520
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001521 @Override public String[] getUserPowerWhitelist() {
1522 return getUserPowerWhitelistInternal();
1523 }
1524
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001525 @Override public String[] getFullPowerWhitelistExceptIdle() {
1526 return getFullPowerWhitelistExceptIdleInternal();
1527 }
1528
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001529 @Override public String[] getFullPowerWhitelist() {
1530 return getFullPowerWhitelistInternal();
1531 }
1532
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001533 @Override public int[] getAppIdWhitelistExceptIdle() {
1534 return getAppIdWhitelistExceptIdleInternal();
1535 }
1536
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001537 @Override public int[] getAppIdWhitelist() {
1538 return getAppIdWhitelistInternal();
1539 }
1540
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001541 @Override public int[] getAppIdUserWhitelist() {
1542 return getAppIdUserWhitelistInternal();
1543 }
1544
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001545 @Override public int[] getAppIdTempWhitelist() {
1546 return getAppIdTempWhitelistInternal();
1547 }
1548
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001549 @Override public boolean isPowerSaveWhitelistExceptIdleApp(String name) {
1550 return isPowerSaveWhitelistExceptIdleAppInternal(name);
1551 }
1552
Amith Yamasani06bf8242015-05-08 16:36:21 -07001553 @Override public boolean isPowerSaveWhitelistApp(String name) {
1554 return isPowerSaveWhitelistAppInternal(name);
1555 }
1556
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001557 @Override public void addPowerSaveTempWhitelistApp(String packageName, long duration,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001558 int userId, String reason) throws RemoteException {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001559 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001560 }
1561
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001562 @Override public long addPowerSaveTempWhitelistAppForMms(String packageName,
1563 int userId, String reason) throws RemoteException {
1564 long duration = mConstants.MMS_TEMP_APP_WHITELIST_DURATION;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001565 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001566 return duration;
1567 }
1568
Dianne Hackborn451c3462015-07-21 17:39:46 -07001569 @Override public long addPowerSaveTempWhitelistAppForSms(String packageName,
1570 int userId, String reason) throws RemoteException {
1571 long duration = mConstants.SMS_TEMP_APP_WHITELIST_DURATION;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001572 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Dianne Hackborn451c3462015-07-21 17:39:46 -07001573 return duration;
1574 }
1575
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001576 @Override public void exitIdle(String reason) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001577 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER,
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001578 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001579 long ident = Binder.clearCallingIdentity();
1580 try {
1581 exitIdleInternal(reason);
1582 } finally {
1583 Binder.restoreCallingIdentity(ident);
1584 }
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001585 }
1586
Yao Chenca5edbb2016-01-13 14:44:36 -08001587 @Override public boolean registerMaintenanceActivityListener(
1588 IMaintenanceActivityListener listener) {
1589 return DeviceIdleController.this.registerMaintenanceActivityListener(listener);
1590 }
1591
1592 @Override public void unregisterMaintenanceActivityListener(
1593 IMaintenanceActivityListener listener) {
1594 DeviceIdleController.this.unregisterMaintenanceActivityListener(listener);
1595 }
1596
Denny cy Leec5a7c292019-01-01 17:37:55 +08001597 @Override public int setPreIdleTimeoutMode(int mode) {
1598 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER,
1599 null);
1600 long ident = Binder.clearCallingIdentity();
1601 try {
1602 return DeviceIdleController.this.setPreIdleTimeoutMode(mode);
1603 } finally {
1604 Binder.restoreCallingIdentity(ident);
1605 }
1606 }
1607
1608 @Override public void resetPreIdleTimeoutMode() {
1609 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER,
1610 null);
1611 long ident = Binder.clearCallingIdentity();
1612 try {
1613 DeviceIdleController.this.resetPreIdleTimeoutMode();
1614 } finally {
1615 Binder.restoreCallingIdentity(ident);
1616 }
1617 }
1618
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001619 @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1620 DeviceIdleController.this.dump(fd, pw, args);
1621 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001622
1623 @Override public void onShellCommand(FileDescriptor in, FileDescriptor out,
Dianne Hackborn354736e2016-08-22 17:00:05 -07001624 FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
1625 (new Shell()).exec(this, in, out, err, args, callback, resultReceiver);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001626 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001627 }
1628
Felipe Lemeef134662016-08-10 14:46:39 -07001629 public class LocalService {
Robin Lee876b88542018-11-13 17:22:24 +01001630 public void onConstraintStateChanged(IDeviceIdleConstraint constraint, boolean active) {
1631 synchronized (DeviceIdleController.this) {
1632 onConstraintStateChangedLocked(constraint, active);
1633 }
1634 }
1635
1636 public void registerDeviceIdleConstraint(IDeviceIdleConstraint constraint, String name,
1637 @IDeviceIdleConstraint.MinimumState int minState) {
1638 registerDeviceIdleConstraintInternal(constraint, name, minState);
1639 }
1640
1641 public void unregisterDeviceIdleConstraint(IDeviceIdleConstraint constraint) {
1642 unregisterDeviceIdleConstraintInternal(constraint);
1643 }
1644
1645 public void exitIdle(String reason) {
1646 exitIdleInternal(reason);
1647 }
1648
Christopher Tatee0be7e82017-02-08 17:38:20 -08001649 // duration in milliseconds
1650 public void addPowerSaveTempWhitelistApp(int callingUid, String packageName,
1651 long duration, int userId, boolean sync, String reason) {
1652 addPowerSaveTempWhitelistAppInternal(callingUid, packageName, duration,
1653 userId, sync, reason);
1654 }
1655
1656 // duration in milliseconds
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001657 public void addPowerSaveTempWhitelistAppDirect(int appId, long duration, boolean sync,
1658 String reason) {
1659 addPowerSaveTempWhitelistAppDirectInternal(0, appId, duration, sync, reason);
1660 }
1661
Christopher Tatee0be7e82017-02-08 17:38:20 -08001662 // duration in milliseconds
Felipe Lemea1b79bf2016-05-24 13:06:54 -07001663 public long getNotificationWhitelistDuration() {
1664 return mConstants.NOTIFICATION_WHITELIST_DURATION;
1665 }
1666
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001667 public void setJobsActive(boolean active) {
1668 DeviceIdleController.this.setJobsActive(active);
1669 }
1670
1671 // Up-call from alarm manager.
1672 public void setAlarmsActive(boolean active) {
1673 DeviceIdleController.this.setAlarmsActive(active);
1674 }
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001675
Christopher Tate42a386b2016-11-07 12:21:21 -08001676 /** Is the app on any of the power save whitelists, whether system or user? */
1677 public boolean isAppOnWhitelist(int appid) {
1678 return DeviceIdleController.this.isAppOnWhitelistInternal(appid);
1679 }
1680
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001681 /**
1682 * Returns the array of app ids whitelisted by user. Take care not to
1683 * modify this, as it is a reference to the original copy. But the reference
1684 * can change when the list changes, so it needs to be re-acquired when
1685 * {@link PowerManager#ACTION_POWER_SAVE_WHITELIST_CHANGED} is sent.
1686 */
1687 public int[] getPowerSaveWhitelistUserAppIds() {
1688 return DeviceIdleController.this.getPowerSaveWhitelistUserAppIds();
1689 }
Suprabh Shuklaa78acfd2017-10-13 19:29:36 -07001690
1691 public int[] getPowerSaveTempWhitelistAppIds() {
1692 return DeviceIdleController.this.getAppIdTempWhitelistInternal();
1693 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001694 }
1695
Kweku Adams00e3a372018-09-28 16:57:09 -07001696 static class Injector {
1697 private final Context mContext;
Kweku Adams799858b2018-10-08 17:19:08 -07001698 private ConnectivityService mConnectivityService;
Kweku Adams9da2bb92018-12-20 06:34:39 -08001699 private Constants mConstants;
Kweku Adams799858b2018-10-08 17:19:08 -07001700 private LocationManager mLocationManager;
Kweku Adams00e3a372018-09-28 16:57:09 -07001701
1702 Injector(Context ctx) {
1703 mContext = ctx;
1704 }
1705
1706 AlarmManager getAlarmManager() {
1707 return mContext.getSystemService(AlarmManager.class);
1708 }
1709
1710 AnyMotionDetector getAnyMotionDetector(Handler handler, SensorManager sm,
1711 AnyMotionDetector.DeviceIdleCallback callback, float angleThreshold) {
1712 return new AnyMotionDetector(getPowerManager(), handler, sm, callback, angleThreshold);
1713 }
1714
1715 AppStateTracker getAppStateTracker(Context ctx, Looper looper) {
1716 return new AppStateTracker(ctx, looper);
1717 }
1718
1719 ConnectivityService getConnectivityService() {
Kweku Adams799858b2018-10-08 17:19:08 -07001720 if (mConnectivityService == null) {
1721 mConnectivityService = (ConnectivityService) ServiceManager.getService(
1722 Context.CONNECTIVITY_SERVICE);
1723 }
1724 return mConnectivityService;
Kweku Adams00e3a372018-09-28 16:57:09 -07001725 }
1726
Kweku Adamsa457f4e2018-10-03 15:56:06 -07001727 Constants getConstants(DeviceIdleController controller, Handler handler,
1728 ContentResolver resolver) {
Kweku Adams9da2bb92018-12-20 06:34:39 -08001729 if (mConstants == null) {
1730 mConstants = controller.new Constants(handler, resolver);
1731 }
1732 return mConstants;
Kweku Adamsa457f4e2018-10-03 15:56:06 -07001733 }
1734
Kweku Adams00e3a372018-09-28 16:57:09 -07001735 LocationManager getLocationManager() {
Kweku Adams799858b2018-10-08 17:19:08 -07001736 if (mLocationManager == null) {
1737 mLocationManager = mContext.getSystemService(LocationManager.class);
1738 }
1739 return mLocationManager;
Kweku Adams00e3a372018-09-28 16:57:09 -07001740 }
1741
Kweku Adamsa457f4e2018-10-03 15:56:06 -07001742 MyHandler getHandler(DeviceIdleController controller) {
1743 return controller.new MyHandler(BackgroundThread.getHandler().getLooper());
Kweku Adams00e3a372018-09-28 16:57:09 -07001744 }
1745
1746 PowerManager getPowerManager() {
1747 return mContext.getSystemService(PowerManager.class);
1748 }
Robin Lee876b88542018-11-13 17:22:24 +01001749
1750 SensorManager getSensorManager() {
1751 return mContext.getSystemService(SensorManager.class);
1752 }
1753
1754 ConstraintController getConstraintController(Handler handler, LocalService localService) {
1755 if (mContext.getPackageManager()
1756 .hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY)) {
1757 return new TvConstraintController(mContext, handler);
1758 }
1759 return null;
1760 }
1761
1762 boolean useMotionSensor() {
1763 return mContext.getResources().getBoolean(
1764 com.android.internal.R.bool.config_autoPowerModeUseMotionSensor);
1765 }
Kweku Adams00e3a372018-09-28 16:57:09 -07001766 }
1767
1768 private final Injector mInjector;
1769
Wale Ogunwale6767eae2018-05-03 15:52:51 -07001770 private ActivityTaskManagerInternal.ScreenObserver mScreenObserver =
1771 new ActivityTaskManagerInternal.ScreenObserver() {
Amith Yamasani396a10c2018-01-19 10:58:07 -08001772 @Override
1773 public void onAwakeStateChanged(boolean isAwake) { }
1774
1775 @Override
1776 public void onKeyguardStateChanged(boolean isShowing) {
1777 synchronized (DeviceIdleController.this) {
1778 DeviceIdleController.this.keyguardShowingLocked(isShowing);
1779 }
1780 }
1781 };
1782
Kweku Adams00e3a372018-09-28 16:57:09 -07001783 @VisibleForTesting DeviceIdleController(Context context, Injector injector) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001784 super(context);
Kweku Adams00e3a372018-09-28 16:57:09 -07001785 mInjector = injector;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001786 mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml"));
Kweku Adams00e3a372018-09-28 16:57:09 -07001787 mHandler = mInjector.getHandler(this);
1788 mAppStateTracker = mInjector.getAppStateTracker(context, FgThread.get().getLooper());
Makoto Onukie4918212018-02-06 11:30:15 -08001789 LocalServices.addService(AppStateTracker.class, mAppStateTracker);
Robin Lee876b88542018-11-13 17:22:24 +01001790 mUseMotionSensor = mInjector.useMotionSensor();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001791 }
1792
Kweku Adams00e3a372018-09-28 16:57:09 -07001793 public DeviceIdleController(Context context) {
1794 this(context, new Injector(context));
1795 }
1796
Christopher Tate42a386b2016-11-07 12:21:21 -08001797 boolean isAppOnWhitelistInternal(int appid) {
1798 synchronized (this) {
1799 return Arrays.binarySearch(mPowerSaveWhitelistAllAppIdArray, appid) >= 0;
1800 }
1801 }
1802
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001803 int[] getPowerSaveWhitelistUserAppIds() {
1804 synchronized (this) {
1805 return mPowerSaveWhitelistUserAppIdArray;
1806 }
1807 }
1808
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001809 private static File getSystemDir() {
1810 return new File(Environment.getDataDirectory(), "system");
1811 }
1812
1813 @Override
1814 public void onStart() {
1815 final PackageManager pm = getContext().getPackageManager();
1816
1817 synchronized (this) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08001818 mLightEnabled = mDeepEnabled = getContext().getResources().getBoolean(
Dianne Hackborn92617032015-06-19 15:32:19 -07001819 com.android.internal.R.bool.config_enableAutoPowerModes);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001820 SystemConfig sysConfig = SystemConfig.getInstance();
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001821 ArraySet<String> allowPowerExceptIdle = sysConfig.getAllowInPowerSaveExceptIdle();
1822 for (int i=0; i<allowPowerExceptIdle.size(); i++) {
1823 String pkg = allowPowerExceptIdle.valueAt(i);
1824 try {
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07001825 ApplicationInfo ai = pm.getApplicationInfo(pkg,
1826 PackageManager.MATCH_SYSTEM_ONLY);
1827 int appid = UserHandle.getAppId(ai.uid);
1828 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
1829 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001830 } catch (PackageManager.NameNotFoundException e) {
1831 }
1832 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001833 ArraySet<String> allowPower = sysConfig.getAllowInPowerSave();
1834 for (int i=0; i<allowPower.size(); i++) {
1835 String pkg = allowPower.valueAt(i);
1836 try {
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07001837 ApplicationInfo ai = pm.getApplicationInfo(pkg,
1838 PackageManager.MATCH_SYSTEM_ONLY);
1839 int appid = UserHandle.getAppId(ai.uid);
1840 // These apps are on both the whitelist-except-idle as well
1841 // as the full whitelist, so they apply in all cases.
1842 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
1843 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
1844 mPowerSaveWhitelistApps.put(ai.packageName, appid);
1845 mPowerSaveWhitelistSystemAppIds.put(appid, true);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001846 } catch (PackageManager.NameNotFoundException e) {
1847 }
1848 }
1849
Kweku Adamsa457f4e2018-10-03 15:56:06 -07001850 mConstants = mInjector.getConstants(this, mHandler, getContext().getContentResolver());
Adam Lesinski31c05d12015-06-09 17:34:04 -07001851
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001852 readConfigFileLocked();
1853 updateWhitelistAppIdsLocked();
1854
Dianne Hackborn88c41352016-04-07 15:18:58 -07001855 mNetworkConnected = true;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001856 mScreenOn = true;
Amith Yamasani396a10c2018-01-19 10:58:07 -08001857 mScreenLocked = false;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001858 // Start out assuming we are charging. If we aren't, we will at least get
1859 // a battery update the next time the level drops.
1860 mCharging = true;
Denny cy Leec5a7c292019-01-01 17:37:55 +08001861 mActiveReason = ACTIVE_REASON_UNKNOWN;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001862 mState = STATE_ACTIVE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001863 mLightState = LIGHT_STATE_ACTIVE;
Adam Lesinski31c05d12015-06-09 17:34:04 -07001864 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
Denny cy Leec5a7c292019-01-01 17:37:55 +08001865 mPreIdleFactor = 1.0f;
1866 mLastPreIdleFactor = 1.0f;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001867 }
1868
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001869 mBinderService = new BinderService();
1870 publishBinderService(Context.DEVICE_IDLE_CONTROLLER, mBinderService);
Dianne Hackborna750a632015-06-16 17:18:23 -07001871 publishLocalService(LocalService.class, new LocalService());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001872 }
1873
1874 @Override
1875 public void onBootPhase(int phase) {
1876 if (phase == PHASE_SYSTEM_SERVICES_READY) {
1877 synchronized (this) {
Kweku Adams00e3a372018-09-28 16:57:09 -07001878 mAlarmManager = mInjector.getAlarmManager();
Kweku Adamsb7ce1902019-01-30 10:55:34 -08001879 mLocalAlarmManager = getLocalService(AlarmManagerInternal.class);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001880 mBatteryStats = BatteryStatsService.getService();
Dianne Hackborn85e35642017-01-12 15:10:57 -08001881 mLocalActivityManager = getLocalService(ActivityManagerInternal.class);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07001882 mLocalActivityTaskManager = getLocalService(ActivityTaskManagerInternal.class);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001883 mLocalPowerManager = getLocalService(PowerManagerInternal.class);
Kweku Adams00e3a372018-09-28 16:57:09 -07001884 mPowerManager = mInjector.getPowerManager();
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001885 mActiveIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
1886 "deviceidle_maint");
1887 mActiveIdleWakeLock.setReferenceCounted(false);
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001888 mGoingIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
1889 "deviceidle_going_idle");
1890 mGoingIdleWakeLock.setReferenceCounted(true);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001891 mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface(
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001892 ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07001893 mNetworkPolicyManagerInternal = getLocalService(NetworkPolicyManagerInternal.class);
Robin Lee876b88542018-11-13 17:22:24 +01001894 mSensorManager = mInjector.getSensorManager();
Robin Leec4d424c2018-12-07 15:09:13 +01001895
1896 if (mUseMotionSensor) {
1897 int sigMotionSensorId = getContext().getResources().getInteger(
1898 com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor);
1899 if (sigMotionSensorId > 0) {
1900 mMotionSensor = mSensorManager.getDefaultSensor(sigMotionSensorId, true);
1901 }
1902 if (mMotionSensor == null && getContext().getResources().getBoolean(
1903 com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) {
1904 mMotionSensor = mSensorManager.getDefaultSensor(
1905 Sensor.TYPE_WRIST_TILT_GESTURE, true);
1906 }
1907 if (mMotionSensor == null) {
1908 // As a last ditch, fall back to SMD.
1909 mMotionSensor = mSensorManager.getDefaultSensor(
1910 Sensor.TYPE_SIGNIFICANT_MOTION, true);
1911 }
Joe LaPenna23d681b2015-08-27 15:12:11 -07001912 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001913
Joe LaPenna23d681b2015-08-27 15:12:11 -07001914 if (getContext().getResources().getBoolean(
1915 com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) {
Joe LaPenna23d681b2015-08-27 15:12:11 -07001916 mLocationRequest = new LocationRequest()
1917 .setQuality(LocationRequest.ACCURACY_FINE)
1918 .setInterval(0)
1919 .setFastestInterval(0)
1920 .setNumUpdates(1);
1921 }
1922
Robin Lee876b88542018-11-13 17:22:24 +01001923 mConstraintController = mInjector.getConstraintController(
1924 mHandler, getLocalService(LocalService.class));
1925 if (mConstraintController != null) {
1926 mConstraintController.start();
1927 }
1928
Joe LaPenna23d681b2015-08-27 15:12:11 -07001929 float angleThreshold = getContext().getResources().getInteger(
1930 com.android.internal.R.integer.config_autoPowerModeThresholdAngle) / 100f;
Kweku Adams00e3a372018-09-28 16:57:09 -07001931 mAnyMotionDetector = mInjector.getAnyMotionDetector(mHandler, mSensorManager, this,
1932 angleThreshold);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001933
Makoto Onukie4918212018-02-06 11:30:15 -08001934 mAppStateTracker.onSystemServicesReady();
1935
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001936 mIdleIntent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001937 mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1938 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001939 mLightIdleIntent = new Intent(PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
1940 mLightIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1941 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001942
1943 IntentFilter filter = new IntentFilter();
1944 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001945 getContext().registerReceiver(mReceiver, filter);
Amith Yamasaniac59f75e2016-05-05 12:38:17 -07001946
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07001947 filter = new IntentFilter();
1948 filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
1949 filter.addDataScheme("package");
Amith Yamasaniac59f75e2016-05-05 12:38:17 -07001950 getContext().registerReceiver(mReceiver, filter);
1951
Dianne Hackborn88c41352016-04-07 15:18:58 -07001952 filter = new IntentFilter();
1953 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07001954 getContext().registerReceiver(mReceiver, filter);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001955
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -07001956 filter = new IntentFilter();
1957 filter.addAction(Intent.ACTION_SCREEN_OFF);
1958 filter.addAction(Intent.ACTION_SCREEN_ON);
1959 getContext().registerReceiver(mInteractivityReceiver, filter);
1960
Makoto Onukiaf8ff4f2018-06-04 14:44:19 -07001961 mLocalActivityManager.setDeviceIdleWhitelist(
1962 mPowerSaveWhitelistAllAppIdArray, mPowerSaveWhitelistExceptIdleAppIdArray);
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001963 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -07001964
Kweku Adamsb396ccf2018-09-17 16:37:15 -07001965 mLocalPowerManager.registerLowPowerModeObserver(ServiceType.QUICK_DOZE,
1966 state -> {
1967 synchronized (DeviceIdleController.this) {
1968 updateQuickDozeFlagLocked(state.batterySaverEnabled);
1969 }
1970 });
1971 updateQuickDozeFlagLocked(
1972 mLocalPowerManager.getLowPowerState(
1973 ServiceType.QUICK_DOZE).batterySaverEnabled);
1974
Wale Ogunwale6767eae2018-05-03 15:52:51 -07001975 mLocalActivityTaskManager.registerScreenObserver(mScreenObserver);
Amith Yamasani396a10c2018-01-19 10:58:07 -08001976
Suprabh Shukla5bf49812018-05-24 18:38:50 -07001977 passWhiteListsToForceAppStandbyTrackerLocked();
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -07001978 updateInteractivityLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001979 }
Dianne Hackborn4cb96ca2016-05-17 13:55:29 -07001980 updateConnectivityState(null);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001981 }
1982 }
1983
Robin Lee876b88542018-11-13 17:22:24 +01001984 @VisibleForTesting
1985 boolean hasMotionSensor() {
1986 return mUseMotionSensor && mMotionSensor != null;
1987 }
1988
1989 private void registerDeviceIdleConstraintInternal(IDeviceIdleConstraint constraint,
1990 final String name, final int type) {
1991 final int minState;
1992 switch (type) {
1993 case IDeviceIdleConstraint.ACTIVE:
1994 minState = STATE_ACTIVE;
1995 break;
1996 case IDeviceIdleConstraint.SENSING_OR_ABOVE:
1997 minState = STATE_SENSING;
1998 break;
1999 default:
2000 Slog.wtf(TAG, "Registering device-idle constraint with invalid type: " + type);
2001 return;
2002 }
2003 synchronized (this) {
2004 if (mConstraints.containsKey(constraint)) {
2005 Slog.e(TAG, "Re-registering device-idle constraint: " + constraint + ".");
2006 return;
2007 }
2008 DeviceIdleConstraintTracker tracker = new DeviceIdleConstraintTracker(name, minState);
2009 mConstraints.put(constraint, tracker);
2010 updateActiveConstraintsLocked();
2011 }
2012 }
2013
2014 private void unregisterDeviceIdleConstraintInternal(IDeviceIdleConstraint constraint) {
2015 synchronized (this) {
2016 // Artifically force the constraint to inactive to unblock anything waiting for it.
2017 onConstraintStateChangedLocked(constraint, /* active= */ false);
2018
2019 // Let the constraint know that we are not listening to it any more.
2020 setConstraintMonitoringLocked(constraint, /* monitoring= */ false);
2021 mConstraints.remove(constraint);
2022 }
2023 }
2024
2025 @GuardedBy("this")
2026 private void onConstraintStateChangedLocked(IDeviceIdleConstraint constraint, boolean active) {
2027 DeviceIdleConstraintTracker tracker = mConstraints.get(constraint);
2028 if (tracker == null) {
2029 Slog.e(TAG, "device-idle constraint " + constraint + " has not been registered.");
2030 return;
2031 }
2032 if (active != tracker.active && tracker.monitoring) {
2033 tracker.active = active;
2034 mNumBlockingConstraints += (tracker.active ? +1 : -1);
2035 if (mNumBlockingConstraints == 0) {
2036 if (mState == STATE_ACTIVE) {
2037 becomeInactiveIfAppropriateLocked();
2038 } else if (mNextAlarmTime == 0 || mNextAlarmTime < SystemClock.elapsedRealtime()) {
2039 stepIdleStateLocked("s:" + tracker.name);
2040 }
2041 }
2042 }
2043 }
2044
2045 @GuardedBy("this")
2046 private void setConstraintMonitoringLocked(IDeviceIdleConstraint constraint, boolean monitor) {
2047 DeviceIdleConstraintTracker tracker = mConstraints.get(constraint);
2048 if (tracker.monitoring != monitor) {
2049 tracker.monitoring = monitor;
2050 updateActiveConstraintsLocked();
2051 // We send the callback on a separate thread instead of just relying on oneway as
2052 // the client could be in the system server with us and cause re-entry problems.
2053 mHandler.obtainMessage(MSG_SEND_CONSTRAINT_MONITORING,
2054 /* monitoring= */ monitor ? 1 : 0,
2055 /* <not used>= */ -1,
2056 /* constraint= */ constraint).sendToTarget();
2057 }
2058 }
2059
2060 @GuardedBy("this")
2061 private void updateActiveConstraintsLocked() {
2062 mNumBlockingConstraints = 0;
2063 for (int i = 0; i < mConstraints.size(); i++) {
2064 final IDeviceIdleConstraint constraint = mConstraints.keyAt(i);
2065 final DeviceIdleConstraintTracker tracker = mConstraints.valueAt(i);
2066 final boolean monitoring = (tracker.minState == mState);
2067 if (monitoring != tracker.monitoring) {
2068 setConstraintMonitoringLocked(constraint, monitoring);
2069 tracker.active = monitoring;
2070 }
2071 if (tracker.monitoring && tracker.active) {
2072 mNumBlockingConstraints++;
2073 }
2074 }
2075 }
2076
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002077 public boolean addPowerSaveWhitelistAppInternal(String name) {
2078 synchronized (this) {
2079 try {
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07002080 ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name,
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -07002081 PackageManager.MATCH_ANY_USER);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002082 if (mPowerSaveWhitelistUserApps.put(name, UserHandle.getAppId(ai.uid)) == null) {
2083 reportPowerSaveWhitelistChangedLocked();
2084 updateWhitelistAppIdsLocked();
2085 writeConfigFileLocked();
2086 }
2087 return true;
2088 } catch (PackageManager.NameNotFoundException e) {
2089 return false;
2090 }
2091 }
2092 }
2093
2094 public boolean removePowerSaveWhitelistAppInternal(String name) {
2095 synchronized (this) {
2096 if (mPowerSaveWhitelistUserApps.remove(name) != null) {
2097 reportPowerSaveWhitelistChangedLocked();
2098 updateWhitelistAppIdsLocked();
2099 writeConfigFileLocked();
2100 return true;
2101 }
2102 }
2103 return false;
2104 }
2105
Felipe Lemef8a46232016-02-10 13:51:54 -08002106 public boolean getPowerSaveWhitelistAppInternal(String name) {
2107 synchronized (this) {
2108 return mPowerSaveWhitelistUserApps.containsKey(name);
2109 }
2110 }
2111
Suprabh Shukla08105642017-09-26 14:45:30 -07002112 void resetSystemPowerWhitelistInternal() {
2113 synchronized (this) {
2114 mPowerSaveWhitelistApps.putAll(mRemovedFromSystemWhitelistApps);
2115 mRemovedFromSystemWhitelistApps.clear();
2116 reportPowerSaveWhitelistChangedLocked();
2117 updateWhitelistAppIdsLocked();
2118 writeConfigFileLocked();
2119 }
2120 }
2121
2122 public boolean restoreSystemPowerWhitelistAppInternal(String name) {
2123 synchronized (this) {
2124 if (!mRemovedFromSystemWhitelistApps.containsKey(name)) {
2125 return false;
2126 }
2127 mPowerSaveWhitelistApps.put(name, mRemovedFromSystemWhitelistApps.remove(name));
2128 reportPowerSaveWhitelistChangedLocked();
2129 updateWhitelistAppIdsLocked();
2130 writeConfigFileLocked();
2131 return true;
2132 }
2133 }
2134
2135 public boolean removeSystemPowerWhitelistAppInternal(String name) {
2136 synchronized (this) {
2137 if (!mPowerSaveWhitelistApps.containsKey(name)) {
2138 return false;
2139 }
2140 mRemovedFromSystemWhitelistApps.put(name, mPowerSaveWhitelistApps.remove(name));
2141 reportPowerSaveWhitelistChangedLocked();
2142 updateWhitelistAppIdsLocked();
2143 writeConfigFileLocked();
2144 return true;
2145 }
2146 }
2147
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07002148 public boolean addPowerSaveWhitelistExceptIdleInternal(String name) {
2149 synchronized (this) {
2150 try {
2151 final ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name,
2152 PackageManager.MATCH_ANY_USER);
2153 if (mPowerSaveWhitelistAppsExceptIdle.put(name, UserHandle.getAppId(ai.uid))
2154 == null) {
2155 mPowerSaveWhitelistUserAppsExceptIdle.add(name);
2156 reportPowerSaveWhitelistChangedLocked();
2157 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(
2158 mPowerSaveWhitelistAppsExceptIdle, mPowerSaveWhitelistUserApps,
2159 mPowerSaveWhitelistExceptIdleAppIds);
Makoto Onuki71755c92018-01-16 14:15:44 -08002160
Suprabh Shukla5bf49812018-05-24 18:38:50 -07002161 passWhiteListsToForceAppStandbyTrackerLocked();
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07002162 }
2163 return true;
2164 } catch (PackageManager.NameNotFoundException e) {
2165 return false;
2166 }
2167 }
2168 }
2169
2170 public void resetPowerSaveWhitelistExceptIdleInternal() {
2171 synchronized (this) {
2172 if (mPowerSaveWhitelistAppsExceptIdle.removeAll(
2173 mPowerSaveWhitelistUserAppsExceptIdle)) {
2174 reportPowerSaveWhitelistChangedLocked();
2175 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(
2176 mPowerSaveWhitelistAppsExceptIdle, mPowerSaveWhitelistUserApps,
2177 mPowerSaveWhitelistExceptIdleAppIds);
2178 mPowerSaveWhitelistUserAppsExceptIdle.clear();
Makoto Onuki71755c92018-01-16 14:15:44 -08002179
Suprabh Shukla5bf49812018-05-24 18:38:50 -07002180 passWhiteListsToForceAppStandbyTrackerLocked();
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07002181 }
2182 }
2183 }
2184
2185 public boolean getPowerSaveWhitelistExceptIdleInternal(String name) {
2186 synchronized (this) {
2187 return mPowerSaveWhitelistAppsExceptIdle.containsKey(name);
2188 }
2189 }
2190
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002191 public String[] getSystemPowerWhitelistExceptIdleInternal() {
2192 synchronized (this) {
2193 int size = mPowerSaveWhitelistAppsExceptIdle.size();
2194 String[] apps = new String[size];
2195 for (int i = 0; i < size; i++) {
2196 apps[i] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i);
2197 }
2198 return apps;
2199 }
2200 }
2201
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002202 public String[] getSystemPowerWhitelistInternal() {
2203 synchronized (this) {
2204 int size = mPowerSaveWhitelistApps.size();
2205 String[] apps = new String[size];
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002206 for (int i = 0; i < size; i++) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002207 apps[i] = mPowerSaveWhitelistApps.keyAt(i);
2208 }
2209 return apps;
2210 }
2211 }
2212
Suprabh Shukla08105642017-09-26 14:45:30 -07002213 public String[] getRemovedSystemPowerWhitelistAppsInternal() {
2214 synchronized (this) {
2215 int size = mRemovedFromSystemWhitelistApps.size();
2216 final String[] apps = new String[size];
2217 for (int i = 0; i < size; i++) {
2218 apps[i] = mRemovedFromSystemWhitelistApps.keyAt(i);
2219 }
2220 return apps;
2221 }
2222 }
2223
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002224 public String[] getUserPowerWhitelistInternal() {
2225 synchronized (this) {
2226 int size = mPowerSaveWhitelistUserApps.size();
2227 String[] apps = new String[size];
2228 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
2229 apps[i] = mPowerSaveWhitelistUserApps.keyAt(i);
2230 }
2231 return apps;
2232 }
2233 }
2234
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002235 public String[] getFullPowerWhitelistExceptIdleInternal() {
2236 synchronized (this) {
2237 int size = mPowerSaveWhitelistAppsExceptIdle.size() + mPowerSaveWhitelistUserApps.size();
2238 String[] apps = new String[size];
2239 int cur = 0;
2240 for (int i = 0; i < mPowerSaveWhitelistAppsExceptIdle.size(); i++) {
2241 apps[cur] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i);
2242 cur++;
2243 }
2244 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
2245 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i);
2246 cur++;
2247 }
2248 return apps;
2249 }
2250 }
2251
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002252 public String[] getFullPowerWhitelistInternal() {
2253 synchronized (this) {
2254 int size = mPowerSaveWhitelistApps.size() + mPowerSaveWhitelistUserApps.size();
2255 String[] apps = new String[size];
2256 int cur = 0;
2257 for (int i = 0; i < mPowerSaveWhitelistApps.size(); i++) {
2258 apps[cur] = mPowerSaveWhitelistApps.keyAt(i);
2259 cur++;
2260 }
2261 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
2262 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i);
2263 cur++;
2264 }
2265 return apps;
2266 }
2267 }
2268
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002269 public boolean isPowerSaveWhitelistExceptIdleAppInternal(String packageName) {
2270 synchronized (this) {
2271 return mPowerSaveWhitelistAppsExceptIdle.containsKey(packageName)
2272 || mPowerSaveWhitelistUserApps.containsKey(packageName);
2273 }
2274 }
2275
Amith Yamasani06bf8242015-05-08 16:36:21 -07002276 public boolean isPowerSaveWhitelistAppInternal(String packageName) {
2277 synchronized (this) {
2278 return mPowerSaveWhitelistApps.containsKey(packageName)
2279 || mPowerSaveWhitelistUserApps.containsKey(packageName);
2280 }
2281 }
2282
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002283 public int[] getAppIdWhitelistExceptIdleInternal() {
2284 synchronized (this) {
2285 return mPowerSaveWhitelistExceptIdleAppIdArray;
2286 }
2287 }
2288
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002289 public int[] getAppIdWhitelistInternal() {
2290 synchronized (this) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002291 return mPowerSaveWhitelistAllAppIdArray;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002292 }
2293 }
2294
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002295 public int[] getAppIdUserWhitelistInternal() {
2296 synchronized (this) {
2297 return mPowerSaveWhitelistUserAppIdArray;
2298 }
2299 }
2300
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002301 public int[] getAppIdTempWhitelistInternal() {
2302 synchronized (this) {
2303 return mTempWhitelistAppIdArray;
2304 }
2305 }
2306
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002307 void addPowerSaveTempWhitelistAppChecked(String packageName, long duration,
2308 int userId, String reason) throws RemoteException {
2309 getContext().enforceCallingPermission(
2310 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
2311 "No permission to change device idle whitelist");
2312 final int callingUid = Binder.getCallingUid();
Sudheer Shankadc589ac2016-11-10 15:30:17 -08002313 userId = ActivityManager.getService().handleIncomingUser(
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002314 Binder.getCallingPid(),
2315 callingUid,
2316 userId,
2317 /*allowAll=*/ false,
2318 /*requireFull=*/ false,
2319 "addPowerSaveTempWhitelistApp", null);
2320 final long token = Binder.clearCallingIdentity();
2321 try {
2322 addPowerSaveTempWhitelistAppInternal(callingUid,
2323 packageName, duration, userId, true, reason);
2324 } finally {
2325 Binder.restoreCallingIdentity(token);
2326 }
2327 }
2328
Sudheer Shanka326b3112017-11-27 14:40:57 -08002329 void removePowerSaveTempWhitelistAppChecked(String packageName, int userId)
2330 throws RemoteException {
2331 getContext().enforceCallingPermission(
2332 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
2333 "No permission to change device idle whitelist");
2334 final int callingUid = Binder.getCallingUid();
2335 userId = ActivityManager.getService().handleIncomingUser(
2336 Binder.getCallingPid(),
2337 callingUid,
2338 userId,
2339 /*allowAll=*/ false,
2340 /*requireFull=*/ false,
2341 "removePowerSaveTempWhitelistApp", null);
2342 final long token = Binder.clearCallingIdentity();
2343 try {
2344 removePowerSaveTempWhitelistAppInternal(packageName, userId);
2345 } finally {
2346 Binder.restoreCallingIdentity(token);
2347 }
2348 }
2349
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002350 /**
2351 * Adds an app to the temporary whitelist and resets the endTime for granting the
2352 * app an exemption to access network and acquire wakelocks.
2353 */
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002354 void addPowerSaveTempWhitelistAppInternal(int callingUid, String packageName,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002355 long duration, int userId, boolean sync, String reason) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002356 try {
Jeff Sharkeye06b4d12016-01-06 14:51:50 -07002357 int uid = getContext().getPackageManager().getPackageUidAsUser(packageName, userId);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002358 int appId = UserHandle.getAppId(uid);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002359 addPowerSaveTempWhitelistAppDirectInternal(callingUid, appId, duration, sync, reason);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002360 } catch (NameNotFoundException e) {
2361 }
2362 }
2363
Dianne Hackborna750a632015-06-16 17:18:23 -07002364 /**
2365 * Adds an app to the temporary whitelist and resets the endTime for granting the
2366 * app an exemption to access network and acquire wakelocks.
2367 */
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002368 void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int appId,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002369 long duration, boolean sync, String reason) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002370 final long timeNow = SystemClock.elapsedRealtime();
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07002371 boolean informWhitelistChanged = false;
Dianne Hackborna750a632015-06-16 17:18:23 -07002372 synchronized (this) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002373 int callingAppId = UserHandle.getAppId(callingUid);
2374 if (callingAppId >= Process.FIRST_APPLICATION_UID) {
2375 if (!mPowerSaveWhitelistSystemAppIds.get(callingAppId)) {
2376 throw new SecurityException("Calling app " + UserHandle.formatUid(callingUid)
2377 + " is not on whitelist");
2378 }
2379 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002380 duration = Math.min(duration, mConstants.MAX_TEMP_APP_WHITELIST_DURATION);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002381 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId);
2382 final boolean newEntry = entry == null;
Dianne Hackborna750a632015-06-16 17:18:23 -07002383 // Set the new end time
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002384 if (newEntry) {
2385 entry = new Pair<>(new MutableLong(0), reason);
2386 mTempWhitelistAppIdEndTimes.put(appId, entry);
2387 }
2388 entry.first.value = timeNow + duration;
Dianne Hackborna750a632015-06-16 17:18:23 -07002389 if (DEBUG) {
Felipe Lemea1b79bf2016-05-24 13:06:54 -07002390 Slog.d(TAG, "Adding AppId " + appId + " to temp whitelist. New entry: " + newEntry);
Dianne Hackborna750a632015-06-16 17:18:23 -07002391 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002392 if (newEntry) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002393 // No pending timeout for the app id, post a delayed message
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002394 try {
2395 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_START,
2396 reason, appId);
2397 } catch (RemoteException e) {
2398 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002399 postTempActiveTimeoutMessage(appId, duration);
Dianne Hackborn85e35642017-01-12 15:10:57 -08002400 updateTempWhitelistAppIdsLocked(appId, true);
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07002401 if (sync) {
2402 informWhitelistChanged = true;
2403 } else {
2404 mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED, appId, 1)
2405 .sendToTarget();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002406 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002407 reportTempWhitelistChangedLocked();
2408 }
2409 }
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07002410 if (informWhitelistChanged) {
2411 mNetworkPolicyManagerInternal.onTempPowerSaveWhitelistChange(appId, true);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002412 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002413 }
2414
Sudheer Shanka326b3112017-11-27 14:40:57 -08002415 /**
2416 * Removes an app from the temporary whitelist and notifies the observers.
2417 */
2418 private void removePowerSaveTempWhitelistAppInternal(String packageName, int userId) {
2419 try {
2420 final int uid = getContext().getPackageManager().getPackageUidAsUser(
2421 packageName, userId);
2422 final int appId = UserHandle.getAppId(uid);
2423 removePowerSaveTempWhitelistAppDirectInternal(appId);
2424 } catch (NameNotFoundException e) {
2425 }
2426 }
2427
2428 private void removePowerSaveTempWhitelistAppDirectInternal(int appId) {
2429 synchronized (this) {
2430 final int idx = mTempWhitelistAppIdEndTimes.indexOfKey(appId);
2431 if (idx < 0) {
2432 // Nothing else to do
2433 return;
2434 }
2435 final String reason = mTempWhitelistAppIdEndTimes.valueAt(idx).second;
2436 mTempWhitelistAppIdEndTimes.removeAt(idx);
2437 onAppRemovedFromTempWhitelistLocked(appId, reason);
2438 }
2439 }
2440
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002441 private void postTempActiveTimeoutMessage(int uid, long delay) {
Felipe Lemea1b79bf2016-05-24 13:06:54 -07002442 if (DEBUG) {
2443 Slog.d(TAG, "postTempActiveTimeoutMessage: uid=" + uid + ", delay=" + delay);
2444 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002445 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, uid, 0),
2446 delay);
2447 }
2448
2449 void checkTempAppWhitelistTimeout(int uid) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002450 final long timeNow = SystemClock.elapsedRealtime();
Felipe Lemea1b79bf2016-05-24 13:06:54 -07002451 if (DEBUG) {
2452 Slog.d(TAG, "checkTempAppWhitelistTimeout: uid=" + uid + ", timeNow=" + timeNow);
2453 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002454 synchronized (this) {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002455 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(uid);
2456 if (entry == null) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002457 // Nothing to do
2458 return;
2459 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002460 if (timeNow >= entry.first.value) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002461 mTempWhitelistAppIdEndTimes.delete(uid);
Sudheer Shanka326b3112017-11-27 14:40:57 -08002462 onAppRemovedFromTempWhitelistLocked(uid, entry.second);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002463 } else {
2464 // Need more time
Felipe Lemea1b79bf2016-05-24 13:06:54 -07002465 if (DEBUG) {
2466 Slog.d(TAG, "Time to remove UID " + uid + ": " + entry.first.value);
2467 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002468 postTempActiveTimeoutMessage(uid, entry.first.value - timeNow);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002469 }
2470 }
2471 }
2472
Sudheer Shanka326b3112017-11-27 14:40:57 -08002473 @GuardedBy("this")
2474 private void onAppRemovedFromTempWhitelistLocked(int appId, String reason) {
2475 if (DEBUG) {
2476 Slog.d(TAG, "Removing appId " + appId + " from temp whitelist");
2477 }
2478 updateTempWhitelistAppIdsLocked(appId, false);
2479 mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED, appId, 0)
2480 .sendToTarget();
2481 reportTempWhitelistChangedLocked();
2482 try {
2483 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH,
2484 reason, appId);
2485 } catch (RemoteException e) {
2486 }
2487 }
2488
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002489 public void exitIdleInternal(String reason) {
2490 synchronized (this) {
Denny cy Leec5a7c292019-01-01 17:37:55 +08002491 mActiveReason = ACTIVE_REASON_FROM_BINDER_CALL;
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002492 becomeActiveLocked(reason, Binder.getCallingUid());
2493 }
2494 }
2495
Kweku Adams799858b2018-10-08 17:19:08 -07002496 @VisibleForTesting
2497 boolean isNetworkConnected() {
2498 synchronized (this) {
2499 return mNetworkConnected;
2500 }
2501 }
2502
Dianne Hackborn4cb96ca2016-05-17 13:55:29 -07002503 void updateConnectivityState(Intent connIntent) {
2504 ConnectivityService cm;
2505 synchronized (this) {
Kweku Adams799858b2018-10-08 17:19:08 -07002506 cm = mInjector.getConnectivityService();
Dianne Hackborn4cb96ca2016-05-17 13:55:29 -07002507 }
2508 if (cm == null) {
2509 return;
2510 }
2511 // Note: can't call out to ConnectivityService with our lock held.
2512 NetworkInfo ni = cm.getActiveNetworkInfo();
2513 synchronized (this) {
Dianne Hackborn88c41352016-04-07 15:18:58 -07002514 boolean conn;
2515 if (ni == null) {
2516 conn = false;
2517 } else {
2518 if (connIntent == null) {
2519 conn = ni.isConnected();
2520 } else {
2521 final int networkType =
2522 connIntent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE,
2523 ConnectivityManager.TYPE_NONE);
2524 if (ni.getType() != networkType) {
2525 return;
2526 }
2527 conn = !connIntent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,
2528 false);
2529 }
2530 }
2531 if (conn != mNetworkConnected) {
2532 mNetworkConnected = conn;
2533 if (conn && mLightState == LIGHT_STATE_WAITING_FOR_NETWORK) {
2534 stepLightIdleStateLocked("network");
2535 }
2536 }
2537 }
2538 }
2539
Kweku Adams00e3a372018-09-28 16:57:09 -07002540 @VisibleForTesting
2541 boolean isScreenOn() {
Kweku Adamsb396ccf2018-09-17 16:37:15 -07002542 synchronized (this) {
2543 return mScreenOn;
2544 }
Kweku Adams00e3a372018-09-28 16:57:09 -07002545 }
2546
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -07002547 void updateInteractivityLocked() {
2548 // The interactivity state from the power manager tells us whether the display is
2549 // in a state that we need to keep things running so they will update at a normal
2550 // frequency.
2551 boolean screenOn = mPowerManager.isInteractive();
2552 if (DEBUG) Slog.d(TAG, "updateInteractivityLocked: screenOn=" + screenOn);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002553 if (!screenOn && mScreenOn) {
2554 mScreenOn = false;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002555 if (!mForceIdle) {
2556 becomeInactiveIfAppropriateLocked();
2557 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002558 } else if (screenOn) {
2559 mScreenOn = true;
Amith Yamasani396a10c2018-01-19 10:58:07 -08002560 if (!mForceIdle && (!mScreenLocked || !mConstants.WAIT_FOR_UNLOCK)) {
Denny cy Leec5a7c292019-01-01 17:37:55 +08002561 mActiveReason = ACTIVE_REASON_SCREEN;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002562 becomeActiveLocked("screen", Process.myUid());
2563 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002564 }
2565 }
2566
Kweku Adams00e3a372018-09-28 16:57:09 -07002567 @VisibleForTesting
2568 boolean isCharging() {
Kweku Adamsb396ccf2018-09-17 16:37:15 -07002569 synchronized (this) {
2570 return mCharging;
2571 }
Kweku Adams00e3a372018-09-28 16:57:09 -07002572 }
2573
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002574 void updateChargingLocked(boolean charging) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002575 if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002576 if (!charging && mCharging) {
2577 mCharging = false;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002578 if (!mForceIdle) {
2579 becomeInactiveIfAppropriateLocked();
2580 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002581 } else if (charging) {
2582 mCharging = charging;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002583 if (!mForceIdle) {
Denny cy Leec5a7c292019-01-01 17:37:55 +08002584 mActiveReason = ACTIVE_REASON_CHARGING;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002585 becomeActiveLocked("charging", Process.myUid());
2586 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002587 }
2588 }
2589
Kweku Adamsb396ccf2018-09-17 16:37:15 -07002590 @VisibleForTesting
2591 boolean isQuickDozeEnabled() {
2592 synchronized (this) {
2593 return mQuickDozeActivated;
2594 }
2595 }
2596
2597 /** Updates the quick doze flag and enters deep doze if appropriate. */
2598 @VisibleForTesting
2599 void updateQuickDozeFlagLocked(boolean enabled) {
2600 if (DEBUG) Slog.i(TAG, "updateQuickDozeFlagLocked: enabled=" + enabled);
2601 mQuickDozeActivated = enabled;
2602 if (enabled) {
2603 // If Quick Doze is enabled, see if we should go straight into it.
2604 becomeInactiveIfAppropriateLocked();
2605 }
2606 // Going from Deep Doze to Light Idle (if quick doze becomes disabled) is tricky and
2607 // probably not worth the overhead, so leave in deep doze if that's the case until the
2608 // next natural time to come out of it.
2609 }
2610
Kweku Adamsb7ce1902019-01-30 10:55:34 -08002611
2612 /** Returns true if the screen is locked. */
2613 @VisibleForTesting
2614 boolean isKeyguardShowing() {
2615 synchronized (this) {
2616 return mScreenLocked;
2617 }
2618 }
2619
2620 @VisibleForTesting
Amith Yamasani396a10c2018-01-19 10:58:07 -08002621 void keyguardShowingLocked(boolean showing) {
2622 if (DEBUG) Slog.i(TAG, "keyguardShowing=" + showing);
2623 if (mScreenLocked != showing) {
2624 mScreenLocked = showing;
2625 if (mScreenOn && !mForceIdle && !mScreenLocked) {
Denny cy Leec5a7c292019-01-01 17:37:55 +08002626 mActiveReason = ACTIVE_REASON_UNLOCKED;
Amith Yamasani396a10c2018-01-19 10:58:07 -08002627 becomeActiveLocked("unlocked", Process.myUid());
2628 }
2629 }
2630 }
2631
Kweku Adamsb7ce1902019-01-30 10:55:34 -08002632 @VisibleForTesting
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002633 void scheduleReportActiveLocked(String activeReason, int activeUid) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002634 Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid, 0, activeReason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002635 mHandler.sendMessage(msg);
2636 }
2637
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002638 void becomeActiveLocked(String activeReason, int activeUid) {
Kweku Adamsb7ce1902019-01-30 10:55:34 -08002639 becomeActiveLocked(activeReason, activeUid, mConstants.INACTIVE_TIMEOUT, true);
2640 }
2641
2642 private void becomeActiveLocked(String activeReason, int activeUid,
2643 long newInactiveTimeout, boolean changeLightIdle) {
2644 if (DEBUG) {
2645 Slog.i(TAG, "becomeActiveLocked, reason=" + activeReason
2646 + ", changeLightIdle=" + changeLightIdle);
2647 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002648 if (mState != STATE_ACTIVE || mLightState != STATE_ACTIVE) {
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002649 EventLogTags.writeDeviceIdle(STATE_ACTIVE, activeReason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002650 mState = STATE_ACTIVE;
Kweku Adamsb7ce1902019-01-30 10:55:34 -08002651 mInactiveTimeout = newInactiveTimeout;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002652 mCurIdleBudget = 0;
2653 mMaintenanceStartTime = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002654 resetIdleManagementLocked();
Kweku Adamsb7ce1902019-01-30 10:55:34 -08002655
2656 if (changeLightIdle) {
2657 EventLogTags.writeDeviceIdleLight(LIGHT_STATE_ACTIVE, activeReason);
2658 mLightState = LIGHT_STATE_ACTIVE;
2659 resetLightIdleManagementLocked();
2660 // Only report active if light is also ACTIVE.
2661 scheduleReportActiveLocked(activeReason, activeUid);
2662 addEvent(EVENT_NORMAL, activeReason);
2663 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002664 }
2665 }
2666
Kweku Adams00e3a372018-09-28 16:57:09 -07002667 /** Must only be used in tests. */
2668 @VisibleForTesting
2669 void setDeepEnabledForTest(boolean enabled) {
Kweku Adams799858b2018-10-08 17:19:08 -07002670 synchronized (this) {
2671 mDeepEnabled = enabled;
2672 }
Kweku Adams00e3a372018-09-28 16:57:09 -07002673 }
2674
2675 /** Must only be used in tests. */
2676 @VisibleForTesting
2677 void setLightEnabledForTest(boolean enabled) {
Kweku Adams799858b2018-10-08 17:19:08 -07002678 synchronized (this) {
2679 mLightEnabled = enabled;
2680 }
Kweku Adams00e3a372018-09-28 16:57:09 -07002681 }
2682
Kweku Adamsb7ce1902019-01-30 10:55:34 -08002683 /** Sanity check to make sure DeviceIdleController and AlarmManager are on the same page. */
2684 private void verifyAlarmStateLocked() {
2685 if (mState == STATE_ACTIVE && mNextAlarmTime != 0) {
2686 Slog.wtf(TAG, "mState=ACTIVE but mNextAlarmTime=" + mNextAlarmTime);
2687 }
2688 if (mState != STATE_IDLE && mLocalAlarmManager.isIdling()) {
2689 Slog.wtf(TAG, "mState=" + stateToString(mState) + " but AlarmManager is idling");
2690 }
2691 if (mState == STATE_IDLE && !mLocalAlarmManager.isIdling()) {
2692 Slog.wtf(TAG, "mState=IDLE but AlarmManager is not idling");
2693 }
2694 if (mLightState == LIGHT_STATE_ACTIVE && mNextLightAlarmTime != 0) {
2695 Slog.wtf(TAG, "mLightState=ACTIVE but mNextLightAlarmTime is "
2696 + TimeUtils.formatDuration(mNextLightAlarmTime - SystemClock.elapsedRealtime())
2697 + " from now");
2698 }
2699 }
2700
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002701 void becomeInactiveIfAppropriateLocked() {
Kweku Adamsb7ce1902019-01-30 10:55:34 -08002702 verifyAlarmStateLocked();
2703
2704 final boolean isScreenBlockingInactive =
2705 mScreenOn && (!mConstants.WAIT_FOR_UNLOCK || !mScreenLocked);
2706 if (DEBUG) {
2707 Slog.d(TAG, "becomeInactiveIfAppropriateLocked():"
2708 + " isScreenBlockingInactive=" + isScreenBlockingInactive
2709 + " (mScreenOn=" + mScreenOn
2710 + ", WAIT_FOR_UNLOCK=" + mConstants.WAIT_FOR_UNLOCK
2711 + ", mScreenLocked=" + mScreenLocked + ")"
2712 + " mCharging=" + mCharging
2713 + " mForceIdle=" + mForceIdle
2714 );
2715 }
2716 if (!mForceIdle && (mCharging || isScreenBlockingInactive)) {
2717 return;
2718 }
2719 // Become inactive and determine if we will ultimately go idle.
2720 if (mDeepEnabled) {
2721 if (mQuickDozeActivated) {
2722 if (mState == STATE_QUICK_DOZE_DELAY || mState == STATE_IDLE
2723 || mState == STATE_IDLE_MAINTENANCE) {
2724 // Already "idling". Don't want to restart the process.
2725 // mLightState can't be LIGHT_STATE_ACTIVE if mState is any of these 3
2726 // values, so returning here is safe.
2727 return;
Kweku Adamsb396ccf2018-09-17 16:37:15 -07002728 }
Kweku Adamsb7ce1902019-01-30 10:55:34 -08002729 if (DEBUG) {
2730 Slog.d(TAG, "Moved from "
2731 + stateToString(mState) + " to STATE_QUICK_DOZE_DELAY");
2732 }
2733 mState = STATE_QUICK_DOZE_DELAY;
2734 // Make sure any motion sensing or locating is stopped.
2735 resetIdleManagementLocked();
2736 // Wait a small amount of time in case something (eg: background service from
2737 // recently closed app) needs to finish running.
2738 scheduleAlarmLocked(mConstants.QUICK_DOZE_DELAY_TIMEOUT, false);
2739 EventLogTags.writeDeviceIdle(mState, "no activity");
2740 } else if (mState == STATE_ACTIVE) {
2741 mState = STATE_INACTIVE;
2742 if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE");
2743 resetIdleManagementLocked();
2744 long delay = mInactiveTimeout;
2745 if (shouldUseIdleTimeoutFactorLocked()) {
2746 delay = (long) (mPreIdleFactor * delay);
2747 }
2748 scheduleAlarmLocked(delay, false);
2749 EventLogTags.writeDeviceIdle(mState, "no activity");
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002750 }
Kweku Adamsb7ce1902019-01-30 10:55:34 -08002751 }
2752 if (mLightState == LIGHT_STATE_ACTIVE && mLightEnabled) {
2753 mLightState = LIGHT_STATE_INACTIVE;
2754 if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE");
2755 resetLightIdleManagementLocked();
2756 scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT);
2757 EventLogTags.writeDeviceIdleLight(mLightState, "no activity");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002758 }
2759 }
2760
Kweku Adams00e3a372018-09-28 16:57:09 -07002761 private void resetIdleManagementLocked() {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002762 mNextIdlePendingDelay = 0;
2763 mNextIdleDelay = 0;
Dianne Hackborn953fc942016-03-29 15:36:24 -07002764 mNextLightIdleDelay = 0;
Denny cy Leec5a7c292019-01-01 17:37:55 +08002765 mIdleStartTime = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002766 cancelAlarmLocked();
Kevin Gabayan92f15e62016-04-04 17:52:22 -07002767 cancelSensingTimeoutAlarmLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002768 cancelLocatingLocked();
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002769 stopMonitoringMotionLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002770 mAnyMotionDetector.stop();
Robin Lee876b88542018-11-13 17:22:24 +01002771 updateActiveConstraintsLocked();
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002772 }
2773
Kweku Adams00e3a372018-09-28 16:57:09 -07002774 private void resetLightIdleManagementLocked() {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002775 cancelLightAlarmLocked();
2776 }
2777
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002778 void exitForceIdleLocked() {
2779 if (mForceIdle) {
2780 mForceIdle = false;
2781 if (mScreenOn || mCharging) {
Denny cy Leec5a7c292019-01-01 17:37:55 +08002782 mActiveReason = ACTIVE_REASON_FORCED;
Dianne Hackborn88c41352016-04-07 15:18:58 -07002783 becomeActiveLocked("exit-force", Process.myUid());
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002784 }
2785 }
2786 }
2787
Kweku Adamsa457f4e2018-10-03 15:56:06 -07002788 /**
2789 * Must only be used in tests.
2790 *
2791 * This sets the state value directly and thus doesn't trigger any behavioral changes.
2792 */
2793 @VisibleForTesting
2794 void setLightStateForTest(int lightState) {
Kweku Adams799858b2018-10-08 17:19:08 -07002795 synchronized (this) {
2796 mLightState = lightState;
2797 }
Kweku Adamsa457f4e2018-10-03 15:56:06 -07002798 }
2799
Kweku Adams00e3a372018-09-28 16:57:09 -07002800 @VisibleForTesting
2801 int getLightState() {
2802 return mLightState;
2803 }
2804
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002805 void stepLightIdleStateLocked(String reason) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002806 if (mLightState == LIGHT_STATE_OVERRIDE) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08002807 // If we are already in deep device idle mode, then
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002808 // there is nothing left to do for light mode.
2809 return;
2810 }
2811
2812 if (DEBUG) Slog.d(TAG, "stepLightIdleStateLocked: mLightState=" + mLightState);
2813 EventLogTags.writeDeviceIdleLightStep();
2814
2815 switch (mLightState) {
2816 case LIGHT_STATE_INACTIVE:
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002817 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
Dianne Hackborn953fc942016-03-29 15:36:24 -07002818 // Reset the upcoming idle delays.
2819 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002820 mMaintenanceStartTime = 0;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002821 if (!isOpsInactiveLocked()) {
2822 // We have some active ops going on... give them a chance to finish
2823 // before going in to our first idle.
2824 mLightState = LIGHT_STATE_PRE_IDLE;
2825 EventLogTags.writeDeviceIdleLight(mLightState, reason);
2826 scheduleLightAlarmLocked(mConstants.LIGHT_PRE_IDLE_TIMEOUT);
2827 break;
2828 }
2829 // Nothing active, fall through to immediately idle.
2830 case LIGHT_STATE_PRE_IDLE:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002831 case LIGHT_STATE_IDLE_MAINTENANCE:
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002832 if (mMaintenanceStartTime != 0) {
2833 long duration = SystemClock.elapsedRealtime() - mMaintenanceStartTime;
2834 if (duration < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
2835 // We didn't use up all of our minimum budget; add this to the reserve.
2836 mCurIdleBudget += (mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET-duration);
2837 } else {
2838 // We used more than our minimum budget; this comes out of the reserve.
2839 mCurIdleBudget -= (duration-mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET);
2840 }
2841 }
2842 mMaintenanceStartTime = 0;
Dianne Hackborn953fc942016-03-29 15:36:24 -07002843 scheduleLightAlarmLocked(mNextLightIdleDelay);
2844 mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT,
2845 (long)(mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR));
2846 if (mNextLightIdleDelay < mConstants.LIGHT_IDLE_TIMEOUT) {
2847 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT;
2848 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002849 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_STATE_IDLE.");
2850 mLightState = LIGHT_STATE_IDLE;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002851 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Amith Yamasaniac6517a2018-04-23 12:19:34 -07002852 addEvent(EVENT_LIGHT_IDLE, null);
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08002853 mGoingIdleWakeLock.acquire();
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002854 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON_LIGHT);
2855 break;
2856 case LIGHT_STATE_IDLE:
Dianne Hackborn88c41352016-04-07 15:18:58 -07002857 case LIGHT_STATE_WAITING_FOR_NETWORK:
2858 if (mNetworkConnected || mLightState == LIGHT_STATE_WAITING_FOR_NETWORK) {
2859 // We have been idling long enough, now it is time to do some work.
2860 mActiveIdleOpCount = 1;
2861 mActiveIdleWakeLock.acquire();
2862 mMaintenanceStartTime = SystemClock.elapsedRealtime();
2863 if (mCurIdleBudget < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
2864 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
2865 } else if (mCurIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) {
2866 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
2867 }
2868 scheduleLightAlarmLocked(mCurIdleBudget);
2869 if (DEBUG) Slog.d(TAG,
2870 "Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE.");
2871 mLightState = LIGHT_STATE_IDLE_MAINTENANCE;
2872 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Amith Yamasaniac6517a2018-04-23 12:19:34 -07002873 addEvent(EVENT_LIGHT_MAINTENANCE, null);
Dianne Hackborn88c41352016-04-07 15:18:58 -07002874 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
2875 } else {
2876 // We'd like to do maintenance, but currently don't have network
2877 // connectivity... let's try to wait until the network comes back.
2878 // We'll only wait for another full idle period, however, and then give up.
2879 scheduleLightAlarmLocked(mNextLightIdleDelay);
2880 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_WAITING_FOR_NETWORK.");
2881 mLightState = LIGHT_STATE_WAITING_FOR_NETWORK;
2882 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002883 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002884 break;
2885 }
2886 }
2887
Kweku Adams00e3a372018-09-28 16:57:09 -07002888 @VisibleForTesting
2889 int getState() {
2890 return mState;
2891 }
2892
2893 @VisibleForTesting
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002894 void stepIdleStateLocked(String reason) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002895 if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002896 EventLogTags.writeDeviceIdleStep();
2897
2898 final long now = SystemClock.elapsedRealtime();
Adam Lesinski31c05d12015-06-09 17:34:04 -07002899 if ((now+mConstants.MIN_TIME_TO_ALARM) > mAlarmManager.getNextWakeFromIdleTime()) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002900 // Whoops, there is an upcoming alarm. We don't actually want to go idle.
2901 if (mState != STATE_ACTIVE) {
Denny cy Leec5a7c292019-01-01 17:37:55 +08002902 mActiveReason = ACTIVE_REASON_ALARM;
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002903 becomeActiveLocked("alarm", Process.myUid());
Koji Fukui27b33302015-12-16 19:43:01 +09002904 becomeInactiveIfAppropriateLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002905 }
2906 return;
2907 }
2908
Robin Lee876b88542018-11-13 17:22:24 +01002909 if (mNumBlockingConstraints != 0 && !mForceIdle) {
2910 // We have some constraints from other parts of the system server preventing
2911 // us from moving to the next state.
2912 if (DEBUG) {
2913 Slog.i(TAG, "Cannot step idle state. Blocked by: " + mConstraints.values().stream()
2914 .filter(x -> x.active)
2915 .map(x -> x.name)
2916 .collect(Collectors.joining(",")));
2917 }
2918 return;
2919 }
2920
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002921 switch (mState) {
2922 case STATE_INACTIVE:
2923 // We have now been inactive long enough, it is time to start looking
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002924 // for motion and sleep some more while doing so.
2925 startMonitoringMotionLocked();
Denny cy Leec5a7c292019-01-01 17:37:55 +08002926 long delay = mConstants.IDLE_AFTER_INACTIVE_TIMEOUT;
2927 if (shouldUseIdleTimeoutFactorLocked()) {
2928 delay = (long) (mPreIdleFactor * delay);
2929 }
2930 scheduleAlarmLocked(delay, false);
Robin Lee876b88542018-11-13 17:22:24 +01002931 moveToStateLocked(STATE_IDLE_PENDING, reason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002932 break;
2933 case STATE_IDLE_PENDING:
Robin Lee876b88542018-11-13 17:22:24 +01002934 moveToStateLocked(STATE_SENSING, reason);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002935 cancelLocatingLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002936 mLocated = false;
2937 mLastGenericLocation = null;
2938 mLastGpsLocation = null;
Robin Lee876b88542018-11-13 17:22:24 +01002939 updateActiveConstraintsLocked();
Robin Leec4d424c2018-12-07 15:09:13 +01002940
Robin Lee876b88542018-11-13 17:22:24 +01002941 // Wait for open constraints and an accelerometer reading before moving on.
Robin Leec4d424c2018-12-07 15:09:13 +01002942 if (mUseMotionSensor && mAnyMotionDetector.hasSensor()) {
2943 scheduleSensingTimeoutAlarmLocked(mConstants.SENSING_TIMEOUT);
2944 mNotMoving = false;
2945 mAnyMotionDetector.checkForAnyMotion();
2946 break;
Robin Lee876b88542018-11-13 17:22:24 +01002947 } else if (mNumBlockingConstraints != 0) {
2948 cancelAlarmLocked();
2949 break;
Robin Leec4d424c2018-12-07 15:09:13 +01002950 }
2951
2952 mNotMoving = true;
2953 // Otherwise, fall through and check this off the list of requirements.
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002954 case STATE_SENSING:
Kevin Gabayan92f15e62016-04-04 17:52:22 -07002955 cancelSensingTimeoutAlarmLocked();
Robin Lee876b88542018-11-13 17:22:24 +01002956 moveToStateLocked(STATE_LOCATING, reason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002957 scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT, false);
Kweku Adams799858b2018-10-08 17:19:08 -07002958 LocationManager locationManager = mInjector.getLocationManager();
2959 if (locationManager != null
2960 && locationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
2961 locationManager.requestLocationUpdates(mLocationRequest,
Joe LaPenna23d681b2015-08-27 15:12:11 -07002962 mGenericLocationListener, mHandler.getLooper());
2963 mLocating = true;
2964 } else {
2965 mHasNetworkLocation = false;
2966 }
Kweku Adams799858b2018-10-08 17:19:08 -07002967 if (locationManager != null
2968 && locationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
Joe LaPenna23d681b2015-08-27 15:12:11 -07002969 mHasGps = true;
Kweku Adams799858b2018-10-08 17:19:08 -07002970 locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5,
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002971 mGpsLocationListener, mHandler.getLooper());
Joe LaPenna23d681b2015-08-27 15:12:11 -07002972 mLocating = true;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002973 } else {
Joe LaPenna23d681b2015-08-27 15:12:11 -07002974 mHasGps = false;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002975 }
Joe LaPenna23d681b2015-08-27 15:12:11 -07002976 // If we have a location provider, we're all set, the listeners will move state
2977 // forward.
2978 if (mLocating) {
2979 break;
2980 }
2981
2982 // Otherwise, we have to move from locating into idle maintenance.
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002983 case STATE_LOCATING:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002984 cancelAlarmLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002985 cancelLocatingLocked();
2986 mAnyMotionDetector.stop();
Dianne Hackborn953fc942016-03-29 15:36:24 -07002987
Kweku Adamsb396ccf2018-09-17 16:37:15 -07002988 // Intentional fallthrough -- time to go into IDLE state.
2989 case STATE_QUICK_DOZE_DELAY:
2990 // Reset the upcoming idle delays.
2991 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
2992 mNextIdleDelay = mConstants.IDLE_TIMEOUT;
2993
2994 // Everything is in place to go into IDLE state.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002995 case STATE_IDLE_MAINTENANCE:
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002996 scheduleAlarmLocked(mNextIdleDelay, true);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002997 if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay +
2998 " ms.");
Adam Lesinski31c05d12015-06-09 17:34:04 -07002999 mNextIdleDelay = (long)(mNextIdleDelay * mConstants.IDLE_FACTOR);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07003000 if (DEBUG) Slog.d(TAG, "Setting mNextIdleDelay = " + mNextIdleDelay);
Denny cy Leec5a7c292019-01-01 17:37:55 +08003001 mIdleStartTime = SystemClock.elapsedRealtime();
Adam Lesinski31c05d12015-06-09 17:34:04 -07003002 mNextIdleDelay = Math.min(mNextIdleDelay, mConstants.MAX_IDLE_TIMEOUT);
Dianne Hackborn953fc942016-03-29 15:36:24 -07003003 if (mNextIdleDelay < mConstants.IDLE_TIMEOUT) {
3004 mNextIdleDelay = mConstants.IDLE_TIMEOUT;
3005 }
Robin Lee876b88542018-11-13 17:22:24 +01003006 moveToStateLocked(STATE_IDLE, reason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003007 if (mLightState != LIGHT_STATE_OVERRIDE) {
3008 mLightState = LIGHT_STATE_OVERRIDE;
3009 cancelLightAlarmLocked();
3010 }
Amith Yamasaniac6517a2018-04-23 12:19:34 -07003011 addEvent(EVENT_DEEP_IDLE, null);
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08003012 mGoingIdleWakeLock.acquire();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003013 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON);
3014 break;
3015 case STATE_IDLE:
3016 // We have been idling long enough, now it is time to do some work.
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003017 mActiveIdleOpCount = 1;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07003018 mActiveIdleWakeLock.acquire();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003019 scheduleAlarmLocked(mNextIdlePendingDelay, false);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07003020 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE to STATE_IDLE_MAINTENANCE. " +
3021 "Next alarm in " + mNextIdlePendingDelay + " ms.");
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003022 mMaintenanceStartTime = SystemClock.elapsedRealtime();
Adam Lesinski31c05d12015-06-09 17:34:04 -07003023 mNextIdlePendingDelay = Math.min(mConstants.MAX_IDLE_PENDING_TIMEOUT,
3024 (long)(mNextIdlePendingDelay * mConstants.IDLE_PENDING_FACTOR));
Dianne Hackborn953fc942016-03-29 15:36:24 -07003025 if (mNextIdlePendingDelay < mConstants.IDLE_PENDING_TIMEOUT) {
3026 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
3027 }
Robin Lee876b88542018-11-13 17:22:24 +01003028 moveToStateLocked(STATE_IDLE_MAINTENANCE, reason);
Amith Yamasaniac6517a2018-04-23 12:19:34 -07003029 addEvent(EVENT_DEEP_MAINTENANCE, null);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003030 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
3031 break;
3032 }
3033 }
3034
Robin Lee876b88542018-11-13 17:22:24 +01003035 private void moveToStateLocked(int state, String reason) {
3036 final int oldState = mState;
3037 mState = state;
3038 if (DEBUG) {
3039 Slog.d(TAG, String.format("Moved from STATE_%s to STATE_%s.",
3040 stateToString(oldState), stateToString(mState)));
3041 }
3042 EventLogTags.writeDeviceIdle(mState, reason);
3043 updateActiveConstraintsLocked();
3044 }
3045
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003046 void incActiveIdleOps() {
3047 synchronized (this) {
3048 mActiveIdleOpCount++;
3049 }
3050 }
3051
3052 void decActiveIdleOps() {
3053 synchronized (this) {
3054 mActiveIdleOpCount--;
3055 if (mActiveIdleOpCount <= 0) {
3056 exitMaintenanceEarlyIfNeededLocked();
Dianne Hackborn945c9c92016-03-30 14:55:00 -07003057 mActiveIdleWakeLock.release();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003058 }
3059 }
3060 }
3061
Kweku Adamsa457f4e2018-10-03 15:56:06 -07003062 /** Must only be used in tests. */
3063 @VisibleForTesting
3064 void setActiveIdleOpsForTest(int count) {
Kweku Adams799858b2018-10-08 17:19:08 -07003065 synchronized (this) {
3066 mActiveIdleOpCount = count;
3067 }
Kweku Adamsa457f4e2018-10-03 15:56:06 -07003068 }
3069
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003070 void setJobsActive(boolean active) {
3071 synchronized (this) {
3072 mJobsActive = active;
Yao Chenca5edbb2016-01-13 14:44:36 -08003073 reportMaintenanceActivityIfNeededLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003074 if (!active) {
3075 exitMaintenanceEarlyIfNeededLocked();
3076 }
3077 }
3078 }
3079
3080 void setAlarmsActive(boolean active) {
3081 synchronized (this) {
3082 mAlarmsActive = active;
3083 if (!active) {
3084 exitMaintenanceEarlyIfNeededLocked();
3085 }
3086 }
3087 }
3088
Yao Chenca5edbb2016-01-13 14:44:36 -08003089 boolean registerMaintenanceActivityListener(IMaintenanceActivityListener listener) {
3090 synchronized (this) {
3091 mMaintenanceActivityListeners.register(listener);
3092 return mReportedMaintenanceActivity;
3093 }
3094 }
3095
3096 void unregisterMaintenanceActivityListener(IMaintenanceActivityListener listener) {
3097 synchronized (this) {
3098 mMaintenanceActivityListeners.unregister(listener);
3099 }
3100 }
3101
Denny cy Leec5a7c292019-01-01 17:37:55 +08003102 @VisibleForTesting
3103 int setPreIdleTimeoutMode(int mode) {
3104 return setPreIdleTimeoutFactor(getPreIdleTimeoutByMode(mode));
3105 }
3106
3107 @VisibleForTesting
3108 float getPreIdleTimeoutByMode(int mode) {
3109 switch (mode) {
3110 case PowerManager.PRE_IDLE_TIMEOUT_MODE_LONG: {
3111 return mConstants.PRE_IDLE_FACTOR_LONG;
3112 }
3113 case PowerManager.PRE_IDLE_TIMEOUT_MODE_SHORT: {
3114 return mConstants.PRE_IDLE_FACTOR_SHORT;
3115 }
3116 case PowerManager.PRE_IDLE_TIMEOUT_MODE_NORMAL: {
3117 return 1.0f;
3118 }
3119 default: {
3120 Slog.w(TAG, "Invalid time out factor mode: " + mode);
3121 return 1.0f;
3122 }
3123 }
3124 }
3125
3126 @VisibleForTesting
3127 float getPreIdleTimeoutFactor() {
3128 return mPreIdleFactor;
3129 }
3130
3131 @VisibleForTesting
3132 int setPreIdleTimeoutFactor(float ratio) {
3133 if (!mDeepEnabled) {
3134 if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: Deep Idle disable");
3135 return SET_IDLE_FACTOR_RESULT_NOT_SUPPORT;
3136 } else if (ratio <= MIN_PRE_IDLE_FACTOR_CHANGE) {
3137 if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: Invalid input");
3138 return SET_IDLE_FACTOR_RESULT_INVALID;
3139 } else if (Math.abs(ratio - mPreIdleFactor) < MIN_PRE_IDLE_FACTOR_CHANGE) {
3140 if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: New factor same as previous factor");
3141 return SET_IDLE_FACTOR_RESULT_IGNORED;
3142 }
3143 synchronized (this) {
3144 mLastPreIdleFactor = mPreIdleFactor;
3145 mPreIdleFactor = ratio;
3146 }
3147 if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: " + ratio);
3148 postUpdatePreIdleFactor();
3149 return SET_IDLE_FACTOR_RESULT_OK;
3150 }
3151
3152 @VisibleForTesting
3153 void resetPreIdleTimeoutMode() {
3154 synchronized (this) {
3155 mLastPreIdleFactor = mPreIdleFactor;
3156 mPreIdleFactor = 1.0f;
3157 }
3158 if (DEBUG) Slog.d(TAG, "resetPreIdleTimeoutMode to 1.0");
3159 postResetPreIdleTimeoutFactor();
3160 }
3161
3162 private void postUpdatePreIdleFactor() {
3163 mHandler.sendEmptyMessage(MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR);
3164 }
3165
3166 private void postResetPreIdleTimeoutFactor() {
3167 mHandler.sendEmptyMessage(MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR);
3168 }
3169
3170 @VisibleForTesting
3171 void updatePreIdleFactor() {
3172 synchronized (this) {
3173 if (!shouldUseIdleTimeoutFactorLocked()) {
3174 return;
3175 }
3176 if (mState == STATE_INACTIVE || mState == STATE_IDLE_PENDING) {
3177 if (mNextAlarmTime == 0) {
3178 return;
3179 }
3180 long delay = mNextAlarmTime - SystemClock.elapsedRealtime();
3181 if (delay < MIN_STATE_STEP_ALARM_CHANGE) {
3182 return;
3183 }
3184 long newDelay = (long) (delay / mLastPreIdleFactor * mPreIdleFactor);
3185 if (Math.abs(delay - newDelay) < MIN_STATE_STEP_ALARM_CHANGE) {
3186 return;
3187 }
3188 scheduleAlarmLocked(newDelay, false);
3189 }
3190 }
3191 }
3192
3193 @VisibleForTesting
3194 void maybeDoImmediateMaintenance() {
3195 synchronized (this) {
3196 if (mState == STATE_IDLE) {
3197 long duration = SystemClock.elapsedRealtime() - mIdleStartTime;
3198 /* Let's trgger a immediate maintenance,
3199 * if it has been idle for a long time */
3200 if (duration > mConstants.IDLE_TIMEOUT) {
3201 scheduleAlarmLocked(0, false);
3202 }
3203 }
3204 }
3205 }
3206
3207 private boolean shouldUseIdleTimeoutFactorLocked() {
3208 // exclude ACTIVE_REASON_MOTION, for exclude device in pocket case
3209 if (mActiveReason == ACTIVE_REASON_MOTION) {
3210 return false;
3211 }
3212 return true;
3213 }
3214
3215 /** Must only be used in tests. */
3216 @VisibleForTesting
3217 void setIdleStartTimeForTest(long idleStartTime) {
3218 synchronized (this) {
3219 mIdleStartTime = idleStartTime;
3220 }
3221 }
3222
Yao Chenca5edbb2016-01-13 14:44:36 -08003223 void reportMaintenanceActivityIfNeededLocked() {
Dianne Hackborn7ab40252016-06-15 17:30:24 -07003224 boolean active = mJobsActive;
Yao Chenca5edbb2016-01-13 14:44:36 -08003225 if (active == mReportedMaintenanceActivity) {
3226 return;
3227 }
3228 mReportedMaintenanceActivity = active;
3229 Message msg = mHandler.obtainMessage(MSG_REPORT_MAINTENANCE_ACTIVITY,
3230 mReportedMaintenanceActivity ? 1 : 0, 0);
3231 mHandler.sendMessage(msg);
3232 }
3233
Denny cy Leec5a7c292019-01-01 17:37:55 +08003234 @VisibleForTesting
3235 long getNextAlarmTime() {
3236 return mNextAlarmTime;
3237 }
3238
Dianne Hackborn945c9c92016-03-30 14:55:00 -07003239 boolean isOpsInactiveLocked() {
Dianne Hackborn7ab40252016-06-15 17:30:24 -07003240 return mActiveIdleOpCount <= 0 && !mJobsActive && !mAlarmsActive;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07003241 }
3242
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003243 void exitMaintenanceEarlyIfNeededLocked() {
Dianne Hackborn945c9c92016-03-30 14:55:00 -07003244 if (mState == STATE_IDLE_MAINTENANCE || mLightState == LIGHT_STATE_IDLE_MAINTENANCE
3245 || mLightState == LIGHT_STATE_PRE_IDLE) {
3246 if (isOpsInactiveLocked()) {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003247 final long now = SystemClock.elapsedRealtime();
3248 if (DEBUG) {
3249 StringBuilder sb = new StringBuilder();
3250 sb.append("Exit: start=");
3251 TimeUtils.formatDuration(mMaintenanceStartTime, sb);
3252 sb.append(" now=");
3253 TimeUtils.formatDuration(now, sb);
3254 Slog.d(TAG, sb.toString());
3255 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003256 if (mState == STATE_IDLE_MAINTENANCE) {
Dianne Hackborn945c9c92016-03-30 14:55:00 -07003257 stepIdleStateLocked("s:early");
3258 } else if (mLightState == LIGHT_STATE_PRE_IDLE) {
3259 stepLightIdleStateLocked("s:predone");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003260 } else {
Dianne Hackborn945c9c92016-03-30 14:55:00 -07003261 stepLightIdleStateLocked("s:early");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003262 }
3263 }
3264 }
3265 }
3266
Nick Vaccaro20feaea2015-09-17 17:22:44 -07003267 void motionLocked() {
3268 if (DEBUG) Slog.d(TAG, "motionLocked()");
3269 // The motion sensor will have been disabled at this point
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003270 handleMotionDetectedLocked(mConstants.MOTION_INACTIVE_TIMEOUT, "motion");
3271 }
3272
3273 void handleMotionDetectedLocked(long timeout, String type) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003274 // The device is not yet active, so we want to go back to the pending idle
Nick Vaccaro20feaea2015-09-17 17:22:44 -07003275 // state to wait again for no motion. Note that we only monitor for motion
3276 // after moving out of the inactive state, so no need to worry about that.
Kweku Adamsb7ce1902019-01-30 10:55:34 -08003277 final boolean becomeInactive = mState != STATE_ACTIVE
3278 || mLightState == LIGHT_STATE_OVERRIDE;
3279 // We only want to change the IDLE state if it's OVERRIDE.
3280 becomeActiveLocked(type, Process.myUid(), timeout, mLightState == LIGHT_STATE_OVERRIDE);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003281 if (becomeInactive) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003282 becomeInactiveIfAppropriateLocked();
3283 }
3284 }
3285
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003286 void receivedGenericLocationLocked(Location location) {
3287 if (mState != STATE_LOCATING) {
3288 cancelLocatingLocked();
3289 return;
3290 }
3291 if (DEBUG) Slog.d(TAG, "Generic location: " + location);
3292 mLastGenericLocation = new Location(location);
Joe LaPenna23d681b2015-08-27 15:12:11 -07003293 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHasGps) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003294 return;
3295 }
3296 mLocated = true;
3297 if (mNotMoving) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003298 stepIdleStateLocked("s:location");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003299 }
3300 }
3301
3302 void receivedGpsLocationLocked(Location location) {
3303 if (mState != STATE_LOCATING) {
3304 cancelLocatingLocked();
3305 return;
3306 }
3307 if (DEBUG) Slog.d(TAG, "GPS location: " + location);
3308 mLastGpsLocation = new Location(location);
3309 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY) {
3310 return;
3311 }
3312 mLocated = true;
3313 if (mNotMoving) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003314 stepIdleStateLocked("s:gps");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003315 }
3316 }
3317
Nick Vaccaro20feaea2015-09-17 17:22:44 -07003318 void startMonitoringMotionLocked() {
3319 if (DEBUG) Slog.d(TAG, "startMonitoringMotionLocked()");
3320 if (mMotionSensor != null && !mMotionListener.active) {
3321 mMotionListener.registerLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003322 }
3323 }
3324
Nick Vaccaro20feaea2015-09-17 17:22:44 -07003325 void stopMonitoringMotionLocked() {
3326 if (DEBUG) Slog.d(TAG, "stopMonitoringMotionLocked()");
3327 if (mMotionSensor != null && mMotionListener.active) {
3328 mMotionListener.unregisterLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003329 }
3330 }
3331
3332 void cancelAlarmLocked() {
3333 if (mNextAlarmTime != 0) {
3334 mNextAlarmTime = 0;
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003335 mAlarmManager.cancel(mDeepAlarmListener);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003336 }
3337 }
3338
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003339 void cancelLightAlarmLocked() {
3340 if (mNextLightAlarmTime != 0) {
3341 mNextLightAlarmTime = 0;
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003342 mAlarmManager.cancel(mLightAlarmListener);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003343 }
3344 }
3345
3346 void cancelLocatingLocked() {
3347 if (mLocating) {
Kweku Adams799858b2018-10-08 17:19:08 -07003348 LocationManager locationManager = mInjector.getLocationManager();
3349 locationManager.removeUpdates(mGenericLocationListener);
3350 locationManager.removeUpdates(mGpsLocationListener);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003351 mLocating = false;
3352 }
Kevin Gabayan89ecf822015-05-18 12:10:07 -07003353 }
3354
Kevin Gabayan92f15e62016-04-04 17:52:22 -07003355 void cancelSensingTimeoutAlarmLocked() {
3356 if (mNextSensingTimeoutAlarmTime != 0) {
3357 mNextSensingTimeoutAlarmTime = 0;
3358 mAlarmManager.cancel(mSensingTimeoutAlarmListener);
3359 }
3360 }
3361
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003362 void scheduleAlarmLocked(long delay, boolean idleUntil) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07003363 if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")");
Robin Leec4d424c2018-12-07 15:09:13 +01003364
3365 if (mUseMotionSensor && mMotionSensor == null
3366 && mState != STATE_QUICK_DOZE_DELAY
3367 && mState != STATE_IDLE
3368 && mState != STATE_IDLE_MAINTENANCE) {
3369 // If there is no motion sensor on this device, but we need one, then we won't schedule
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003370 // alarms, because we can't determine if the device is not moving. This effectively
Joe LaPenna23d681b2015-08-27 15:12:11 -07003371 // turns off normal execution of device idling, although it is still possible to
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003372 // manually poke it by pretending like the alarm is going off.
Kweku Adamsb396ccf2018-09-17 16:37:15 -07003373 // STATE_QUICK_DOZE_DELAY skips the motion sensing so if the state is past the motion
3374 // sensing stage (ie, is QUICK_DOZE_DELAY, IDLE, or IDLE_MAINTENANCE), then idling
3375 // can continue until the user interacts with the device.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003376 return;
3377 }
3378 mNextAlarmTime = SystemClock.elapsedRealtime() + delay;
3379 if (idleUntil) {
3380 mAlarmManager.setIdleUntil(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003381 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003382 } else {
3383 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003384 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003385 }
3386 }
3387
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003388 void scheduleLightAlarmLocked(long delay) {
3389 if (DEBUG) Slog.d(TAG, "scheduleLightAlarmLocked(" + delay + ")");
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003390 mNextLightAlarmTime = SystemClock.elapsedRealtime() + delay;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003391 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003392 mNextLightAlarmTime, "DeviceIdleController.light", mLightAlarmListener, mHandler);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07003393 }
3394
Kevin Gabayan92f15e62016-04-04 17:52:22 -07003395 void scheduleSensingTimeoutAlarmLocked(long delay) {
3396 if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")");
3397 mNextSensingTimeoutAlarmTime = SystemClock.elapsedRealtime() + delay;
3398 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextSensingTimeoutAlarmTime,
3399 "DeviceIdleController.sensing", mSensingTimeoutAlarmListener, mHandler);
3400 }
3401
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003402 private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps,
3403 ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds) {
3404 outAppIds.clear();
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08003405 if (systemApps != null) {
3406 for (int i = 0; i < systemApps.size(); i++) {
3407 outAppIds.put(systemApps.valueAt(i), true);
3408 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003409 }
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08003410 if (userApps != null) {
3411 for (int i = 0; i < userApps.size(); i++) {
3412 outAppIds.put(userApps.valueAt(i), true);
3413 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003414 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003415 int size = outAppIds.size();
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003416 int[] appids = new int[size];
3417 for (int i = 0; i < size; i++) {
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003418 appids[i] = outAppIds.keyAt(i);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003419 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003420 return appids;
3421 }
3422
3423 private void updateWhitelistAppIdsLocked() {
3424 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(mPowerSaveWhitelistAppsExceptIdle,
3425 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistExceptIdleAppIds);
3426 mPowerSaveWhitelistAllAppIdArray = buildAppIdArray(mPowerSaveWhitelistApps,
3427 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistAllAppIds);
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08003428 mPowerSaveWhitelistUserAppIdArray = buildAppIdArray(null,
3429 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistUserAppIds);
Dianne Hackborn85e35642017-01-12 15:10:57 -08003430 if (mLocalActivityManager != null) {
Makoto Onukiaf8ff4f2018-06-04 14:44:19 -07003431 mLocalActivityManager.setDeviceIdleWhitelist(
3432 mPowerSaveWhitelistAllAppIdArray, mPowerSaveWhitelistExceptIdleAppIdArray);
Dianne Hackborn85e35642017-01-12 15:10:57 -08003433 }
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003434 if (mLocalPowerManager != null) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003435 if (DEBUG) {
3436 Slog.d(TAG, "Setting wakelock whitelist to "
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07003437 + Arrays.toString(mPowerSaveWhitelistAllAppIdArray));
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003438 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07003439 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003440 }
Suprabh Shukla5bf49812018-05-24 18:38:50 -07003441 passWhiteListsToForceAppStandbyTrackerLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003442 }
3443
Dianne Hackborn85e35642017-01-12 15:10:57 -08003444 private void updateTempWhitelistAppIdsLocked(int appId, boolean adding) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003445 final int size = mTempWhitelistAppIdEndTimes.size();
3446 if (mTempWhitelistAppIdArray.length != size) {
3447 mTempWhitelistAppIdArray = new int[size];
3448 }
3449 for (int i = 0; i < size; i++) {
3450 mTempWhitelistAppIdArray[i] = mTempWhitelistAppIdEndTimes.keyAt(i);
3451 }
Dianne Hackborn85e35642017-01-12 15:10:57 -08003452 if (mLocalActivityManager != null) {
3453 if (DEBUG) {
3454 Slog.d(TAG, "Setting activity manager temp whitelist to "
3455 + Arrays.toString(mTempWhitelistAppIdArray));
3456 }
3457 mLocalActivityManager.updateDeviceIdleTempWhitelist(mTempWhitelistAppIdArray, appId,
3458 adding);
3459 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003460 if (mLocalPowerManager != null) {
3461 if (DEBUG) {
3462 Slog.d(TAG, "Setting wakelock temp whitelist to "
3463 + Arrays.toString(mTempWhitelistAppIdArray));
3464 }
3465 mLocalPowerManager.setDeviceIdleTempWhitelist(mTempWhitelistAppIdArray);
3466 }
Suprabh Shukla5bf49812018-05-24 18:38:50 -07003467 passWhiteListsToForceAppStandbyTrackerLocked();
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003468 }
3469
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003470 private void reportPowerSaveWhitelistChangedLocked() {
3471 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
3472 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Xiaohui Chene4de5a02015-09-22 15:33:31 -07003473 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003474 }
3475
3476 private void reportTempWhitelistChangedLocked() {
3477 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED);
3478 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Xiaohui Chene4de5a02015-09-22 15:33:31 -07003479 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003480 }
3481
Suprabh Shukla5bf49812018-05-24 18:38:50 -07003482 private void passWhiteListsToForceAppStandbyTrackerLocked() {
Makoto Onukie4918212018-02-06 11:30:15 -08003483 mAppStateTracker.setPowerSaveWhitelistAppIds(
Makoto Onuki71755c92018-01-16 14:15:44 -08003484 mPowerSaveWhitelistExceptIdleAppIdArray,
Suprabh Shukla5bf49812018-05-24 18:38:50 -07003485 mPowerSaveWhitelistUserAppIdArray,
Makoto Onuki2206af32017-11-21 16:25:35 -08003486 mTempWhitelistAppIdArray);
3487 }
3488
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003489 void readConfigFileLocked() {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003490 if (DEBUG) Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003491 mPowerSaveWhitelistUserApps.clear();
3492 FileInputStream stream;
3493 try {
3494 stream = mConfigFile.openRead();
3495 } catch (FileNotFoundException e) {
3496 return;
3497 }
3498 try {
3499 XmlPullParser parser = Xml.newPullParser();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01003500 parser.setInput(stream, StandardCharsets.UTF_8.name());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003501 readConfigFileLocked(parser);
3502 } catch (XmlPullParserException e) {
3503 } finally {
3504 try {
3505 stream.close();
3506 } catch (IOException e) {
3507 }
3508 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003509 }
3510
3511 private void readConfigFileLocked(XmlPullParser parser) {
3512 final PackageManager pm = getContext().getPackageManager();
3513
3514 try {
3515 int type;
3516 while ((type = parser.next()) != XmlPullParser.START_TAG
3517 && type != XmlPullParser.END_DOCUMENT) {
3518 ;
3519 }
3520
3521 if (type != XmlPullParser.START_TAG) {
3522 throw new IllegalStateException("no start tag found");
3523 }
3524
3525 int outerDepth = parser.getDepth();
3526 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3527 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3528 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3529 continue;
3530 }
3531
3532 String tagName = parser.getName();
Suprabh Shukla08105642017-09-26 14:45:30 -07003533 switch (tagName) {
3534 case "wl":
3535 String name = parser.getAttributeValue(null, "n");
3536 if (name != null) {
3537 try {
3538 ApplicationInfo ai = pm.getApplicationInfo(name,
3539 PackageManager.MATCH_ANY_USER);
3540 mPowerSaveWhitelistUserApps.put(ai.packageName,
3541 UserHandle.getAppId(ai.uid));
3542 } catch (PackageManager.NameNotFoundException e) {
3543 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003544 }
Suprabh Shukla08105642017-09-26 14:45:30 -07003545 break;
3546 case "un-wl":
3547 final String packageName = parser.getAttributeValue(null, "n");
3548 if (mPowerSaveWhitelistApps.containsKey(packageName)) {
3549 mRemovedFromSystemWhitelistApps.put(packageName,
3550 mPowerSaveWhitelistApps.remove(packageName));
3551 }
3552 break;
3553 default:
3554 Slog.w(TAG, "Unknown element under <config>: "
3555 + parser.getName());
3556 XmlUtils.skipCurrentTag(parser);
3557 break;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003558 }
3559 }
3560
3561 } catch (IllegalStateException e) {
3562 Slog.w(TAG, "Failed parsing config " + e);
3563 } catch (NullPointerException e) {
3564 Slog.w(TAG, "Failed parsing config " + e);
3565 } catch (NumberFormatException e) {
3566 Slog.w(TAG, "Failed parsing config " + e);
3567 } catch (XmlPullParserException e) {
3568 Slog.w(TAG, "Failed parsing config " + e);
3569 } catch (IOException e) {
3570 Slog.w(TAG, "Failed parsing config " + e);
3571 } catch (IndexOutOfBoundsException e) {
3572 Slog.w(TAG, "Failed parsing config " + e);
3573 }
3574 }
3575
3576 void writeConfigFileLocked() {
3577 mHandler.removeMessages(MSG_WRITE_CONFIG);
3578 mHandler.sendEmptyMessageDelayed(MSG_WRITE_CONFIG, 5000);
3579 }
3580
3581 void handleWriteConfigFile() {
3582 final ByteArrayOutputStream memStream = new ByteArrayOutputStream();
3583
3584 try {
3585 synchronized (this) {
3586 XmlSerializer out = new FastXmlSerializer();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01003587 out.setOutput(memStream, StandardCharsets.UTF_8.name());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003588 writeConfigFileLocked(out);
3589 }
3590 } catch (IOException e) {
3591 }
3592
3593 synchronized (mConfigFile) {
3594 FileOutputStream stream = null;
3595 try {
3596 stream = mConfigFile.startWrite();
3597 memStream.writeTo(stream);
3598 stream.flush();
3599 FileUtils.sync(stream);
3600 stream.close();
3601 mConfigFile.finishWrite(stream);
3602 } catch (IOException e) {
3603 Slog.w(TAG, "Error writing config file", e);
3604 mConfigFile.failWrite(stream);
3605 }
3606 }
3607 }
3608
3609 void writeConfigFileLocked(XmlSerializer out) throws IOException {
3610 out.startDocument(null, true);
3611 out.startTag(null, "config");
3612 for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) {
3613 String name = mPowerSaveWhitelistUserApps.keyAt(i);
3614 out.startTag(null, "wl");
3615 out.attribute(null, "n", name);
3616 out.endTag(null, "wl");
3617 }
Suprabh Shukla08105642017-09-26 14:45:30 -07003618 for (int i = 0; i < mRemovedFromSystemWhitelistApps.size(); i++) {
3619 out.startTag(null, "un-wl");
3620 out.attribute(null, "n", mRemovedFromSystemWhitelistApps.keyAt(i));
3621 out.endTag(null, "un-wl");
3622 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003623 out.endTag(null, "config");
3624 out.endDocument();
3625 }
3626
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003627 static void dumpHelp(PrintWriter pw) {
3628 pw.println("Device idle controller (deviceidle) commands:");
3629 pw.println(" help");
3630 pw.println(" Print this help text.");
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003631 pw.println(" step [light|deep]");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003632 pw.println(" Immediately step to next state, without waiting for alarm.");
Dianne Hackborn88c41352016-04-07 15:18:58 -07003633 pw.println(" force-idle [light|deep]");
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003634 pw.println(" Force directly into idle mode, regardless of other device state.");
Dianne Hackborn88c41352016-04-07 15:18:58 -07003635 pw.println(" force-inactive");
3636 pw.println(" Force to be inactive, ready to freely step idle states.");
3637 pw.println(" unforce");
3638 pw.println(" Resume normal functioning after force-idle or force-inactive.");
3639 pw.println(" get [light|deep|force|screen|charging|network]");
3640 pw.println(" Retrieve the current given state.");
Dianne Hackbornb6843652016-02-22 12:20:13 -08003641 pw.println(" disable [light|deep|all]");
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003642 pw.println(" Completely disable device idle mode.");
Dianne Hackbornb6843652016-02-22 12:20:13 -08003643 pw.println(" enable [light|deep|all]");
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003644 pw.println(" Re-enable device idle mode after it had previously been disabled.");
Dianne Hackbornb6843652016-02-22 12:20:13 -08003645 pw.println(" enabled [light|deep|all]");
Dianne Hackborn92617032015-06-19 15:32:19 -07003646 pw.println(" Print 1 if device idle mode is currently enabled, else 0.");
Dianne Hackborn1b139682015-07-06 15:13:37 -07003647 pw.println(" whitelist");
3648 pw.println(" Print currently whitelisted apps.");
Dianne Hackborn92617032015-06-19 15:32:19 -07003649 pw.println(" whitelist [package ...]");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003650 pw.println(" Add (prefix with +) or remove (prefix with -) packages.");
Suprabh Shukla08105642017-09-26 14:45:30 -07003651 pw.println(" sys-whitelist [package ...|reset]");
3652 pw.println(" Prefix the package with '-' to remove it from the system whitelist or '+'"
3653 + " to put it back in the system whitelist.");
3654 pw.println(" Note that only packages that were"
3655 + " earlier removed from the system whitelist can be added back.");
3656 pw.println(" reset will reset the whitelist to the original state");
3657 pw.println(" Prints the system whitelist if no arguments are specified");
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07003658 pw.println(" except-idle-whitelist [package ...|reset]");
3659 pw.println(" Prefix the package with '+' to add it to whitelist or "
3660 + "'=' to check if it is already whitelisted");
3661 pw.println(" [reset] will reset the whitelist to it's original state");
3662 pw.println(" Note that unlike <whitelist> cmd, "
3663 + "changes made using this won't be persisted across boots");
Felipe Lemea1b79bf2016-05-24 13:06:54 -07003664 pw.println(" tempwhitelist");
3665 pw.println(" Print packages that are temporarily whitelisted.");
Sudheer Shanka326b3112017-11-27 14:40:57 -08003666 pw.println(" tempwhitelist [-u USER] [-d DURATION] [-r] [package]");
3667 pw.println(" Temporarily place package in whitelist for DURATION milliseconds.");
Dianne Hackborn85e35642017-01-12 15:10:57 -08003668 pw.println(" If no DURATION is specified, 10 seconds is used");
Sudheer Shanka326b3112017-11-27 14:40:57 -08003669 pw.println(" If [-r] option is used, then the package is removed from temp whitelist "
3670 + "and any [-d] is ignored");
Amith Yamasani4cb42572018-04-27 10:02:57 -07003671 pw.println(" motion");
3672 pw.println(" Simulate a motion event to bring the device out of deep doze");
Denny cy Leec5a7c292019-01-01 17:37:55 +08003673 pw.println(" pre-idle-factor [0|1|2]");
3674 pw.println(" Set a new factor to idle time before step to idle"
3675 + "(inactive_to and idle_after_inactive_to)");
3676 pw.println(" reset-pre-idle-factor");
3677 pw.println(" Reset factor to idle time to default");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003678 }
3679
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003680 class Shell extends ShellCommand {
3681 int userId = UserHandle.USER_SYSTEM;
3682
3683 @Override
3684 public int onCommand(String cmd) {
3685 return onShellCommand(this, cmd);
3686 }
3687
3688 @Override
3689 public void onHelp() {
3690 PrintWriter pw = getOutPrintWriter();
3691 dumpHelp(pw);
3692 }
3693 }
3694
3695 int onShellCommand(Shell shell, String cmd) {
3696 PrintWriter pw = shell.getOutPrintWriter();
3697 if ("step".equals(cmd)) {
3698 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3699 null);
3700 synchronized (this) {
3701 long token = Binder.clearCallingIdentity();
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003702 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003703 try {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003704 if (arg == null || "deep".equals(arg)) {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003705 stepIdleStateLocked("s:shell");
3706 pw.print("Stepped to deep: ");
3707 pw.println(stateToString(mState));
3708 } else if ("light".equals(arg)) {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003709 stepLightIdleStateLocked("s:shell");
3710 pw.print("Stepped to light: "); pw.println(lightStateToString(mLightState));
3711 } else {
3712 pw.println("Unknown idle mode: " + arg);
3713 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003714 } finally {
3715 Binder.restoreCallingIdentity(token);
3716 }
3717 }
3718 } else if ("force-idle".equals(cmd)) {
3719 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3720 null);
3721 synchronized (this) {
3722 long token = Binder.clearCallingIdentity();
Dianne Hackborn88c41352016-04-07 15:18:58 -07003723 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003724 try {
Dianne Hackborn88c41352016-04-07 15:18:58 -07003725 if (arg == null || "deep".equals(arg)) {
3726 if (!mDeepEnabled) {
3727 pw.println("Unable to go deep idle; not enabled");
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003728 return -1;
3729 }
Dianne Hackborn88c41352016-04-07 15:18:58 -07003730 mForceIdle = true;
3731 becomeInactiveIfAppropriateLocked();
3732 int curState = mState;
3733 while (curState != STATE_IDLE) {
3734 stepIdleStateLocked("s:shell");
3735 if (curState == mState) {
3736 pw.print("Unable to go deep idle; stopped at ");
3737 pw.println(stateToString(mState));
3738 exitForceIdleLocked();
3739 return -1;
3740 }
3741 curState = mState;
3742 }
3743 pw.println("Now forced in to deep idle mode");
3744 } else if ("light".equals(arg)) {
3745 mForceIdle = true;
3746 becomeInactiveIfAppropriateLocked();
3747 int curLightState = mLightState;
3748 while (curLightState != LIGHT_STATE_IDLE) {
Tej Singh93cf3e32017-12-07 13:05:38 -08003749 stepLightIdleStateLocked("s:shell");
Dianne Hackborn88c41352016-04-07 15:18:58 -07003750 if (curLightState == mLightState) {
3751 pw.print("Unable to go light idle; stopped at ");
3752 pw.println(lightStateToString(mLightState));
3753 exitForceIdleLocked();
3754 return -1;
3755 }
3756 curLightState = mLightState;
3757 }
3758 pw.println("Now forced in to light idle mode");
3759 } else {
3760 pw.println("Unknown idle mode: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003761 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003762 } finally {
3763 Binder.restoreCallingIdentity(token);
3764 }
3765 }
Dianne Hackborn88c41352016-04-07 15:18:58 -07003766 } else if ("force-inactive".equals(cmd)) {
3767 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3768 null);
3769 synchronized (this) {
3770 long token = Binder.clearCallingIdentity();
3771 try {
3772 mForceIdle = true;
3773 becomeInactiveIfAppropriateLocked();
3774 pw.print("Light state: ");
3775 pw.print(lightStateToString(mLightState));
3776 pw.print(", deep state: ");
3777 pw.println(stateToString(mState));
3778 } finally {
3779 Binder.restoreCallingIdentity(token);
3780 }
3781 }
3782 } else if ("unforce".equals(cmd)) {
3783 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3784 null);
3785 synchronized (this) {
3786 long token = Binder.clearCallingIdentity();
3787 try {
3788 exitForceIdleLocked();
3789 pw.print("Light state: ");
3790 pw.print(lightStateToString(mLightState));
3791 pw.print(", deep state: ");
3792 pw.println(stateToString(mState));
3793 } finally {
3794 Binder.restoreCallingIdentity(token);
3795 }
3796 }
3797 } else if ("get".equals(cmd)) {
3798 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3799 null);
3800 synchronized (this) {
3801 String arg = shell.getNextArg();
3802 if (arg != null) {
3803 long token = Binder.clearCallingIdentity();
3804 try {
3805 switch (arg) {
3806 case "light": pw.println(lightStateToString(mLightState)); break;
3807 case "deep": pw.println(stateToString(mState)); break;
3808 case "force": pw.println(mForceIdle); break;
Kweku Adamsb396ccf2018-09-17 16:37:15 -07003809 case "quick": pw.println(mQuickDozeActivated); break;
Dianne Hackborn88c41352016-04-07 15:18:58 -07003810 case "screen": pw.println(mScreenOn); break;
3811 case "charging": pw.println(mCharging); break;
3812 case "network": pw.println(mNetworkConnected); break;
3813 default: pw.println("Unknown get option: " + arg); break;
3814 }
3815 } finally {
3816 Binder.restoreCallingIdentity(token);
3817 }
3818 } else {
3819 pw.println("Argument required");
3820 }
3821 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003822 } else if ("disable".equals(cmd)) {
3823 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3824 null);
3825 synchronized (this) {
3826 long token = Binder.clearCallingIdentity();
Dianne Hackbornb6843652016-02-22 12:20:13 -08003827 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003828 try {
Dianne Hackbornb6843652016-02-22 12:20:13 -08003829 boolean becomeActive = false;
3830 boolean valid = false;
3831 if (arg == null || "deep".equals(arg) || "all".equals(arg)) {
3832 valid = true;
3833 if (mDeepEnabled) {
3834 mDeepEnabled = false;
3835 becomeActive = true;
3836 pw.println("Deep idle mode disabled");
3837 }
3838 }
3839 if (arg == null || "light".equals(arg) || "all".equals(arg)) {
3840 valid = true;
3841 if (mLightEnabled) {
3842 mLightEnabled = false;
3843 becomeActive = true;
3844 pw.println("Light idle mode disabled");
3845 }
3846 }
3847 if (becomeActive) {
Denny cy Leec5a7c292019-01-01 17:37:55 +08003848 mActiveReason = ACTIVE_REASON_FORCED;
Dianne Hackbornb6843652016-02-22 12:20:13 -08003849 becomeActiveLocked((arg == null ? "all" : arg) + "-disabled",
3850 Process.myUid());
3851 }
3852 if (!valid) {
3853 pw.println("Unknown idle mode: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003854 }
3855 } finally {
3856 Binder.restoreCallingIdentity(token);
3857 }
3858 }
3859 } else if ("enable".equals(cmd)) {
3860 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3861 null);
3862 synchronized (this) {
3863 long token = Binder.clearCallingIdentity();
Dianne Hackbornb6843652016-02-22 12:20:13 -08003864 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003865 try {
Dianne Hackbornb6843652016-02-22 12:20:13 -08003866 boolean becomeInactive = false;
3867 boolean valid = false;
3868 if (arg == null || "deep".equals(arg) || "all".equals(arg)) {
3869 valid = true;
3870 if (!mDeepEnabled) {
3871 mDeepEnabled = true;
3872 becomeInactive = true;
3873 pw.println("Deep idle mode enabled");
3874 }
3875 }
3876 if (arg == null || "light".equals(arg) || "all".equals(arg)) {
3877 valid = true;
3878 if (!mLightEnabled) {
3879 mLightEnabled = true;
3880 becomeInactive = true;
3881 pw.println("Light idle mode enable");
3882 }
3883 }
3884 if (becomeInactive) {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003885 becomeInactiveIfAppropriateLocked();
Dianne Hackbornb6843652016-02-22 12:20:13 -08003886 }
3887 if (!valid) {
3888 pw.println("Unknown idle mode: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003889 }
3890 } finally {
3891 Binder.restoreCallingIdentity(token);
3892 }
3893 }
3894 } else if ("enabled".equals(cmd)) {
3895 synchronized (this) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08003896 String arg = shell.getNextArg();
3897 if (arg == null || "all".equals(arg)) {
3898 pw.println(mDeepEnabled && mLightEnabled ? "1" : 0);
3899 } else if ("deep".equals(arg)) {
3900 pw.println(mDeepEnabled ? "1" : 0);
3901 } else if ("light".equals(arg)) {
3902 pw.println(mLightEnabled ? "1" : 0);
3903 } else {
3904 pw.println("Unknown idle mode: " + arg);
3905 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003906 }
3907 } else if ("whitelist".equals(cmd)) {
Dianne Hackborneb909e32016-09-29 14:35:15 -07003908 String arg = shell.getNextArg();
3909 if (arg != null) {
3910 getContext().enforceCallingOrSelfPermission(
3911 android.Manifest.permission.DEVICE_POWER, null);
3912 long token = Binder.clearCallingIdentity();
3913 try {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003914 do {
3915 if (arg.length() < 1 || (arg.charAt(0) != '-'
Felipe Lemef8a46232016-02-10 13:51:54 -08003916 && arg.charAt(0) != '+' && arg.charAt(0) != '=')) {
3917 pw.println("Package must be prefixed with +, -, or =: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003918 return -1;
3919 }
3920 char op = arg.charAt(0);
3921 String pkg = arg.substring(1);
3922 if (op == '+') {
3923 if (addPowerSaveWhitelistAppInternal(pkg)) {
3924 pw.println("Added: " + pkg);
3925 } else {
3926 pw.println("Unknown package: " + pkg);
3927 }
Felipe Lemef8a46232016-02-10 13:51:54 -08003928 } else if (op == '-') {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003929 if (removePowerSaveWhitelistAppInternal(pkg)) {
3930 pw.println("Removed: " + pkg);
3931 }
Felipe Lemef8a46232016-02-10 13:51:54 -08003932 } else {
3933 pw.println(getPowerSaveWhitelistAppInternal(pkg));
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003934 }
3935 } while ((arg=shell.getNextArg()) != null);
Dianne Hackborneb909e32016-09-29 14:35:15 -07003936 } finally {
3937 Binder.restoreCallingIdentity(token);
3938 }
3939 } else {
3940 synchronized (this) {
3941 for (int j=0; j<mPowerSaveWhitelistAppsExceptIdle.size(); j++) {
3942 pw.print("system-excidle,");
3943 pw.print(mPowerSaveWhitelistAppsExceptIdle.keyAt(j));
3944 pw.print(",");
3945 pw.println(mPowerSaveWhitelistAppsExceptIdle.valueAt(j));
3946 }
3947 for (int j=0; j<mPowerSaveWhitelistApps.size(); j++) {
3948 pw.print("system,");
3949 pw.print(mPowerSaveWhitelistApps.keyAt(j));
3950 pw.print(",");
3951 pw.println(mPowerSaveWhitelistApps.valueAt(j));
3952 }
3953 for (int j=0; j<mPowerSaveWhitelistUserApps.size(); j++) {
3954 pw.print("user,");
3955 pw.print(mPowerSaveWhitelistUserApps.keyAt(j));
3956 pw.print(",");
3957 pw.println(mPowerSaveWhitelistUserApps.valueAt(j));
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003958 }
3959 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003960 }
3961 } else if ("tempwhitelist".equals(cmd)) {
Dianne Hackborn85e35642017-01-12 15:10:57 -08003962 long duration = 10000;
Sudheer Shanka326b3112017-11-27 14:40:57 -08003963 boolean removePkg = false;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003964 String opt;
3965 while ((opt=shell.getNextOption()) != null) {
3966 if ("-u".equals(opt)) {
3967 opt = shell.getNextArg();
3968 if (opt == null) {
3969 pw.println("-u requires a user number");
3970 return -1;
3971 }
3972 shell.userId = Integer.parseInt(opt);
Dianne Hackborn85e35642017-01-12 15:10:57 -08003973 } else if ("-d".equals(opt)) {
3974 opt = shell.getNextArg();
3975 if (opt == null) {
3976 pw.println("-d requires a duration");
3977 return -1;
3978 }
3979 duration = Long.parseLong(opt);
Sudheer Shanka326b3112017-11-27 14:40:57 -08003980 } else if ("-r".equals(opt)) {
3981 removePkg = true;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003982 }
3983 }
3984 String arg = shell.getNextArg();
3985 if (arg != null) {
3986 try {
Sudheer Shanka326b3112017-11-27 14:40:57 -08003987 if (removePkg) {
3988 removePowerSaveTempWhitelistAppChecked(arg, shell.userId);
3989 } else {
3990 addPowerSaveTempWhitelistAppChecked(arg, duration, shell.userId, "shell");
3991 }
Christopher Tateec3a9f32017-03-21 17:43:47 -07003992 } catch (Exception e) {
3993 pw.println("Failed: " + e);
3994 return -1;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003995 }
Sudheer Shanka326b3112017-11-27 14:40:57 -08003996 } else if (removePkg) {
3997 pw.println("[-r] requires a package name");
3998 return -1;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003999 } else {
Felipe Lemea1b79bf2016-05-24 13:06:54 -07004000 dumpTempWhitelistSchedule(pw, false);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07004001 }
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07004002 } else if ("except-idle-whitelist".equals(cmd)) {
4003 getContext().enforceCallingOrSelfPermission(
4004 android.Manifest.permission.DEVICE_POWER, null);
4005 final long token = Binder.clearCallingIdentity();
4006 try {
4007 String arg = shell.getNextArg();
4008 if (arg == null) {
4009 pw.println("No arguments given");
4010 return -1;
4011 } else if ("reset".equals(arg)) {
4012 resetPowerSaveWhitelistExceptIdleInternal();
4013 } else {
4014 do {
4015 if (arg.length() < 1 || (arg.charAt(0) != '-'
4016 && arg.charAt(0) != '+' && arg.charAt(0) != '=')) {
4017 pw.println("Package must be prefixed with +, -, or =: " + arg);
4018 return -1;
4019 }
4020 char op = arg.charAt(0);
4021 String pkg = arg.substring(1);
4022 if (op == '+') {
4023 if (addPowerSaveWhitelistExceptIdleInternal(pkg)) {
4024 pw.println("Added: " + pkg);
4025 } else {
4026 pw.println("Unknown package: " + pkg);
4027 }
4028 } else if (op == '=') {
4029 pw.println(getPowerSaveWhitelistExceptIdleInternal(pkg));
4030 } else {
4031 pw.println("Unknown argument: " + arg);
4032 return -1;
4033 }
4034 } while ((arg = shell.getNextArg()) != null);
4035 }
4036 } finally {
4037 Binder.restoreCallingIdentity(token);
4038 }
Suprabh Shukla08105642017-09-26 14:45:30 -07004039 } else if ("sys-whitelist".equals(cmd)) {
4040 String arg = shell.getNextArg();
4041 if (arg != null) {
4042 getContext().enforceCallingOrSelfPermission(
4043 android.Manifest.permission.DEVICE_POWER, null);
4044 final long token = Binder.clearCallingIdentity();
4045 try {
4046 if ("reset".equals(arg)) {
4047 resetSystemPowerWhitelistInternal();
4048 } else {
4049 do {
4050 if (arg.length() < 1
4051 || (arg.charAt(0) != '-' && arg.charAt(0) != '+')) {
4052 pw.println("Package must be prefixed with + or - " + arg);
4053 return -1;
4054 }
4055 final char op = arg.charAt(0);
4056 final String pkg = arg.substring(1);
4057 switch (op) {
4058 case '+':
4059 if (restoreSystemPowerWhitelistAppInternal(pkg)) {
4060 pw.println("Restored " + pkg);
4061 }
4062 break;
4063 case '-':
4064 if (removeSystemPowerWhitelistAppInternal(pkg)) {
4065 pw.println("Removed " + pkg);
4066 }
4067 break;
4068 }
4069 } while ((arg = shell.getNextArg()) != null);
4070 }
4071 } finally {
4072 Binder.restoreCallingIdentity(token);
4073 }
4074 } else {
4075 synchronized (this) {
Amith Yamasani4cb42572018-04-27 10:02:57 -07004076 for (int j = 0; j < mPowerSaveWhitelistApps.size(); j++) {
Suprabh Shukla08105642017-09-26 14:45:30 -07004077 pw.print(mPowerSaveWhitelistApps.keyAt(j));
4078 pw.print(",");
4079 pw.println(mPowerSaveWhitelistApps.valueAt(j));
4080 }
4081 }
4082 }
Amith Yamasani4cb42572018-04-27 10:02:57 -07004083 } else if ("motion".equals(cmd)) {
4084 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
4085 null);
4086 synchronized (this) {
4087 long token = Binder.clearCallingIdentity();
4088 try {
4089 motionLocked();
4090 pw.print("Light state: ");
4091 pw.print(lightStateToString(mLightState));
4092 pw.print(", deep state: ");
4093 pw.println(stateToString(mState));
4094 } finally {
4095 Binder.restoreCallingIdentity(token);
4096 }
4097 }
Denny cy Leec5a7c292019-01-01 17:37:55 +08004098 } else if ("pre-idle-factor".equals(cmd)) {
4099 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
4100 null);
4101 synchronized (this) {
4102 long token = Binder.clearCallingIdentity();
4103 int ret = SET_IDLE_FACTOR_RESULT_UNINIT;
4104 try {
4105 String arg = shell.getNextArg();
4106 boolean valid = false;
4107 int mode = 0;
4108 if (arg != null) {
4109 mode = Integer.parseInt(arg);
4110 ret = setPreIdleTimeoutMode(mode);
4111 if (ret == SET_IDLE_FACTOR_RESULT_OK) {
4112 pw.println("pre-idle-factor: " + mode);
4113 valid = true;
4114 } else if (ret == SET_IDLE_FACTOR_RESULT_NOT_SUPPORT) {
4115 valid = true;
4116 pw.println("Deep idle not supported");
4117 } else if (ret == SET_IDLE_FACTOR_RESULT_IGNORED) {
4118 valid = true;
4119 pw.println("Idle timeout factor not changed");
4120 }
4121 }
4122 if (!valid) {
4123 pw.println("Unknown idle timeout factor: " + arg
4124 + ",(error code: " + ret + ")");
4125 }
4126 } catch (NumberFormatException e) {
4127 pw.println("Unknown idle timeout factor"
4128 + ",(error code: " + ret + ")");
4129 } finally {
4130 Binder.restoreCallingIdentity(token);
4131 }
4132 }
4133 } else if ("reset-pre-idle-factor".equals(cmd)) {
4134 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
4135 null);
4136 synchronized (this) {
4137 long token = Binder.clearCallingIdentity();
4138 try {
4139 resetPreIdleTimeoutMode();
4140 } finally {
4141 Binder.restoreCallingIdentity(token);
4142 }
4143 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07004144 } else {
4145 return shell.handleDefaultCommands(cmd);
4146 }
4147 return 0;
4148 }
4149
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004150 void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06004151 if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004152
4153 if (args != null) {
Xiaohui Chen7c696362015-09-16 09:56:14 -07004154 int userId = UserHandle.USER_SYSTEM;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004155 for (int i=0; i<args.length; i++) {
4156 String arg = args[i];
4157 if ("-h".equals(arg)) {
4158 dumpHelp(pw);
4159 return;
Amith Yamasaniaf575b92015-05-29 15:35:26 -07004160 } else if ("-u".equals(arg)) {
4161 i++;
4162 if (i < args.length) {
4163 arg = args[i];
4164 userId = Integer.parseInt(arg);
4165 }
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07004166 } else if ("-a".equals(arg)) {
4167 // Ignore, we always dump all.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004168 } else if (arg.length() > 0 && arg.charAt(0) == '-'){
4169 pw.println("Unknown option: " + arg);
4170 return;
4171 } else {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07004172 Shell shell = new Shell();
4173 shell.userId = userId;
4174 String[] newArgs = new String[args.length-i];
4175 System.arraycopy(args, i, newArgs, 0, args.length-i);
Dianne Hackborn354736e2016-08-22 17:00:05 -07004176 shell.exec(mBinderService, null, fd, null, newArgs, null,
4177 new ResultReceiver(null));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004178 return;
4179 }
4180 }
4181 }
4182
4183 synchronized (this) {
Dianne Hackborna750a632015-06-16 17:18:23 -07004184 mConstants.dump(pw);
4185
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08004186 if (mEventCmds[0] != EVENT_NULL) {
4187 pw.println(" Idling history:");
4188 long now = SystemClock.elapsedRealtime();
4189 for (int i=EVENT_BUFFER_SIZE-1; i>=0; i--) {
4190 int cmd = mEventCmds[i];
4191 if (cmd == EVENT_NULL) {
4192 continue;
4193 }
4194 String label;
4195 switch (mEventCmds[i]) {
4196 case EVENT_NORMAL: label = " normal"; break;
4197 case EVENT_LIGHT_IDLE: label = " light-idle"; break;
4198 case EVENT_LIGHT_MAINTENANCE: label = "light-maint"; break;
Dianne Hackbornb6843652016-02-22 12:20:13 -08004199 case EVENT_DEEP_IDLE: label = " deep-idle"; break;
4200 case EVENT_DEEP_MAINTENANCE: label = " deep-maint"; break;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08004201 default: label = " ??"; break;
4202 }
4203 pw.print(" ");
4204 pw.print(label);
4205 pw.print(": ");
Amith Yamasaniac6517a2018-04-23 12:19:34 -07004206 TimeUtils.formatDuration(mEventTimes[i], now, pw);
4207 if (mEventReasons[i] != null) {
4208 pw.print(" (");
4209 pw.print(mEventReasons[i]);
4210 pw.print(")");
4211 }
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08004212 pw.println();
Amith Yamasaniac6517a2018-04-23 12:19:34 -07004213
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08004214 }
4215 }
4216
Dianne Hackborn4a503b12015-08-06 22:19:06 -07004217 int size = mPowerSaveWhitelistAppsExceptIdle.size();
4218 if (size > 0) {
4219 pw.println(" Whitelist (except idle) system apps:");
4220 for (int i = 0; i < size; i++) {
4221 pw.print(" ");
4222 pw.println(mPowerSaveWhitelistAppsExceptIdle.keyAt(i));
4223 }
4224 }
4225 size = mPowerSaveWhitelistApps.size();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004226 if (size > 0) {
4227 pw.println(" Whitelist system apps:");
4228 for (int i = 0; i < size; i++) {
4229 pw.print(" ");
4230 pw.println(mPowerSaveWhitelistApps.keyAt(i));
4231 }
4232 }
Suprabh Shukla08105642017-09-26 14:45:30 -07004233 size = mRemovedFromSystemWhitelistApps.size();
4234 if (size > 0) {
4235 pw.println(" Removed from whitelist system apps:");
4236 for (int i = 0; i < size; i++) {
4237 pw.print(" ");
4238 pw.println(mRemovedFromSystemWhitelistApps.keyAt(i));
4239 }
4240 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004241 size = mPowerSaveWhitelistUserApps.size();
4242 if (size > 0) {
4243 pw.println(" Whitelist user apps:");
4244 for (int i = 0; i < size; i++) {
4245 pw.print(" ");
4246 pw.println(mPowerSaveWhitelistUserApps.keyAt(i));
4247 }
4248 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07004249 size = mPowerSaveWhitelistExceptIdleAppIds.size();
4250 if (size > 0) {
4251 pw.println(" Whitelist (except idle) all app ids:");
4252 for (int i = 0; i < size; i++) {
4253 pw.print(" ");
4254 pw.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
4255 pw.println();
4256 }
4257 }
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08004258 size = mPowerSaveWhitelistUserAppIds.size();
4259 if (size > 0) {
4260 pw.println(" Whitelist user app ids:");
4261 for (int i = 0; i < size; i++) {
4262 pw.print(" ");
4263 pw.print(mPowerSaveWhitelistUserAppIds.keyAt(i));
4264 pw.println();
4265 }
4266 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07004267 size = mPowerSaveWhitelistAllAppIds.size();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004268 if (size > 0) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07004269 pw.println(" Whitelist all app ids:");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004270 for (int i = 0; i < size; i++) {
Dianne Hackborna750a632015-06-16 17:18:23 -07004271 pw.print(" ");
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07004272 pw.print(mPowerSaveWhitelistAllAppIds.keyAt(i));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004273 pw.println();
4274 }
4275 }
Felipe Lemea1b79bf2016-05-24 13:06:54 -07004276 dumpTempWhitelistSchedule(pw, true);
4277
Dianne Hackborna750a632015-06-16 17:18:23 -07004278 size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0;
4279 if (size > 0) {
4280 pw.println(" Temp whitelist app ids:");
4281 for (int i = 0; i < size; i++) {
4282 pw.print(" ");
4283 pw.print(mTempWhitelistAppIdArray[i]);
4284 pw.println();
4285 }
4286 }
Adam Lesinski31c05d12015-06-09 17:34:04 -07004287
Dianne Hackbornb6843652016-02-22 12:20:13 -08004288 pw.print(" mLightEnabled="); pw.print(mLightEnabled);
Felipe Lemea1b79bf2016-05-24 13:06:54 -07004289 pw.print(" mDeepEnabled="); pw.println(mDeepEnabled);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07004290 pw.print(" mForceIdle="); pw.println(mForceIdle);
Robin Leec4d424c2018-12-07 15:09:13 +01004291 pw.print(" mUseMotionSensor="); pw.print(mUseMotionSensor);
4292 if (mUseMotionSensor) {
4293 pw.print(" mMotionSensor="); pw.println(mMotionSensor);
4294 } else {
4295 pw.println();
4296 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004297 pw.print(" mScreenOn="); pw.println(mScreenOn);
Amith Yamasani396a10c2018-01-19 10:58:07 -08004298 pw.print(" mScreenLocked="); pw.println(mScreenLocked);
Dianne Hackborn88c41352016-04-07 15:18:58 -07004299 pw.print(" mNetworkConnected="); pw.println(mNetworkConnected);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004300 pw.print(" mCharging="); pw.println(mCharging);
Robin Lee876b88542018-11-13 17:22:24 +01004301 if (mConstraints.size() != 0) {
4302 pw.println(" mConstraints={");
4303 for (int i = 0; i < mConstraints.size(); i++) {
4304 final DeviceIdleConstraintTracker tracker = mConstraints.valueAt(i);
4305 pw.print(" \""); pw.print(tracker.name); pw.print("\"=");
4306 if (tracker.minState == mState) {
4307 pw.println(tracker.active);
4308 } else {
4309 pw.print("ignored <mMinState="); pw.print(stateToString(tracker.minState));
4310 pw.println(">");
4311 }
4312 }
4313 pw.println(" }");
4314 }
Robin Leec4d424c2018-12-07 15:09:13 +01004315 if (mUseMotionSensor) {
Robin Lee876b88542018-11-13 17:22:24 +01004316 pw.print(" mMotionActive="); pw.println(mMotionListener.active);
Robin Leec4d424c2018-12-07 15:09:13 +01004317 pw.print(" mNotMoving="); pw.println(mNotMoving);
4318 }
Joe LaPenna23d681b2015-08-27 15:12:11 -07004319 pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHasGps=");
4320 pw.print(mHasGps); pw.print(" mHasNetwork=");
4321 pw.print(mHasNetworkLocation); pw.print(" mLocated="); pw.println(mLocated);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07004322 if (mLastGenericLocation != null) {
4323 pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation);
4324 }
4325 if (mLastGpsLocation != null) {
4326 pw.print(" mLastGpsLocation="); pw.println(mLastGpsLocation);
4327 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004328 pw.print(" mState="); pw.print(stateToString(mState));
4329 pw.print(" mLightState=");
4330 pw.println(lightStateToString(mLightState));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004331 pw.print(" mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw);
4332 pw.println();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08004333 if (mActiveIdleOpCount != 0) {
4334 pw.print(" mActiveIdleOpCount="); pw.println(mActiveIdleOpCount);
4335 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004336 if (mNextAlarmTime != 0) {
4337 pw.print(" mNextAlarmTime=");
4338 TimeUtils.formatDuration(mNextAlarmTime, SystemClock.elapsedRealtime(), pw);
4339 pw.println();
4340 }
4341 if (mNextIdlePendingDelay != 0) {
4342 pw.print(" mNextIdlePendingDelay=");
4343 TimeUtils.formatDuration(mNextIdlePendingDelay, pw);
4344 pw.println();
4345 }
4346 if (mNextIdleDelay != 0) {
4347 pw.print(" mNextIdleDelay=");
4348 TimeUtils.formatDuration(mNextIdleDelay, pw);
4349 pw.println();
4350 }
Dianne Hackborn953fc942016-03-29 15:36:24 -07004351 if (mNextLightIdleDelay != 0) {
4352 pw.print(" mNextIdleDelay=");
4353 TimeUtils.formatDuration(mNextLightIdleDelay, pw);
4354 pw.println();
4355 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004356 if (mNextLightAlarmTime != 0) {
4357 pw.print(" mNextLightAlarmTime=");
4358 TimeUtils.formatDuration(mNextLightAlarmTime, SystemClock.elapsedRealtime(), pw);
4359 pw.println();
4360 }
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08004361 if (mCurIdleBudget != 0) {
4362 pw.print(" mCurIdleBudget=");
4363 TimeUtils.formatDuration(mCurIdleBudget, pw);
4364 pw.println();
4365 }
4366 if (mMaintenanceStartTime != 0) {
4367 pw.print(" mMaintenanceStartTime=");
4368 TimeUtils.formatDuration(mMaintenanceStartTime, SystemClock.elapsedRealtime(), pw);
4369 pw.println();
4370 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08004371 if (mJobsActive) {
4372 pw.print(" mJobsActive="); pw.println(mJobsActive);
4373 }
4374 if (mAlarmsActive) {
4375 pw.print(" mAlarmsActive="); pw.println(mAlarmsActive);
4376 }
Denny cy Leec5a7c292019-01-01 17:37:55 +08004377 if (Math.abs(mPreIdleFactor - 1.0f) > MIN_PRE_IDLE_FACTOR_CHANGE) {
4378 pw.print(" mPreIdleFactor="); pw.println(mPreIdleFactor);
4379 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004380 }
4381 }
Felipe Lemea1b79bf2016-05-24 13:06:54 -07004382
4383 void dumpTempWhitelistSchedule(PrintWriter pw, boolean printTitle) {
4384 final int size = mTempWhitelistAppIdEndTimes.size();
4385 if (size > 0) {
4386 String prefix = "";
4387 if (printTitle) {
4388 pw.println(" Temp whitelist schedule:");
4389 prefix = " ";
4390 }
4391 final long timeNow = SystemClock.elapsedRealtime();
4392 for (int i = 0; i < size; i++) {
4393 pw.print(prefix);
4394 pw.print("UID=");
4395 pw.print(mTempWhitelistAppIdEndTimes.keyAt(i));
4396 pw.print(": ");
4397 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.valueAt(i);
4398 TimeUtils.formatDuration(entry.first.value, timeNow, pw);
4399 pw.print(" - ");
4400 pw.println(entry.second);
4401 }
4402 }
4403 }
4404 }