blob: 39030aaf3eb4a840134beb6ce589e3edcb04dcb8 [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;
274 private IBatteryStats mBatteryStats;
Dianne Hackborn85e35642017-01-12 15:10:57 -0800275 private ActivityManagerInternal mLocalActivityManager;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700276 private ActivityTaskManagerInternal mLocalActivityTaskManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700277 private PowerManagerInternal mLocalPowerManager;
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700278 private PowerManager mPowerManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700279 private INetworkPolicyManager mNetworkPolicyManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700280 private SensorManager mSensorManager;
Robin Leec4d424c2018-12-07 15:09:13 +0100281 private final boolean mUseMotionSensor;
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700282 private Sensor mMotionSensor;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700283 private LocationRequest mLocationRequest;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700284 private Intent mIdleIntent;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700285 private Intent mLightIdleIntent;
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700286 private AnyMotionDetector mAnyMotionDetector;
Makoto Onukie4918212018-02-06 11:30:15 -0800287 private final AppStateTracker mAppStateTracker;
Dianne Hackbornb6843652016-02-22 12:20:13 -0800288 private boolean mLightEnabled;
289 private boolean mDeepEnabled;
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700290 private boolean mQuickDozeActivated;
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700291 private boolean mForceIdle;
Dianne Hackborn88c41352016-04-07 15:18:58 -0700292 private boolean mNetworkConnected;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700293 private boolean mScreenOn;
294 private boolean mCharging;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700295 private boolean mNotMoving;
296 private boolean mLocating;
297 private boolean mLocated;
Joe LaPenna23d681b2015-08-27 15:12:11 -0700298 private boolean mHasGps;
299 private boolean mHasNetworkLocation;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700300 private Location mLastGenericLocation;
301 private Location mLastGpsLocation;
Amith Yamasani396a10c2018-01-19 10:58:07 -0800302 // Current locked state of the screen
303 private boolean mScreenLocked;
Robin Lee876b88542018-11-13 17:22:24 +0100304 private int mNumBlockingConstraints = 0;
305
306 /**
307 * Constraints are the "handbrakes" that stop the device from moving into a lower state until
308 * every one is released at the same time.
309 *
310 * @see #registerDeviceIdleConstraintInternal(IDeviceIdleConstraint, String, int)
311 */
312 private final ArrayMap<IDeviceIdleConstraint, DeviceIdleConstraintTracker>
313 mConstraints = new ArrayMap<>();
314 private ConstraintController mConstraintController;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700315
316 /** Device is currently active. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700317 @VisibleForTesting
318 static final int STATE_ACTIVE = 0;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700319 /** Device is inactive (screen off, no motion) and we are waiting to for idle. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700320 @VisibleForTesting
321 static final int STATE_INACTIVE = 1;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700322 /** Device is past the initial inactive period, and waiting for the next idle period. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700323 @VisibleForTesting
324 static final int STATE_IDLE_PENDING = 2;
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700325 /** Device is currently sensing motion. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700326 @VisibleForTesting
327 static final int STATE_SENSING = 3;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700328 /** Device is currently finding location (and may still be sensing). */
Kweku Adams00e3a372018-09-28 16:57:09 -0700329 @VisibleForTesting
330 static final int STATE_LOCATING = 4;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700331 /** Device is in the idle state, trying to stay asleep as much as possible. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700332 @VisibleForTesting
333 static final int STATE_IDLE = 5;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700334 /** Device is in the idle state, but temporarily out of idle to do regular maintenance. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700335 @VisibleForTesting
336 static final int STATE_IDLE_MAINTENANCE = 6;
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700337 /**
338 * Device is inactive and should go straight into idle (foregoing motion and location
339 * monitoring), but allow some time for current work to complete first.
340 */
341 @VisibleForTesting
342 static final int STATE_QUICK_DOZE_DELAY = 7;
Amith Yamasani396a10c2018-01-19 10:58:07 -0800343
Denny cy Leec5a7c292019-01-01 17:37:55 +0800344 private static final int ACTIVE_REASON_UNKNOWN = 0;
345 private static final int ACTIVE_REASON_MOTION = 1;
346 private static final int ACTIVE_REASON_SCREEN = 2;
347 private static final int ACTIVE_REASON_CHARGING = 3;
348 private static final int ACTIVE_REASON_UNLOCKED = 4;
349 private static final int ACTIVE_REASON_FROM_BINDER_CALL = 5;
350 private static final int ACTIVE_REASON_FORCED = 6;
351 private static final int ACTIVE_REASON_ALARM = 7;
352 @VisibleForTesting
353 static final int SET_IDLE_FACTOR_RESULT_UNINIT = -1;
354 @VisibleForTesting
355 static final int SET_IDLE_FACTOR_RESULT_IGNORED = 0;
356 @VisibleForTesting
357 static final int SET_IDLE_FACTOR_RESULT_OK = 1;
358 @VisibleForTesting
359 static final int SET_IDLE_FACTOR_RESULT_NOT_SUPPORT = 2;
360 @VisibleForTesting
361 static final int SET_IDLE_FACTOR_RESULT_INVALID = 3;
362 @VisibleForTesting
363 static final long MIN_STATE_STEP_ALARM_CHANGE = 60 * 1000;
364 @VisibleForTesting
365 static final float MIN_PRE_IDLE_FACTOR_CHANGE = 0.05f;
366
Kweku Adams00e3a372018-09-28 16:57:09 -0700367 @VisibleForTesting
368 static String stateToString(int state) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700369 switch (state) {
370 case STATE_ACTIVE: return "ACTIVE";
371 case STATE_INACTIVE: return "INACTIVE";
372 case STATE_IDLE_PENDING: return "IDLE_PENDING";
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700373 case STATE_SENSING: return "SENSING";
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700374 case STATE_LOCATING: return "LOCATING";
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700375 case STATE_IDLE: return "IDLE";
376 case STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE";
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700377 case STATE_QUICK_DOZE_DELAY: return "QUICK_DOZE_DELAY";
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700378 default: return Integer.toString(state);
379 }
380 }
381
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700382 /** Device is currently active. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700383 @VisibleForTesting
384 static final int LIGHT_STATE_ACTIVE = 0;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700385 /** Device is inactive (screen off) and we are waiting to for the first light idle. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700386 @VisibleForTesting
387 static final int LIGHT_STATE_INACTIVE = 1;
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700388 /** Device is about to go idle for the first time, wait for current work to complete. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700389 @VisibleForTesting
390 static final int LIGHT_STATE_PRE_IDLE = 3;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700391 /** Device is in the light idle state, trying to stay asleep as much as possible. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700392 @VisibleForTesting
393 static final int LIGHT_STATE_IDLE = 4;
Dianne Hackborn88c41352016-04-07 15:18:58 -0700394 /** Device is in the light idle state, we want to go in to idle maintenance but are
395 * waiting for network connectivity before doing so. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700396 @VisibleForTesting
397 static final int LIGHT_STATE_WAITING_FOR_NETWORK = 5;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700398 /** Device is in the light idle state, but temporarily out of idle to do regular maintenance. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700399 @VisibleForTesting
400 static final int LIGHT_STATE_IDLE_MAINTENANCE = 6;
Dianne Hackbornb6843652016-02-22 12:20:13 -0800401 /** Device light idle state is overriden, now applying deep doze state. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700402 @VisibleForTesting
403 static final int LIGHT_STATE_OVERRIDE = 7;
404
405 @VisibleForTesting
406 static String lightStateToString(int state) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700407 switch (state) {
408 case LIGHT_STATE_ACTIVE: return "ACTIVE";
409 case LIGHT_STATE_INACTIVE: return "INACTIVE";
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700410 case LIGHT_STATE_PRE_IDLE: return "PRE_IDLE";
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700411 case LIGHT_STATE_IDLE: return "IDLE";
Dianne Hackborn88c41352016-04-07 15:18:58 -0700412 case LIGHT_STATE_WAITING_FOR_NETWORK: return "WAITING_FOR_NETWORK";
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700413 case LIGHT_STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE";
414 case LIGHT_STATE_OVERRIDE: return "OVERRIDE";
415 default: return Integer.toString(state);
416 }
417 }
418
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700419 private int mState;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700420 private int mLightState;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700421
422 private long mInactiveTimeout;
423 private long mNextAlarmTime;
424 private long mNextIdlePendingDelay;
425 private long mNextIdleDelay;
Dianne Hackborn953fc942016-03-29 15:36:24 -0700426 private long mNextLightIdleDelay;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700427 private long mNextLightAlarmTime;
Kevin Gabayan92f15e62016-04-04 17:52:22 -0700428 private long mNextSensingTimeoutAlarmTime;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800429 private long mCurIdleBudget;
430 private long mMaintenanceStartTime;
Denny cy Leec5a7c292019-01-01 17:37:55 +0800431 private long mIdleStartTime;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700432
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800433 private int mActiveIdleOpCount;
Joe Onorato8f0e9ced2016-12-08 17:48:49 -0800434 private PowerManager.WakeLock mActiveIdleWakeLock; // held when there are operations in progress
435 private PowerManager.WakeLock mGoingIdleWakeLock; // held when we are going idle so hardware
436 // (especially NetworkPolicyManager) can shut
437 // down.
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800438 private boolean mJobsActive;
439 private boolean mAlarmsActive;
Yao Chenca5edbb2016-01-13 14:44:36 -0800440 private boolean mReportedMaintenanceActivity;
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800441
Denny cy Leec5a7c292019-01-01 17:37:55 +0800442 /* Factor to apply to INACTIVE_TIMEOUT and IDLE_AFTER_INACTIVE_TIMEOUT in order to enter
443 * STATE_IDLE faster or slower. Don't apply this to SENSING_TIMEOUT or LOCATING_TIMEOUT because:
444 * - Both of them are shorter
445 * - Device sensor might take time be to become be stabilized
446 * Also don't apply the factor if the device is in motion because device motion provides a
447 * stronger signal than a prediction algorithm.
448 */
449 private float mPreIdleFactor;
450 private float mLastPreIdleFactor;
451 private int mActiveReason;
452
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700453 public final AtomicFile mConfigFile;
454
Yao Chenca5edbb2016-01-13 14:44:36 -0800455 private final RemoteCallbackList<IMaintenanceActivityListener> mMaintenanceActivityListeners =
456 new RemoteCallbackList<IMaintenanceActivityListener>();
457
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700458 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700459 * Package names the system has white-listed to opt out of power save restrictions,
460 * except for device idle mode.
461 */
462 private final ArrayMap<String, Integer> mPowerSaveWhitelistAppsExceptIdle = new ArrayMap<>();
463
464 /**
Sudheer Shanka3f4d7702017-04-28 17:38:03 -0700465 * Package names the user has white-listed using commandline option to opt out of
466 * power save restrictions, except for device idle mode.
467 */
468 private final ArraySet<String> mPowerSaveWhitelistUserAppsExceptIdle = new ArraySet<>();
469
470 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700471 * Package names the system has white-listed to opt out of power save restrictions for
472 * all modes.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700473 */
474 private final ArrayMap<String, Integer> mPowerSaveWhitelistApps = new ArrayMap<>();
475
476 /**
477 * Package names the user has white-listed to opt out of power save restrictions.
478 */
479 private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>();
480
481 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700482 * App IDs of built-in system apps that have been white-listed except for idle modes.
483 */
484 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIdsExceptIdle
485 = new SparseBooleanArray();
486
487 /**
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700488 * App IDs of built-in system apps that have been white-listed.
489 */
490 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray();
491
492 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700493 * App IDs that have been white-listed to opt out of power save restrictions, except
494 * for device idle modes.
495 */
496 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
497
498 /**
499 * Current app IDs that are in the complete power save white list, but shouldn't be
500 * excluded from idle modes. This array can be shared with others because it will not be
501 * modified once set.
502 */
503 private int[] mPowerSaveWhitelistExceptIdleAppIdArray = new int[0];
504
505 /**
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700506 * App IDs that have been white-listed to opt out of power save restrictions.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700507 */
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700508 private final SparseBooleanArray mPowerSaveWhitelistAllAppIds = new SparseBooleanArray();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700509
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700510 /**
511 * Current app IDs that are in the complete power save white list. This array can
512 * be shared with others because it will not be modified once set.
513 */
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700514 private int[] mPowerSaveWhitelistAllAppIdArray = new int[0];
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700515
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700516 /**
Dianne Hackborn262ae5c2016-02-10 16:28:29 -0800517 * App IDs that have been white-listed by the user to opt out of power save restrictions.
518 */
519 private final SparseBooleanArray mPowerSaveWhitelistUserAppIds = new SparseBooleanArray();
520
521 /**
522 * Current app IDs that are in the user power save white list. This array can
523 * be shared with others because it will not be modified once set.
524 */
525 private int[] mPowerSaveWhitelistUserAppIdArray = new int[0];
526
527 /**
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700528 * List of end times for UIDs that are temporarily marked as being allowed to access
529 * the network and acquire wakelocks. Times are in milliseconds.
530 */
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700531 private final SparseArray<Pair<MutableLong, String>> mTempWhitelistAppIdEndTimes
532 = new SparseArray<>();
533
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -0700534 private NetworkPolicyManagerInternal mNetworkPolicyManagerInternal;
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700535
536 /**
537 * Current app IDs of temporarily whitelist apps for high-priority messages.
538 */
539 private int[] mTempWhitelistAppIdArray = new int[0];
540
Suprabh Shukla08105642017-09-26 14:45:30 -0700541 /**
542 * Apps in the system whitelist that have been taken out (probably because the user wanted to).
543 * They can be restored back by calling restoreAppToSystemWhitelist(String).
544 */
545 private ArrayMap<String, Integer> mRemovedFromSystemWhitelistApps = new ArrayMap<>();
546
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800547 private static final int EVENT_NULL = 0;
548 private static final int EVENT_NORMAL = 1;
549 private static final int EVENT_LIGHT_IDLE = 2;
550 private static final int EVENT_LIGHT_MAINTENANCE = 3;
Dianne Hackbornb6843652016-02-22 12:20:13 -0800551 private static final int EVENT_DEEP_IDLE = 4;
552 private static final int EVENT_DEEP_MAINTENANCE = 5;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800553
Dianne Hackbornef3aa6e2016-04-29 18:18:08 -0700554 private final int[] mEventCmds = new int[EVENT_BUFFER_SIZE];
555 private final long[] mEventTimes = new long[EVENT_BUFFER_SIZE];
Amith Yamasaniac6517a2018-04-23 12:19:34 -0700556 private final String[] mEventReasons = new String[EVENT_BUFFER_SIZE];
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800557
Amith Yamasaniac6517a2018-04-23 12:19:34 -0700558 private void addEvent(int cmd, String reason) {
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800559 if (mEventCmds[0] != cmd) {
560 System.arraycopy(mEventCmds, 0, mEventCmds, 1, EVENT_BUFFER_SIZE - 1);
561 System.arraycopy(mEventTimes, 0, mEventTimes, 1, EVENT_BUFFER_SIZE - 1);
Amith Yamasaniac6517a2018-04-23 12:19:34 -0700562 System.arraycopy(mEventReasons, 0, mEventReasons, 1, EVENT_BUFFER_SIZE - 1);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800563 mEventCmds[0] = cmd;
564 mEventTimes[0] = SystemClock.elapsedRealtime();
Amith Yamasaniac6517a2018-04-23 12:19:34 -0700565 mEventReasons[0] = reason;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800566 }
567 }
568
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700569 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
570 @Override public void onReceive(Context context, Intent intent) {
Dianne Hackborn88c41352016-04-07 15:18:58 -0700571 switch (intent.getAction()) {
572 case ConnectivityManager.CONNECTIVITY_ACTION: {
Dianne Hackborn4cb96ca2016-05-17 13:55:29 -0700573 updateConnectivityState(intent);
Dianne Hackborn88c41352016-04-07 15:18:58 -0700574 } break;
575 case Intent.ACTION_BATTERY_CHANGED: {
Robin Lee204cb222018-12-07 15:17:44 +0100576 boolean present = intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, true);
577 boolean plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
Dianne Hackborn88c41352016-04-07 15:18:58 -0700578 synchronized (DeviceIdleController.this) {
Robin Lee204cb222018-12-07 15:17:44 +0100579 updateChargingLocked(present && plugged);
Dianne Hackborn88c41352016-04-07 15:18:58 -0700580 }
581 } break;
582 case Intent.ACTION_PACKAGE_REMOVED: {
583 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
584 Uri data = intent.getData();
585 String ssp;
586 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
587 removePowerSaveWhitelistAppInternal(ssp);
588 }
589 }
590 } break;
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700591 }
592 }
593 };
594
595 private final AlarmManager.OnAlarmListener mLightAlarmListener
596 = new AlarmManager.OnAlarmListener() {
597 @Override
598 public void onAlarm() {
599 synchronized (DeviceIdleController.this) {
600 stepLightIdleStateLocked("s:alarm");
601 }
602 }
603 };
604
Kevin Gabayan92f15e62016-04-04 17:52:22 -0700605 private final AlarmManager.OnAlarmListener mSensingTimeoutAlarmListener
606 = new AlarmManager.OnAlarmListener() {
607 @Override
608 public void onAlarm() {
609 if (mState == STATE_SENSING) {
610 synchronized (DeviceIdleController.this) {
Kweku Adams00e3a372018-09-28 16:57:09 -0700611 // Restart the device idle progression in case the device moved but the screen
612 // didn't turn on.
Kevin Gabayan92f15e62016-04-04 17:52:22 -0700613 becomeInactiveIfAppropriateLocked();
614 }
615 }
616 }
617 };
618
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700619 private final AlarmManager.OnAlarmListener mDeepAlarmListener
620 = new AlarmManager.OnAlarmListener() {
621 @Override
622 public void onAlarm() {
623 synchronized (DeviceIdleController.this) {
624 stepIdleStateLocked("s:alarm");
625 }
626 }
627 };
628
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800629 private final BroadcastReceiver mIdleStartedDoneReceiver = new BroadcastReceiver() {
630 @Override public void onReceive(Context context, Intent intent) {
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700631 // When coming out of a deep idle, we will add in some delay before we allow
632 // the system to settle down and finish the maintenance window. This is
633 // to give a chance for any pending work to be scheduled.
634 if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(intent.getAction())) {
635 mHandler.sendEmptyMessageDelayed(MSG_FINISH_IDLE_OP,
636 mConstants.MIN_DEEP_MAINTENANCE_TIME);
637 } else {
638 mHandler.sendEmptyMessageDelayed(MSG_FINISH_IDLE_OP,
639 mConstants.MIN_LIGHT_MAINTENANCE_TIME);
640 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800641 }
642 };
643
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -0700644 private final BroadcastReceiver mInteractivityReceiver = new BroadcastReceiver() {
645 @Override
646 public void onReceive(Context context, Intent intent) {
Dianne Hackborn9b5ebc92017-09-08 13:45:35 -0700647 synchronized (DeviceIdleController.this) {
648 updateInteractivityLocked();
649 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700650 }
651 };
652
Kweku Adams00e3a372018-09-28 16:57:09 -0700653 @VisibleForTesting
654 final class MotionListener extends TriggerEventListener
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700655 implements SensorEventListener {
656
657 boolean active = false;
658
Kweku Adams00e3a372018-09-28 16:57:09 -0700659 public boolean isActive() {
660 return active;
661 }
662
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700663 @Override
664 public void onTrigger(TriggerEvent event) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700665 synchronized (DeviceIdleController.this) {
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700666 active = false;
667 motionLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700668 }
669 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700670
671 @Override
672 public void onSensorChanged(SensorEvent event) {
673 synchronized (DeviceIdleController.this) {
674 mSensorManager.unregisterListener(this, mMotionSensor);
675 active = false;
676 motionLocked();
677 }
678 }
679
680 @Override
681 public void onAccuracyChanged(Sensor sensor, int accuracy) {}
682
683 public boolean registerLocked() {
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700684 boolean success;
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700685 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
686 success = mSensorManager.requestTriggerSensor(mMotionListener, mMotionSensor);
687 } else {
688 success = mSensorManager.registerListener(
689 mMotionListener, mMotionSensor, SensorManager.SENSOR_DELAY_NORMAL);
690 }
691 if (success) {
692 active = true;
693 } else {
694 Slog.e(TAG, "Unable to register for " + mMotionSensor);
695 }
696 return success;
697 }
698
699 public void unregisterLocked() {
700 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
701 mSensorManager.cancelTriggerSensor(mMotionListener, mMotionSensor);
702 } else {
703 mSensorManager.unregisterListener(mMotionListener);
704 }
705 active = false;
706 }
707 }
Kweku Adams00e3a372018-09-28 16:57:09 -0700708 @VisibleForTesting final MotionListener mMotionListener = new MotionListener();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700709
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700710 private final LocationListener mGenericLocationListener = new LocationListener() {
711 @Override
712 public void onLocationChanged(Location location) {
713 synchronized (DeviceIdleController.this) {
714 receivedGenericLocationLocked(location);
715 }
716 }
717
718 @Override
719 public void onStatusChanged(String provider, int status, Bundle extras) {
720 }
721
722 @Override
723 public void onProviderEnabled(String provider) {
724 }
725
726 @Override
727 public void onProviderDisabled(String provider) {
728 }
729 };
730
731 private final LocationListener mGpsLocationListener = new LocationListener() {
732 @Override
733 public void onLocationChanged(Location location) {
734 synchronized (DeviceIdleController.this) {
735 receivedGpsLocationLocked(location);
736 }
737 }
738
739 @Override
740 public void onStatusChanged(String provider, int status, Bundle extras) {
741 }
742
743 @Override
744 public void onProviderEnabled(String provider) {
745 }
746
747 @Override
748 public void onProviderDisabled(String provider) {
749 }
750 };
751
Adam Lesinski31c05d12015-06-09 17:34:04 -0700752 /**
753 * All times are in milliseconds. These constants are kept synchronized with the system
754 * global Settings. Any access to this class or its fields should be done while
755 * holding the DeviceIdleController lock.
756 */
Robin Lee876b88542018-11-13 17:22:24 +0100757 public final class Constants extends ContentObserver {
Adam Lesinski31c05d12015-06-09 17:34:04 -0700758 // Key names stored in the settings value.
Dianne Hackborn953fc942016-03-29 15:36:24 -0700759 private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT
760 = "light_after_inactive_to";
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700761 private static final String KEY_LIGHT_PRE_IDLE_TIMEOUT = "light_pre_idle_to";
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700762 private static final String KEY_LIGHT_IDLE_TIMEOUT = "light_idle_to";
Dianne Hackborn953fc942016-03-29 15:36:24 -0700763 private static final String KEY_LIGHT_IDLE_FACTOR = "light_idle_factor";
764 private static final String KEY_LIGHT_MAX_IDLE_TIMEOUT = "light_max_idle_to";
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800765 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET
766 = "light_idle_maintenance_min_budget";
767 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET
768 = "light_idle_maintenance_max_budget";
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700769 private static final String KEY_MIN_LIGHT_MAINTENANCE_TIME = "min_light_maintenance_time";
770 private static final String KEY_MIN_DEEP_MAINTENANCE_TIME = "min_deep_maintenance_time";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700771 private static final String KEY_INACTIVE_TIMEOUT = "inactive_to";
772 private static final String KEY_SENSING_TIMEOUT = "sensing_to";
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700773 private static final String KEY_LOCATING_TIMEOUT = "locating_to";
774 private static final String KEY_LOCATION_ACCURACY = "location_accuracy";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700775 private static final String KEY_MOTION_INACTIVE_TIMEOUT = "motion_inactive_to";
776 private static final String KEY_IDLE_AFTER_INACTIVE_TIMEOUT = "idle_after_inactive_to";
777 private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to";
778 private static final String KEY_MAX_IDLE_PENDING_TIMEOUT = "max_idle_pending_to";
779 private static final String KEY_IDLE_PENDING_FACTOR = "idle_pending_factor";
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700780 private static final String KEY_QUICK_DOZE_DELAY_TIMEOUT = "quick_doze_delay_to";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700781 private static final String KEY_IDLE_TIMEOUT = "idle_to";
782 private static final String KEY_MAX_IDLE_TIMEOUT = "max_idle_to";
783 private static final String KEY_IDLE_FACTOR = "idle_factor";
784 private static final String KEY_MIN_TIME_TO_ALARM = "min_time_to_alarm";
785 private static final String KEY_MAX_TEMP_APP_WHITELIST_DURATION =
786 "max_temp_app_whitelist_duration";
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700787 private static final String KEY_MMS_TEMP_APP_WHITELIST_DURATION =
788 "mms_temp_app_whitelist_duration";
Dianne Hackborn451c3462015-07-21 17:39:46 -0700789 private static final String KEY_SMS_TEMP_APP_WHITELIST_DURATION =
790 "sms_temp_app_whitelist_duration";
Felipe Lemea1b79bf2016-05-24 13:06:54 -0700791 private static final String KEY_NOTIFICATION_WHITELIST_DURATION =
792 "notification_whitelist_duration";
Amith Yamasani396a10c2018-01-19 10:58:07 -0800793 /**
794 * Whether to wait for the user to unlock the device before causing screen-on to
795 * exit doze. Default = true
796 */
797 private static final String KEY_WAIT_FOR_UNLOCK = "wait_for_unlock";
Denny cy Leec5a7c292019-01-01 17:37:55 +0800798 private static final String KEY_PRE_IDLE_FACTOR_LONG =
799 "pre_idle_factor_long";
800 private static final String KEY_PRE_IDLE_FACTOR_SHORT =
801 "pre_idle_factor_short";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700802
803 /**
Dianne Hackborn953fc942016-03-29 15:36:24 -0700804 * This is the time, after becoming inactive, that we go in to the first
805 * light-weight idle mode.
806 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
807 * @see #KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT
808 */
809 public long LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT;
810
811 /**
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700812 * This is amount of time we will wait from the point where we decide we would
813 * like to go idle until we actually do, while waiting for jobs and other current
814 * activity to finish.
815 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
816 * @see #KEY_LIGHT_PRE_IDLE_TIMEOUT
817 */
818 public long LIGHT_PRE_IDLE_TIMEOUT;
819
820 /**
Dianne Hackborn953fc942016-03-29 15:36:24 -0700821 * This is the initial time that we will run in idle maintenance mode.
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700822 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
823 * @see #KEY_LIGHT_IDLE_TIMEOUT
824 */
825 public long LIGHT_IDLE_TIMEOUT;
826
827 /**
Dianne Hackborn953fc942016-03-29 15:36:24 -0700828 * Scaling factor to apply to the light idle mode time each time we complete a cycle.
829 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
830 * @see #KEY_LIGHT_IDLE_FACTOR
831 */
832 public float LIGHT_IDLE_FACTOR;
833
834 /**
Kweku Adams00e3a372018-09-28 16:57:09 -0700835 * This is the maximum time we will run in idle maintenance mode.
Dianne Hackborn953fc942016-03-29 15:36:24 -0700836 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
837 * @see #KEY_LIGHT_MAX_IDLE_TIMEOUT
838 */
839 public long LIGHT_MAX_IDLE_TIMEOUT;
840
841 /**
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800842 * This is the minimum amount of time we want to make available for maintenance mode
843 * when lightly idling. That is, we will always have at least this amount of time
844 * available maintenance before timing out and cutting off maintenance mode.
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700845 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800846 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700847 */
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800848 public long LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
849
850 /**
851 * This is the maximum amount of time we want to make available for maintenance mode
852 * when lightly idling. That is, if the system isn't using up its minimum maintenance
853 * budget and this time is being added to the budget reserve, this is the maximum
854 * reserve size we will allow to grow and thus the maximum amount of time we will
855 * allow for the maintenance window.
856 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
857 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET
858 */
859 public long LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700860
861 /**
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700862 * This is the minimum amount of time that we will stay in maintenance mode after
863 * a light doze. We have this minimum to allow various things to respond to switching
864 * in to maintenance mode and scheduling their work -- otherwise we may
Dianne Hackborn7ab40252016-06-15 17:30:24 -0700865 * see there is nothing to do (no jobs pending) and go out of maintenance
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700866 * mode immediately.
867 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
868 * @see #KEY_MIN_LIGHT_MAINTENANCE_TIME
869 */
870 public long MIN_LIGHT_MAINTENANCE_TIME;
871
872 /**
873 * This is the minimum amount of time that we will stay in maintenance mode after
874 * a full doze. We have this minimum to allow various things to respond to switching
875 * in to maintenance mode and scheduling their work -- otherwise we may
Dianne Hackborn7ab40252016-06-15 17:30:24 -0700876 * see there is nothing to do (no jobs pending) and go out of maintenance
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700877 * mode immediately.
878 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
879 * @see #KEY_MIN_DEEP_MAINTENANCE_TIME
880 */
881 public long MIN_DEEP_MAINTENANCE_TIME;
882
883 /**
Adam Lesinski31c05d12015-06-09 17:34:04 -0700884 * This is the time, after becoming inactive, at which we start looking at the
885 * motion sensor to determine if the device is being left alone. We don't do this
886 * immediately after going inactive just because we don't want to be continually running
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700887 * the motion sensor whenever the screen is off.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700888 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
889 * @see #KEY_INACTIVE_TIMEOUT
890 */
891 public long INACTIVE_TIMEOUT;
892
893 /**
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700894 * If we don't receive a callback from AnyMotion in this amount of time +
895 * {@link #LOCATING_TIMEOUT}, we will change from
Adam Lesinski31c05d12015-06-09 17:34:04 -0700896 * STATE_SENSING to STATE_INACTIVE, and any AnyMotion callbacks while not in STATE_SENSING
897 * will be ignored.
898 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
899 * @see #KEY_SENSING_TIMEOUT
900 */
901 public long SENSING_TIMEOUT;
902
903 /**
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700904 * This is how long we will wait to try to get a good location fix before going in to
905 * idle mode.
906 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
907 * @see #KEY_LOCATING_TIMEOUT
908 */
909 public long LOCATING_TIMEOUT;
910
911 /**
912 * The desired maximum accuracy (in meters) we consider the location to be good enough to go
913 * on to idle. We will be trying to get an accuracy fix at least this good or until
914 * {@link #LOCATING_TIMEOUT} expires.
915 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
916 * @see #KEY_LOCATION_ACCURACY
917 */
918 public float LOCATION_ACCURACY;
919
920 /**
Adam Lesinski31c05d12015-06-09 17:34:04 -0700921 * This is the time, after seeing motion, that we wait after becoming inactive from
922 * that until we start looking for motion again.
923 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
924 * @see #KEY_MOTION_INACTIVE_TIMEOUT
925 */
926 public long MOTION_INACTIVE_TIMEOUT;
927
928 /**
929 * This is the time, after the inactive timeout elapses, that we will wait looking
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700930 * for motion until we truly consider the device to be idle.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700931 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
932 * @see #KEY_IDLE_AFTER_INACTIVE_TIMEOUT
933 */
934 public long IDLE_AFTER_INACTIVE_TIMEOUT;
935
936 /**
937 * This is the initial time, after being idle, that we will allow ourself to be back
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700938 * in the IDLE_MAINTENANCE state allowing the system to run normally until we return to
939 * idle.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700940 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
941 * @see #KEY_IDLE_PENDING_TIMEOUT
942 */
943 public long IDLE_PENDING_TIMEOUT;
944
945 /**
946 * Maximum pending idle timeout (time spent running) we will be allowed to use.
947 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
948 * @see #KEY_MAX_IDLE_PENDING_TIMEOUT
949 */
950 public long MAX_IDLE_PENDING_TIMEOUT;
951
952 /**
953 * Scaling factor to apply to current pending idle timeout each time we cycle through
954 * that state.
955 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
956 * @see #KEY_IDLE_PENDING_FACTOR
957 */
958 public float IDLE_PENDING_FACTOR;
959
960 /**
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700961 * This is amount of time we will wait from the point where we go into
962 * STATE_QUICK_DOZE_DELAY until we actually go into STATE_IDLE, while waiting for jobs
963 * and other current activity to finish.
964 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
965 * @see #KEY_QUICK_DOZE_DELAY_TIMEOUT
966 */
967 public long QUICK_DOZE_DELAY_TIMEOUT;
968
969 /**
Adam Lesinski31c05d12015-06-09 17:34:04 -0700970 * This is the initial time that we want to sit in the idle state before waking up
971 * again to return to pending idle and allowing normal work to run.
972 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
973 * @see #KEY_IDLE_TIMEOUT
974 */
975 public long IDLE_TIMEOUT;
976
977 /**
978 * Maximum idle duration we will be allowed to use.
979 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
980 * @see #KEY_MAX_IDLE_TIMEOUT
981 */
982 public long MAX_IDLE_TIMEOUT;
983
984 /**
985 * Scaling factor to apply to current idle timeout each time we cycle through that state.
986 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
987 * @see #KEY_IDLE_FACTOR
988 */
989 public float IDLE_FACTOR;
990
991 /**
992 * This is the minimum time we will allow until the next upcoming alarm for us to
993 * actually go in to idle mode.
994 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
995 * @see #KEY_MIN_TIME_TO_ALARM
996 */
997 public long MIN_TIME_TO_ALARM;
998
999 /**
1000 * Max amount of time to temporarily whitelist an app when it receives a high priority
1001 * tickle.
1002 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
1003 * @see #KEY_MAX_TEMP_APP_WHITELIST_DURATION
1004 */
1005 public long MAX_TEMP_APP_WHITELIST_DURATION;
1006
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001007 /**
1008 * Amount of time we would like to whitelist an app that is receiving an MMS.
1009 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
1010 * @see #KEY_MMS_TEMP_APP_WHITELIST_DURATION
1011 */
1012 public long MMS_TEMP_APP_WHITELIST_DURATION;
1013
Dianne Hackborn451c3462015-07-21 17:39:46 -07001014 /**
1015 * Amount of time we would like to whitelist an app that is receiving an SMS.
1016 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
1017 * @see #KEY_SMS_TEMP_APP_WHITELIST_DURATION
1018 */
1019 public long SMS_TEMP_APP_WHITELIST_DURATION;
1020
Felipe Lemea1b79bf2016-05-24 13:06:54 -07001021 /**
1022 * Amount of time we would like to whitelist an app that is handling a
1023 * {@link android.app.PendingIntent} triggered by a {@link android.app.Notification}.
1024 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
1025 * @see #KEY_NOTIFICATION_WHITELIST_DURATION
1026 */
1027 public long NOTIFICATION_WHITELIST_DURATION;
1028
Denny cy Leec5a7c292019-01-01 17:37:55 +08001029 /**
1030 * Pre idle time factor use to make idle delay longer
1031 */
1032 public float PRE_IDLE_FACTOR_LONG;
1033
1034 /**
1035 * Pre idle time factor use to make idle delay shorter
1036 */
1037 public float PRE_IDLE_FACTOR_SHORT;
1038
Amith Yamasani396a10c2018-01-19 10:58:07 -08001039 public boolean WAIT_FOR_UNLOCK;
1040
Adam Lesinski31c05d12015-06-09 17:34:04 -07001041 private final ContentResolver mResolver;
shreerag597da8a2017-07-21 14:24:14 -07001042 private final boolean mSmallBatteryDevice;
Adam Lesinski31c05d12015-06-09 17:34:04 -07001043 private final KeyValueListParser mParser = new KeyValueListParser(',');
1044
1045 public Constants(Handler handler, ContentResolver resolver) {
1046 super(handler);
1047 mResolver = resolver;
shreerag597da8a2017-07-21 14:24:14 -07001048 mSmallBatteryDevice = ActivityManager.isSmallBatteryDevice();
1049 mResolver.registerContentObserver(
1050 Settings.Global.getUriFor(Settings.Global.DEVICE_IDLE_CONSTANTS),
Joe LaPennaf33b5bf2016-03-23 15:19:47 -07001051 false, this);
Adam Lesinski31c05d12015-06-09 17:34:04 -07001052 updateConstants();
1053 }
1054
1055 @Override
1056 public void onChange(boolean selfChange, Uri uri) {
1057 updateConstants();
1058 }
1059
1060 private void updateConstants() {
1061 synchronized (DeviceIdleController.this) {
1062 try {
1063 mParser.setString(Settings.Global.getString(mResolver,
shreerag597da8a2017-07-21 14:24:14 -07001064 Settings.Global.DEVICE_IDLE_CONSTANTS));
Adam Lesinski31c05d12015-06-09 17:34:04 -07001065 } catch (IllegalArgumentException e) {
1066 // Failed to parse the settings string, log this and move on
1067 // with defaults.
1068 Slog.e(TAG, "Bad device idle settings", e);
1069 }
1070
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001071 LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getDurationMillis(
Dianne Hackborn953fc942016-03-29 15:36:24 -07001072 KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
Suprabh Shukla85fff7d2018-05-08 17:39:24 -07001073 !COMPRESS_TIME ? 3 * 60 * 1000L : 15 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001074 LIGHT_PRE_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_LIGHT_PRE_IDLE_TIMEOUT,
Suprabh Shukla85fff7d2018-05-08 17:39:24 -07001075 !COMPRESS_TIME ? 3 * 60 * 1000L : 30 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001076 LIGHT_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_LIGHT_IDLE_TIMEOUT,
Dianne Hackborn953fc942016-03-29 15:36:24 -07001077 !COMPRESS_TIME ? 5 * 60 * 1000L : 15 * 1000L);
1078 LIGHT_IDLE_FACTOR = mParser.getFloat(KEY_LIGHT_IDLE_FACTOR,
1079 2f);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001080 LIGHT_MAX_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_LIGHT_MAX_IDLE_TIMEOUT,
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001081 !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001082 LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = mParser.getDurationMillis(
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001083 KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET,
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001084 !COMPRESS_TIME ? 1 * 60 * 1000L : 15 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001085 LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = mParser.getDurationMillis(
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001086 KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET,
1087 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001088 MIN_LIGHT_MAINTENANCE_TIME = mParser.getDurationMillis(
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001089 KEY_MIN_LIGHT_MAINTENANCE_TIME,
1090 !COMPRESS_TIME ? 5 * 1000L : 1 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001091 MIN_DEEP_MAINTENANCE_TIME = mParser.getDurationMillis(
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001092 KEY_MIN_DEEP_MAINTENANCE_TIME,
1093 !COMPRESS_TIME ? 30 * 1000L : 5 * 1000L);
Michael Kwan88871462017-08-21 13:13:37 -07001094 long inactiveTimeoutDefault = (mSmallBatteryDevice ? 15 : 30) * 60 * 1000L;
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001095 INACTIVE_TIMEOUT = mParser.getDurationMillis(KEY_INACTIVE_TIMEOUT,
Joe LaPenna0c5d3e92016-03-24 13:29:56 -07001096 !COMPRESS_TIME ? inactiveTimeoutDefault : (inactiveTimeoutDefault / 10));
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001097 SENSING_TIMEOUT = mParser.getDurationMillis(KEY_SENSING_TIMEOUT,
Kweku Adams9da2bb92018-12-20 06:34:39 -08001098 !COMPRESS_TIME ? 4 * 60 * 1000L : 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001099 LOCATING_TIMEOUT = mParser.getDurationMillis(KEY_LOCATING_TIMEOUT,
Kweku Adams9da2bb92018-12-20 06:34:39 -08001100 !COMPRESS_TIME ? 30 * 1000L : 15 * 1000L);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001101 LOCATION_ACCURACY = mParser.getFloat(KEY_LOCATION_ACCURACY, 20);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001102 MOTION_INACTIVE_TIMEOUT = mParser.getDurationMillis(KEY_MOTION_INACTIVE_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001103 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
Michael Kwan88871462017-08-21 13:13:37 -07001104 long idleAfterInactiveTimeout = (mSmallBatteryDevice ? 15 : 30) * 60 * 1000L;
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001105 IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getDurationMillis(
1106 KEY_IDLE_AFTER_INACTIVE_TIMEOUT,
Joe LaPenna0c5d3e92016-03-24 13:29:56 -07001107 !COMPRESS_TIME ? idleAfterInactiveTimeout
1108 : (idleAfterInactiveTimeout / 10));
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001109 IDLE_PENDING_TIMEOUT = mParser.getDurationMillis(KEY_IDLE_PENDING_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001110 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001111 MAX_IDLE_PENDING_TIMEOUT = mParser.getDurationMillis(KEY_MAX_IDLE_PENDING_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001112 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
1113 IDLE_PENDING_FACTOR = mParser.getFloat(KEY_IDLE_PENDING_FACTOR,
1114 2f);
Kweku Adamsb396ccf2018-09-17 16:37:15 -07001115 QUICK_DOZE_DELAY_TIMEOUT = mParser.getDurationMillis(
1116 KEY_QUICK_DOZE_DELAY_TIMEOUT, !COMPRESS_TIME ? 60 * 1000L : 15 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001117 IDLE_TIMEOUT = mParser.getDurationMillis(KEY_IDLE_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001118 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001119 MAX_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_MAX_IDLE_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001120 !COMPRESS_TIME ? 6 * 60 * 60 * 1000L : 30 * 60 * 1000L);
1121 IDLE_FACTOR = mParser.getFloat(KEY_IDLE_FACTOR,
1122 2f);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001123 MIN_TIME_TO_ALARM = mParser.getDurationMillis(KEY_MIN_TIME_TO_ALARM,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001124 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001125 MAX_TEMP_APP_WHITELIST_DURATION = mParser.getDurationMillis(
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001126 KEY_MAX_TEMP_APP_WHITELIST_DURATION, 5 * 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001127 MMS_TEMP_APP_WHITELIST_DURATION = mParser.getDurationMillis(
Dianne Hackborn0b6134b2015-07-14 18:48:07 -07001128 KEY_MMS_TEMP_APP_WHITELIST_DURATION, 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001129 SMS_TEMP_APP_WHITELIST_DURATION = mParser.getDurationMillis(
Dianne Hackborn451c3462015-07-21 17:39:46 -07001130 KEY_SMS_TEMP_APP_WHITELIST_DURATION, 20 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001131 NOTIFICATION_WHITELIST_DURATION = mParser.getDurationMillis(
Felipe Lemea1b79bf2016-05-24 13:06:54 -07001132 KEY_NOTIFICATION_WHITELIST_DURATION, 30 * 1000L);
Amith Yamasani396a10c2018-01-19 10:58:07 -08001133 WAIT_FOR_UNLOCK = mParser.getBoolean(KEY_WAIT_FOR_UNLOCK, false);
Denny cy Leec5a7c292019-01-01 17:37:55 +08001134 PRE_IDLE_FACTOR_LONG = mParser.getFloat(KEY_PRE_IDLE_FACTOR_LONG, 1.67f);
1135 PRE_IDLE_FACTOR_SHORT = mParser.getFloat(KEY_PRE_IDLE_FACTOR_SHORT, 0.33f);
Adam Lesinski31c05d12015-06-09 17:34:04 -07001136 }
1137 }
1138
1139 void dump(PrintWriter pw) {
1140 pw.println(" Settings:");
1141
Dianne Hackborn953fc942016-03-29 15:36:24 -07001142 pw.print(" "); pw.print(KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("=");
1143 TimeUtils.formatDuration(LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT, pw);
1144 pw.println();
1145
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001146 pw.print(" "); pw.print(KEY_LIGHT_PRE_IDLE_TIMEOUT); pw.print("=");
1147 TimeUtils.formatDuration(LIGHT_PRE_IDLE_TIMEOUT, pw);
1148 pw.println();
1149
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001150 pw.print(" "); pw.print(KEY_LIGHT_IDLE_TIMEOUT); pw.print("=");
1151 TimeUtils.formatDuration(LIGHT_IDLE_TIMEOUT, pw);
1152 pw.println();
1153
Dianne Hackborn953fc942016-03-29 15:36:24 -07001154 pw.print(" "); pw.print(KEY_LIGHT_IDLE_FACTOR); pw.print("=");
1155 pw.print(LIGHT_IDLE_FACTOR);
1156 pw.println();
1157
1158 pw.print(" "); pw.print(KEY_LIGHT_MAX_IDLE_TIMEOUT); pw.print("=");
1159 TimeUtils.formatDuration(LIGHT_MAX_IDLE_TIMEOUT, pw);
1160 pw.println();
1161
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001162 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET); pw.print("=");
1163 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MIN_BUDGET, pw);
1164 pw.println();
1165
1166 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET); pw.print("=");
1167 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MAX_BUDGET, pw);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001168 pw.println();
1169
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001170 pw.print(" "); pw.print(KEY_MIN_LIGHT_MAINTENANCE_TIME); pw.print("=");
1171 TimeUtils.formatDuration(MIN_LIGHT_MAINTENANCE_TIME, pw);
1172 pw.println();
1173
1174 pw.print(" "); pw.print(KEY_MIN_DEEP_MAINTENANCE_TIME); pw.print("=");
1175 TimeUtils.formatDuration(MIN_DEEP_MAINTENANCE_TIME, pw);
1176 pw.println();
1177
Dianne Hackborna750a632015-06-16 17:18:23 -07001178 pw.print(" "); pw.print(KEY_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001179 TimeUtils.formatDuration(INACTIVE_TIMEOUT, pw);
1180 pw.println();
1181
Dianne Hackborna750a632015-06-16 17:18:23 -07001182 pw.print(" "); pw.print(KEY_SENSING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001183 TimeUtils.formatDuration(SENSING_TIMEOUT, pw);
1184 pw.println();
1185
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001186 pw.print(" "); pw.print(KEY_LOCATING_TIMEOUT); pw.print("=");
1187 TimeUtils.formatDuration(LOCATING_TIMEOUT, pw);
1188 pw.println();
1189
1190 pw.print(" "); pw.print(KEY_LOCATION_ACCURACY); pw.print("=");
1191 pw.print(LOCATION_ACCURACY); pw.print("m");
1192 pw.println();
1193
Dianne Hackborna750a632015-06-16 17:18:23 -07001194 pw.print(" "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001195 TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT, pw);
1196 pw.println();
1197
Dianne Hackborna750a632015-06-16 17:18:23 -07001198 pw.print(" "); pw.print(KEY_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001199 TimeUtils.formatDuration(IDLE_AFTER_INACTIVE_TIMEOUT, pw);
1200 pw.println();
1201
Dianne Hackborna750a632015-06-16 17:18:23 -07001202 pw.print(" "); pw.print(KEY_IDLE_PENDING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001203 TimeUtils.formatDuration(IDLE_PENDING_TIMEOUT, pw);
1204 pw.println();
1205
Dianne Hackborna750a632015-06-16 17:18:23 -07001206 pw.print(" "); pw.print(KEY_MAX_IDLE_PENDING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001207 TimeUtils.formatDuration(MAX_IDLE_PENDING_TIMEOUT, pw);
1208 pw.println();
1209
Dianne Hackborna750a632015-06-16 17:18:23 -07001210 pw.print(" "); pw.print(KEY_IDLE_PENDING_FACTOR); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001211 pw.println(IDLE_PENDING_FACTOR);
1212
Kweku Adamsb396ccf2018-09-17 16:37:15 -07001213 pw.print(" "); pw.print(KEY_QUICK_DOZE_DELAY_TIMEOUT); pw.print("=");
1214 TimeUtils.formatDuration(QUICK_DOZE_DELAY_TIMEOUT, pw);
1215 pw.println();
1216
Dianne Hackborna750a632015-06-16 17:18:23 -07001217 pw.print(" "); pw.print(KEY_IDLE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001218 TimeUtils.formatDuration(IDLE_TIMEOUT, pw);
1219 pw.println();
1220
Dianne Hackborna750a632015-06-16 17:18:23 -07001221 pw.print(" "); pw.print(KEY_MAX_IDLE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001222 TimeUtils.formatDuration(MAX_IDLE_TIMEOUT, pw);
1223 pw.println();
1224
Dianne Hackborna750a632015-06-16 17:18:23 -07001225 pw.print(" "); pw.print(KEY_IDLE_FACTOR); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001226 pw.println(IDLE_FACTOR);
1227
Dianne Hackborna750a632015-06-16 17:18:23 -07001228 pw.print(" "); pw.print(KEY_MIN_TIME_TO_ALARM); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001229 TimeUtils.formatDuration(MIN_TIME_TO_ALARM, pw);
1230 pw.println();
1231
Dianne Hackborna750a632015-06-16 17:18:23 -07001232 pw.print(" "); pw.print(KEY_MAX_TEMP_APP_WHITELIST_DURATION); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001233 TimeUtils.formatDuration(MAX_TEMP_APP_WHITELIST_DURATION, pw);
1234 pw.println();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001235
1236 pw.print(" "); pw.print(KEY_MMS_TEMP_APP_WHITELIST_DURATION); pw.print("=");
1237 TimeUtils.formatDuration(MMS_TEMP_APP_WHITELIST_DURATION, pw);
1238 pw.println();
Dianne Hackborn451c3462015-07-21 17:39:46 -07001239
1240 pw.print(" "); pw.print(KEY_SMS_TEMP_APP_WHITELIST_DURATION); pw.print("=");
1241 TimeUtils.formatDuration(SMS_TEMP_APP_WHITELIST_DURATION, pw);
1242 pw.println();
Felipe Lemea1b79bf2016-05-24 13:06:54 -07001243
1244 pw.print(" "); pw.print(KEY_NOTIFICATION_WHITELIST_DURATION); pw.print("=");
1245 TimeUtils.formatDuration(NOTIFICATION_WHITELIST_DURATION, pw);
1246 pw.println();
Amith Yamasani396a10c2018-01-19 10:58:07 -08001247
1248 pw.print(" "); pw.print(KEY_WAIT_FOR_UNLOCK); pw.print("=");
1249 pw.println(WAIT_FOR_UNLOCK);
Denny cy Leec5a7c292019-01-01 17:37:55 +08001250
1251 pw.print(" "); pw.print(KEY_PRE_IDLE_FACTOR_LONG); pw.print("=");
1252 pw.println(PRE_IDLE_FACTOR_LONG);
1253
1254 pw.print(" "); pw.print(KEY_PRE_IDLE_FACTOR_SHORT); pw.print("=");
1255 pw.println(PRE_IDLE_FACTOR_SHORT);
Adam Lesinski31c05d12015-06-09 17:34:04 -07001256 }
1257 }
1258
1259 private Constants mConstants;
1260
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001261 @Override
1262 public void onAnyMotionResult(int result) {
1263 if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")");
Kevin Gabayan92f15e62016-04-04 17:52:22 -07001264 if (result != AnyMotionDetector.RESULT_UNKNOWN) {
1265 synchronized (this) {
1266 cancelSensingTimeoutAlarmLocked();
1267 }
1268 }
Kevin Gabayandcf47012016-07-08 10:41:24 -07001269 if ((result == AnyMotionDetector.RESULT_MOVED) ||
1270 (result == AnyMotionDetector.RESULT_UNKNOWN)) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001271 synchronized (this) {
Kevin Gabayandcf47012016-07-08 10:41:24 -07001272 handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "non_stationary");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001273 }
1274 } else if (result == AnyMotionDetector.RESULT_STATIONARY) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001275 if (mState == STATE_SENSING) {
1276 // If we are currently sensing, it is time to move to locating.
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001277 synchronized (this) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001278 mNotMoving = true;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001279 stepIdleStateLocked("s:stationary");
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001280 }
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001281 } else if (mState == STATE_LOCATING) {
1282 // If we are currently locating, note that we are not moving and step
1283 // if we have located the position.
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001284 synchronized (this) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001285 mNotMoving = true;
1286 if (mLocated) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001287 stepIdleStateLocked("s:stationary");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001288 }
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001289 }
1290 }
1291 }
1292 }
1293
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001294 private static final int MSG_WRITE_CONFIG = 1;
1295 private static final int MSG_REPORT_IDLE_ON = 2;
1296 private static final int MSG_REPORT_IDLE_ON_LIGHT = 3;
1297 private static final int MSG_REPORT_IDLE_OFF = 4;
1298 private static final int MSG_REPORT_ACTIVE = 5;
1299 private static final int MSG_TEMP_APP_WHITELIST_TIMEOUT = 6;
1300 private static final int MSG_REPORT_MAINTENANCE_ACTIVITY = 7;
1301 private static final int MSG_FINISH_IDLE_OP = 8;
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07001302 private static final int MSG_REPORT_TEMP_APP_WHITELIST_CHANGED = 9;
Robin Lee876b88542018-11-13 17:22:24 +01001303 private static final int MSG_SEND_CONSTRAINT_MONITORING = 10;
Denny cy Leec5a7c292019-01-01 17:37:55 +08001304 private static final int MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR = 11;
1305 private static final int MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR = 12;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001306
1307 final class MyHandler extends Handler {
1308 MyHandler(Looper looper) {
1309 super(looper);
1310 }
1311
1312 @Override public void handleMessage(Message msg) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001313 if (DEBUG) Slog.d(TAG, "handleMessage(" + msg.what + ")");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001314 switch (msg.what) {
1315 case MSG_WRITE_CONFIG: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001316 // Does not hold a wakelock. Just let this happen whenever.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001317 handleWriteConfigFile();
1318 } break;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001319 case MSG_REPORT_IDLE_ON:
1320 case MSG_REPORT_IDLE_ON_LIGHT: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001321 // mGoingIdleWakeLock is held at this point
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001322 EventLogTags.writeDeviceIdleOnStart();
Dianne Hackbornb6843652016-02-22 12:20:13 -08001323 final boolean deepChanged;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001324 final boolean lightChanged;
1325 if (msg.what == MSG_REPORT_IDLE_ON) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08001326 deepChanged = mLocalPowerManager.setDeviceIdleMode(true);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001327 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
1328 } else {
Dianne Hackbornb6843652016-02-22 12:20:13 -08001329 deepChanged = mLocalPowerManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001330 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(true);
1331 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001332 try {
1333 mNetworkPolicyManager.setDeviceIdleMode(true);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001334 mBatteryStats.noteDeviceIdleMode(msg.what == MSG_REPORT_IDLE_ON
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001335 ? BatteryStats.DEVICE_IDLE_MODE_DEEP
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001336 : BatteryStats.DEVICE_IDLE_MODE_LIGHT, null, Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001337 } catch (RemoteException e) {
1338 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08001339 if (deepChanged) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001340 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
1341 }
1342 if (lightChanged) {
1343 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL);
1344 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001345 EventLogTags.writeDeviceIdleOnComplete();
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001346 mGoingIdleWakeLock.release();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001347 } break;
1348 case MSG_REPORT_IDLE_OFF: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001349 // mActiveIdleWakeLock is held at this point
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001350 EventLogTags.writeDeviceIdleOffStart("unknown");
Dianne Hackbornb6843652016-02-22 12:20:13 -08001351 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001352 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001353 try {
1354 mNetworkPolicyManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001355 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF,
1356 null, Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001357 } catch (RemoteException e) {
1358 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08001359 if (deepChanged) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001360 incActiveIdleOps();
1361 getContext().sendOrderedBroadcastAsUser(mIdleIntent, UserHandle.ALL,
1362 null, mIdleStartedDoneReceiver, null, 0, null, null);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001363 }
1364 if (lightChanged) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001365 incActiveIdleOps();
1366 getContext().sendOrderedBroadcastAsUser(mLightIdleIntent, UserHandle.ALL,
1367 null, mIdleStartedDoneReceiver, null, 0, null, null);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001368 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001369 // Always start with one active op for the message being sent here.
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001370 // Now we are done!
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001371 decActiveIdleOps();
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001372 EventLogTags.writeDeviceIdleOffComplete();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001373 } break;
1374 case MSG_REPORT_ACTIVE: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001375 // The device is awake at this point, so no wakelock necessary.
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001376 String activeReason = (String)msg.obj;
1377 int activeUid = msg.arg1;
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001378 EventLogTags.writeDeviceIdleOffStart(
1379 activeReason != null ? activeReason : "unknown");
Dianne Hackbornb6843652016-02-22 12:20:13 -08001380 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001381 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001382 try {
1383 mNetworkPolicyManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001384 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF,
1385 activeReason, activeUid);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001386 } catch (RemoteException e) {
1387 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08001388 if (deepChanged) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001389 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
1390 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001391 if (lightChanged) {
1392 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL);
1393 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001394 EventLogTags.writeDeviceIdleOffComplete();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001395 } break;
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001396 case MSG_TEMP_APP_WHITELIST_TIMEOUT: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001397 // TODO: What is keeping the device awake at this point? Does it need to be?
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001398 int uid = msg.arg1;
1399 checkTempAppWhitelistTimeout(uid);
1400 } break;
Yao Chenca5edbb2016-01-13 14:44:36 -08001401 case MSG_REPORT_MAINTENANCE_ACTIVITY: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001402 // TODO: What is keeping the device awake at this point? Does it need to be?
Yao Chenca5edbb2016-01-13 14:44:36 -08001403 boolean active = (msg.arg1 == 1);
1404 final int size = mMaintenanceActivityListeners.beginBroadcast();
1405 try {
1406 for (int i = 0; i < size; i++) {
1407 try {
1408 mMaintenanceActivityListeners.getBroadcastItem(i)
1409 .onMaintenanceActivityChanged(active);
1410 } catch (RemoteException ignored) {
1411 }
1412 }
1413 } finally {
1414 mMaintenanceActivityListeners.finishBroadcast();
1415 }
1416 } break;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001417 case MSG_FINISH_IDLE_OP: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001418 // mActiveIdleWakeLock is held at this point
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001419 decActiveIdleOps();
1420 } break;
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07001421 case MSG_REPORT_TEMP_APP_WHITELIST_CHANGED: {
1422 final int appId = msg.arg1;
1423 final boolean added = (msg.arg2 == 1);
1424 mNetworkPolicyManagerInternal.onTempPowerSaveWhitelistChange(appId, added);
1425 } break;
Robin Lee876b88542018-11-13 17:22:24 +01001426 case MSG_SEND_CONSTRAINT_MONITORING: {
1427 final IDeviceIdleConstraint constraint = (IDeviceIdleConstraint) msg.obj;
1428 final boolean monitoring = (msg.arg1 == 1);
1429 if (monitoring) {
1430 constraint.startMonitoring();
1431 } else {
1432 constraint.stopMonitoring();
1433 }
1434 } break;
Denny cy Leec5a7c292019-01-01 17:37:55 +08001435 case MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR: {
1436 updatePreIdleFactor();
1437 } break;
1438 case MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR: {
1439 updatePreIdleFactor();
1440 maybeDoImmediateMaintenance();
1441 } break;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001442 }
1443 }
1444 }
1445
1446 final MyHandler mHandler;
1447
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001448 BinderService mBinderService;
1449
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001450 private final class BinderService extends IDeviceIdleController.Stub {
1451 @Override public void addPowerSaveWhitelistApp(String name) {
Eugene Susla6a7006a2017-03-13 12:57:58 -07001452 if (DEBUG) {
1453 Slog.i(TAG, "addPowerSaveWhitelistApp(name = " + name + ")");
1454 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001455 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1456 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001457 long ident = Binder.clearCallingIdentity();
1458 try {
1459 addPowerSaveWhitelistAppInternal(name);
1460 } finally {
1461 Binder.restoreCallingIdentity(ident);
1462 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001463 }
1464
1465 @Override public void removePowerSaveWhitelistApp(String name) {
Eugene Susla6a7006a2017-03-13 12:57:58 -07001466 if (DEBUG) {
1467 Slog.i(TAG, "removePowerSaveWhitelistApp(name = " + name + ")");
1468 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001469 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1470 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001471 long ident = Binder.clearCallingIdentity();
1472 try {
1473 removePowerSaveWhitelistAppInternal(name);
1474 } finally {
1475 Binder.restoreCallingIdentity(ident);
1476 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001477 }
1478
Suprabh Shukla08105642017-09-26 14:45:30 -07001479 @Override public void removeSystemPowerWhitelistApp(String name) {
1480 if (DEBUG) {
1481 Slog.d(TAG, "removeAppFromSystemWhitelist(name = " + name + ")");
1482 }
1483 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1484 null);
1485 long ident = Binder.clearCallingIdentity();
1486 try {
1487 removeSystemPowerWhitelistAppInternal(name);
1488 } finally {
1489 Binder.restoreCallingIdentity(ident);
1490 }
1491 }
1492
1493 @Override public void restoreSystemPowerWhitelistApp(String name) {
1494 if (DEBUG) {
1495 Slog.d(TAG, "restoreAppToSystemWhitelist(name = " + name + ")");
1496 }
1497 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1498 null);
1499 long ident = Binder.clearCallingIdentity();
1500 try {
1501 restoreSystemPowerWhitelistAppInternal(name);
1502 } finally {
1503 Binder.restoreCallingIdentity(ident);
1504 }
1505 }
1506
1507 public String[] getRemovedSystemPowerWhitelistApps() {
1508 return getRemovedSystemPowerWhitelistAppsInternal();
1509 }
1510
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001511 @Override public String[] getSystemPowerWhitelistExceptIdle() {
1512 return getSystemPowerWhitelistExceptIdleInternal();
1513 }
1514
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001515 @Override public String[] getSystemPowerWhitelist() {
1516 return getSystemPowerWhitelistInternal();
1517 }
1518
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001519 @Override public String[] getUserPowerWhitelist() {
1520 return getUserPowerWhitelistInternal();
1521 }
1522
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001523 @Override public String[] getFullPowerWhitelistExceptIdle() {
1524 return getFullPowerWhitelistExceptIdleInternal();
1525 }
1526
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001527 @Override public String[] getFullPowerWhitelist() {
1528 return getFullPowerWhitelistInternal();
1529 }
1530
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001531 @Override public int[] getAppIdWhitelistExceptIdle() {
1532 return getAppIdWhitelistExceptIdleInternal();
1533 }
1534
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001535 @Override public int[] getAppIdWhitelist() {
1536 return getAppIdWhitelistInternal();
1537 }
1538
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001539 @Override public int[] getAppIdUserWhitelist() {
1540 return getAppIdUserWhitelistInternal();
1541 }
1542
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001543 @Override public int[] getAppIdTempWhitelist() {
1544 return getAppIdTempWhitelistInternal();
1545 }
1546
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001547 @Override public boolean isPowerSaveWhitelistExceptIdleApp(String name) {
1548 return isPowerSaveWhitelistExceptIdleAppInternal(name);
1549 }
1550
Amith Yamasani06bf8242015-05-08 16:36:21 -07001551 @Override public boolean isPowerSaveWhitelistApp(String name) {
1552 return isPowerSaveWhitelistAppInternal(name);
1553 }
1554
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001555 @Override public void addPowerSaveTempWhitelistApp(String packageName, long duration,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001556 int userId, String reason) throws RemoteException {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001557 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001558 }
1559
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001560 @Override public long addPowerSaveTempWhitelistAppForMms(String packageName,
1561 int userId, String reason) throws RemoteException {
1562 long duration = mConstants.MMS_TEMP_APP_WHITELIST_DURATION;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001563 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001564 return duration;
1565 }
1566
Dianne Hackborn451c3462015-07-21 17:39:46 -07001567 @Override public long addPowerSaveTempWhitelistAppForSms(String packageName,
1568 int userId, String reason) throws RemoteException {
1569 long duration = mConstants.SMS_TEMP_APP_WHITELIST_DURATION;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001570 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Dianne Hackborn451c3462015-07-21 17:39:46 -07001571 return duration;
1572 }
1573
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001574 @Override public void exitIdle(String reason) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001575 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER,
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001576 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001577 long ident = Binder.clearCallingIdentity();
1578 try {
1579 exitIdleInternal(reason);
1580 } finally {
1581 Binder.restoreCallingIdentity(ident);
1582 }
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001583 }
1584
Yao Chenca5edbb2016-01-13 14:44:36 -08001585 @Override public boolean registerMaintenanceActivityListener(
1586 IMaintenanceActivityListener listener) {
1587 return DeviceIdleController.this.registerMaintenanceActivityListener(listener);
1588 }
1589
1590 @Override public void unregisterMaintenanceActivityListener(
1591 IMaintenanceActivityListener listener) {
1592 DeviceIdleController.this.unregisterMaintenanceActivityListener(listener);
1593 }
1594
Denny cy Leec5a7c292019-01-01 17:37:55 +08001595 @Override public int setPreIdleTimeoutMode(int mode) {
1596 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER,
1597 null);
1598 long ident = Binder.clearCallingIdentity();
1599 try {
1600 return DeviceIdleController.this.setPreIdleTimeoutMode(mode);
1601 } finally {
1602 Binder.restoreCallingIdentity(ident);
1603 }
1604 }
1605
1606 @Override public void resetPreIdleTimeoutMode() {
1607 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER,
1608 null);
1609 long ident = Binder.clearCallingIdentity();
1610 try {
1611 DeviceIdleController.this.resetPreIdleTimeoutMode();
1612 } finally {
1613 Binder.restoreCallingIdentity(ident);
1614 }
1615 }
1616
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001617 @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1618 DeviceIdleController.this.dump(fd, pw, args);
1619 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001620
1621 @Override public void onShellCommand(FileDescriptor in, FileDescriptor out,
Dianne Hackborn354736e2016-08-22 17:00:05 -07001622 FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
1623 (new Shell()).exec(this, in, out, err, args, callback, resultReceiver);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001624 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001625 }
1626
Felipe Lemeef134662016-08-10 14:46:39 -07001627 public class LocalService {
Robin Lee876b88542018-11-13 17:22:24 +01001628 public void onConstraintStateChanged(IDeviceIdleConstraint constraint, boolean active) {
1629 synchronized (DeviceIdleController.this) {
1630 onConstraintStateChangedLocked(constraint, active);
1631 }
1632 }
1633
1634 public void registerDeviceIdleConstraint(IDeviceIdleConstraint constraint, String name,
1635 @IDeviceIdleConstraint.MinimumState int minState) {
1636 registerDeviceIdleConstraintInternal(constraint, name, minState);
1637 }
1638
1639 public void unregisterDeviceIdleConstraint(IDeviceIdleConstraint constraint) {
1640 unregisterDeviceIdleConstraintInternal(constraint);
1641 }
1642
1643 public void exitIdle(String reason) {
1644 exitIdleInternal(reason);
1645 }
1646
Christopher Tatee0be7e82017-02-08 17:38:20 -08001647 // duration in milliseconds
1648 public void addPowerSaveTempWhitelistApp(int callingUid, String packageName,
1649 long duration, int userId, boolean sync, String reason) {
1650 addPowerSaveTempWhitelistAppInternal(callingUid, packageName, duration,
1651 userId, sync, reason);
1652 }
1653
1654 // duration in milliseconds
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001655 public void addPowerSaveTempWhitelistAppDirect(int appId, long duration, boolean sync,
1656 String reason) {
1657 addPowerSaveTempWhitelistAppDirectInternal(0, appId, duration, sync, reason);
1658 }
1659
Christopher Tatee0be7e82017-02-08 17:38:20 -08001660 // duration in milliseconds
Felipe Lemea1b79bf2016-05-24 13:06:54 -07001661 public long getNotificationWhitelistDuration() {
1662 return mConstants.NOTIFICATION_WHITELIST_DURATION;
1663 }
1664
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001665 public void setJobsActive(boolean active) {
1666 DeviceIdleController.this.setJobsActive(active);
1667 }
1668
1669 // Up-call from alarm manager.
1670 public void setAlarmsActive(boolean active) {
1671 DeviceIdleController.this.setAlarmsActive(active);
1672 }
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001673
Christopher Tate42a386b2016-11-07 12:21:21 -08001674 /** Is the app on any of the power save whitelists, whether system or user? */
1675 public boolean isAppOnWhitelist(int appid) {
1676 return DeviceIdleController.this.isAppOnWhitelistInternal(appid);
1677 }
1678
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001679 /**
1680 * Returns the array of app ids whitelisted by user. Take care not to
1681 * modify this, as it is a reference to the original copy. But the reference
1682 * can change when the list changes, so it needs to be re-acquired when
1683 * {@link PowerManager#ACTION_POWER_SAVE_WHITELIST_CHANGED} is sent.
1684 */
1685 public int[] getPowerSaveWhitelistUserAppIds() {
1686 return DeviceIdleController.this.getPowerSaveWhitelistUserAppIds();
1687 }
Suprabh Shuklaa78acfd2017-10-13 19:29:36 -07001688
1689 public int[] getPowerSaveTempWhitelistAppIds() {
1690 return DeviceIdleController.this.getAppIdTempWhitelistInternal();
1691 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001692 }
1693
Kweku Adams00e3a372018-09-28 16:57:09 -07001694 static class Injector {
1695 private final Context mContext;
Kweku Adams799858b2018-10-08 17:19:08 -07001696 private ConnectivityService mConnectivityService;
Kweku Adams9da2bb92018-12-20 06:34:39 -08001697 private Constants mConstants;
Kweku Adams799858b2018-10-08 17:19:08 -07001698 private LocationManager mLocationManager;
Kweku Adams00e3a372018-09-28 16:57:09 -07001699
1700 Injector(Context ctx) {
1701 mContext = ctx;
1702 }
1703
1704 AlarmManager getAlarmManager() {
1705 return mContext.getSystemService(AlarmManager.class);
1706 }
1707
1708 AnyMotionDetector getAnyMotionDetector(Handler handler, SensorManager sm,
1709 AnyMotionDetector.DeviceIdleCallback callback, float angleThreshold) {
1710 return new AnyMotionDetector(getPowerManager(), handler, sm, callback, angleThreshold);
1711 }
1712
1713 AppStateTracker getAppStateTracker(Context ctx, Looper looper) {
1714 return new AppStateTracker(ctx, looper);
1715 }
1716
1717 ConnectivityService getConnectivityService() {
Kweku Adams799858b2018-10-08 17:19:08 -07001718 if (mConnectivityService == null) {
1719 mConnectivityService = (ConnectivityService) ServiceManager.getService(
1720 Context.CONNECTIVITY_SERVICE);
1721 }
1722 return mConnectivityService;
Kweku Adams00e3a372018-09-28 16:57:09 -07001723 }
1724
Kweku Adamsa457f4e2018-10-03 15:56:06 -07001725 Constants getConstants(DeviceIdleController controller, Handler handler,
1726 ContentResolver resolver) {
Kweku Adams9da2bb92018-12-20 06:34:39 -08001727 if (mConstants == null) {
1728 mConstants = controller.new Constants(handler, resolver);
1729 }
1730 return mConstants;
Kweku Adamsa457f4e2018-10-03 15:56:06 -07001731 }
1732
Kweku Adams00e3a372018-09-28 16:57:09 -07001733 LocationManager getLocationManager() {
Kweku Adams799858b2018-10-08 17:19:08 -07001734 if (mLocationManager == null) {
1735 mLocationManager = mContext.getSystemService(LocationManager.class);
1736 }
1737 return mLocationManager;
Kweku Adams00e3a372018-09-28 16:57:09 -07001738 }
1739
Kweku Adamsa457f4e2018-10-03 15:56:06 -07001740 MyHandler getHandler(DeviceIdleController controller) {
1741 return controller.new MyHandler(BackgroundThread.getHandler().getLooper());
Kweku Adams00e3a372018-09-28 16:57:09 -07001742 }
1743
1744 PowerManager getPowerManager() {
1745 return mContext.getSystemService(PowerManager.class);
1746 }
Robin Lee876b88542018-11-13 17:22:24 +01001747
1748 SensorManager getSensorManager() {
1749 return mContext.getSystemService(SensorManager.class);
1750 }
1751
1752 ConstraintController getConstraintController(Handler handler, LocalService localService) {
1753 if (mContext.getPackageManager()
1754 .hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY)) {
1755 return new TvConstraintController(mContext, handler);
1756 }
1757 return null;
1758 }
1759
1760 boolean useMotionSensor() {
1761 return mContext.getResources().getBoolean(
1762 com.android.internal.R.bool.config_autoPowerModeUseMotionSensor);
1763 }
Kweku Adams00e3a372018-09-28 16:57:09 -07001764 }
1765
1766 private final Injector mInjector;
1767
Wale Ogunwale6767eae2018-05-03 15:52:51 -07001768 private ActivityTaskManagerInternal.ScreenObserver mScreenObserver =
1769 new ActivityTaskManagerInternal.ScreenObserver() {
Amith Yamasani396a10c2018-01-19 10:58:07 -08001770 @Override
1771 public void onAwakeStateChanged(boolean isAwake) { }
1772
1773 @Override
1774 public void onKeyguardStateChanged(boolean isShowing) {
1775 synchronized (DeviceIdleController.this) {
1776 DeviceIdleController.this.keyguardShowingLocked(isShowing);
1777 }
1778 }
1779 };
1780
Kweku Adams00e3a372018-09-28 16:57:09 -07001781 @VisibleForTesting DeviceIdleController(Context context, Injector injector) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001782 super(context);
Kweku Adams00e3a372018-09-28 16:57:09 -07001783 mInjector = injector;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001784 mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml"));
Kweku Adams00e3a372018-09-28 16:57:09 -07001785 mHandler = mInjector.getHandler(this);
1786 mAppStateTracker = mInjector.getAppStateTracker(context, FgThread.get().getLooper());
Makoto Onukie4918212018-02-06 11:30:15 -08001787 LocalServices.addService(AppStateTracker.class, mAppStateTracker);
Robin Lee876b88542018-11-13 17:22:24 +01001788 mUseMotionSensor = mInjector.useMotionSensor();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001789 }
1790
Kweku Adams00e3a372018-09-28 16:57:09 -07001791 public DeviceIdleController(Context context) {
1792 this(context, new Injector(context));
1793 }
1794
Christopher Tate42a386b2016-11-07 12:21:21 -08001795 boolean isAppOnWhitelistInternal(int appid) {
1796 synchronized (this) {
1797 return Arrays.binarySearch(mPowerSaveWhitelistAllAppIdArray, appid) >= 0;
1798 }
1799 }
1800
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001801 int[] getPowerSaveWhitelistUserAppIds() {
1802 synchronized (this) {
1803 return mPowerSaveWhitelistUserAppIdArray;
1804 }
1805 }
1806
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001807 private static File getSystemDir() {
1808 return new File(Environment.getDataDirectory(), "system");
1809 }
1810
1811 @Override
1812 public void onStart() {
1813 final PackageManager pm = getContext().getPackageManager();
1814
1815 synchronized (this) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08001816 mLightEnabled = mDeepEnabled = getContext().getResources().getBoolean(
Dianne Hackborn92617032015-06-19 15:32:19 -07001817 com.android.internal.R.bool.config_enableAutoPowerModes);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001818 SystemConfig sysConfig = SystemConfig.getInstance();
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001819 ArraySet<String> allowPowerExceptIdle = sysConfig.getAllowInPowerSaveExceptIdle();
1820 for (int i=0; i<allowPowerExceptIdle.size(); i++) {
1821 String pkg = allowPowerExceptIdle.valueAt(i);
1822 try {
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07001823 ApplicationInfo ai = pm.getApplicationInfo(pkg,
1824 PackageManager.MATCH_SYSTEM_ONLY);
1825 int appid = UserHandle.getAppId(ai.uid);
1826 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
1827 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001828 } catch (PackageManager.NameNotFoundException e) {
1829 }
1830 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001831 ArraySet<String> allowPower = sysConfig.getAllowInPowerSave();
1832 for (int i=0; i<allowPower.size(); i++) {
1833 String pkg = allowPower.valueAt(i);
1834 try {
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07001835 ApplicationInfo ai = pm.getApplicationInfo(pkg,
1836 PackageManager.MATCH_SYSTEM_ONLY);
1837 int appid = UserHandle.getAppId(ai.uid);
1838 // These apps are on both the whitelist-except-idle as well
1839 // as the full whitelist, so they apply in all cases.
1840 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
1841 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
1842 mPowerSaveWhitelistApps.put(ai.packageName, appid);
1843 mPowerSaveWhitelistSystemAppIds.put(appid, true);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001844 } catch (PackageManager.NameNotFoundException e) {
1845 }
1846 }
1847
Kweku Adamsa457f4e2018-10-03 15:56:06 -07001848 mConstants = mInjector.getConstants(this, mHandler, getContext().getContentResolver());
Adam Lesinski31c05d12015-06-09 17:34:04 -07001849
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001850 readConfigFileLocked();
1851 updateWhitelistAppIdsLocked();
1852
Dianne Hackborn88c41352016-04-07 15:18:58 -07001853 mNetworkConnected = true;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001854 mScreenOn = true;
Amith Yamasani396a10c2018-01-19 10:58:07 -08001855 mScreenLocked = false;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001856 // Start out assuming we are charging. If we aren't, we will at least get
1857 // a battery update the next time the level drops.
1858 mCharging = true;
Denny cy Leec5a7c292019-01-01 17:37:55 +08001859 mActiveReason = ACTIVE_REASON_UNKNOWN;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001860 mState = STATE_ACTIVE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001861 mLightState = LIGHT_STATE_ACTIVE;
Adam Lesinski31c05d12015-06-09 17:34:04 -07001862 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
Denny cy Leec5a7c292019-01-01 17:37:55 +08001863 mPreIdleFactor = 1.0f;
1864 mLastPreIdleFactor = 1.0f;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001865 }
1866
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001867 mBinderService = new BinderService();
1868 publishBinderService(Context.DEVICE_IDLE_CONTROLLER, mBinderService);
Dianne Hackborna750a632015-06-16 17:18:23 -07001869 publishLocalService(LocalService.class, new LocalService());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001870 }
1871
1872 @Override
1873 public void onBootPhase(int phase) {
1874 if (phase == PHASE_SYSTEM_SERVICES_READY) {
1875 synchronized (this) {
Kweku Adams00e3a372018-09-28 16:57:09 -07001876 mAlarmManager = mInjector.getAlarmManager();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001877 mBatteryStats = BatteryStatsService.getService();
Dianne Hackborn85e35642017-01-12 15:10:57 -08001878 mLocalActivityManager = getLocalService(ActivityManagerInternal.class);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07001879 mLocalActivityTaskManager = getLocalService(ActivityTaskManagerInternal.class);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001880 mLocalPowerManager = getLocalService(PowerManagerInternal.class);
Kweku Adams00e3a372018-09-28 16:57:09 -07001881 mPowerManager = mInjector.getPowerManager();
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001882 mActiveIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
1883 "deviceidle_maint");
1884 mActiveIdleWakeLock.setReferenceCounted(false);
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001885 mGoingIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
1886 "deviceidle_going_idle");
1887 mGoingIdleWakeLock.setReferenceCounted(true);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001888 mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface(
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001889 ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07001890 mNetworkPolicyManagerInternal = getLocalService(NetworkPolicyManagerInternal.class);
Robin Lee876b88542018-11-13 17:22:24 +01001891 mSensorManager = mInjector.getSensorManager();
Robin Leec4d424c2018-12-07 15:09:13 +01001892
1893 if (mUseMotionSensor) {
1894 int sigMotionSensorId = getContext().getResources().getInteger(
1895 com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor);
1896 if (sigMotionSensorId > 0) {
1897 mMotionSensor = mSensorManager.getDefaultSensor(sigMotionSensorId, true);
1898 }
1899 if (mMotionSensor == null && getContext().getResources().getBoolean(
1900 com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) {
1901 mMotionSensor = mSensorManager.getDefaultSensor(
1902 Sensor.TYPE_WRIST_TILT_GESTURE, true);
1903 }
1904 if (mMotionSensor == null) {
1905 // As a last ditch, fall back to SMD.
1906 mMotionSensor = mSensorManager.getDefaultSensor(
1907 Sensor.TYPE_SIGNIFICANT_MOTION, true);
1908 }
Joe LaPenna23d681b2015-08-27 15:12:11 -07001909 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001910
Joe LaPenna23d681b2015-08-27 15:12:11 -07001911 if (getContext().getResources().getBoolean(
1912 com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) {
Joe LaPenna23d681b2015-08-27 15:12:11 -07001913 mLocationRequest = new LocationRequest()
1914 .setQuality(LocationRequest.ACCURACY_FINE)
1915 .setInterval(0)
1916 .setFastestInterval(0)
1917 .setNumUpdates(1);
1918 }
1919
Robin Lee876b88542018-11-13 17:22:24 +01001920 mConstraintController = mInjector.getConstraintController(
1921 mHandler, getLocalService(LocalService.class));
1922 if (mConstraintController != null) {
1923 mConstraintController.start();
1924 }
1925
Joe LaPenna23d681b2015-08-27 15:12:11 -07001926 float angleThreshold = getContext().getResources().getInteger(
1927 com.android.internal.R.integer.config_autoPowerModeThresholdAngle) / 100f;
Kweku Adams00e3a372018-09-28 16:57:09 -07001928 mAnyMotionDetector = mInjector.getAnyMotionDetector(mHandler, mSensorManager, this,
1929 angleThreshold);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001930
Makoto Onukie4918212018-02-06 11:30:15 -08001931 mAppStateTracker.onSystemServicesReady();
1932
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001933 mIdleIntent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001934 mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1935 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001936 mLightIdleIntent = new Intent(PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
1937 mLightIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1938 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001939
1940 IntentFilter filter = new IntentFilter();
1941 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001942 getContext().registerReceiver(mReceiver, filter);
Amith Yamasaniac59f75e2016-05-05 12:38:17 -07001943
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07001944 filter = new IntentFilter();
1945 filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
1946 filter.addDataScheme("package");
Amith Yamasaniac59f75e2016-05-05 12:38:17 -07001947 getContext().registerReceiver(mReceiver, filter);
1948
Dianne Hackborn88c41352016-04-07 15:18:58 -07001949 filter = new IntentFilter();
1950 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07001951 getContext().registerReceiver(mReceiver, filter);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001952
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -07001953 filter = new IntentFilter();
1954 filter.addAction(Intent.ACTION_SCREEN_OFF);
1955 filter.addAction(Intent.ACTION_SCREEN_ON);
1956 getContext().registerReceiver(mInteractivityReceiver, filter);
1957
Makoto Onukiaf8ff4f2018-06-04 14:44:19 -07001958 mLocalActivityManager.setDeviceIdleWhitelist(
1959 mPowerSaveWhitelistAllAppIdArray, mPowerSaveWhitelistExceptIdleAppIdArray);
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001960 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -07001961
Kweku Adamsb396ccf2018-09-17 16:37:15 -07001962 mLocalPowerManager.registerLowPowerModeObserver(ServiceType.QUICK_DOZE,
1963 state -> {
1964 synchronized (DeviceIdleController.this) {
1965 updateQuickDozeFlagLocked(state.batterySaverEnabled);
1966 }
1967 });
1968 updateQuickDozeFlagLocked(
1969 mLocalPowerManager.getLowPowerState(
1970 ServiceType.QUICK_DOZE).batterySaverEnabled);
1971
Wale Ogunwale6767eae2018-05-03 15:52:51 -07001972 mLocalActivityTaskManager.registerScreenObserver(mScreenObserver);
Amith Yamasani396a10c2018-01-19 10:58:07 -08001973
Suprabh Shukla5bf49812018-05-24 18:38:50 -07001974 passWhiteListsToForceAppStandbyTrackerLocked();
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -07001975 updateInteractivityLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001976 }
Dianne Hackborn4cb96ca2016-05-17 13:55:29 -07001977 updateConnectivityState(null);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001978 }
1979 }
1980
Robin Lee876b88542018-11-13 17:22:24 +01001981 @VisibleForTesting
1982 boolean hasMotionSensor() {
1983 return mUseMotionSensor && mMotionSensor != null;
1984 }
1985
1986 private void registerDeviceIdleConstraintInternal(IDeviceIdleConstraint constraint,
1987 final String name, final int type) {
1988 final int minState;
1989 switch (type) {
1990 case IDeviceIdleConstraint.ACTIVE:
1991 minState = STATE_ACTIVE;
1992 break;
1993 case IDeviceIdleConstraint.SENSING_OR_ABOVE:
1994 minState = STATE_SENSING;
1995 break;
1996 default:
1997 Slog.wtf(TAG, "Registering device-idle constraint with invalid type: " + type);
1998 return;
1999 }
2000 synchronized (this) {
2001 if (mConstraints.containsKey(constraint)) {
2002 Slog.e(TAG, "Re-registering device-idle constraint: " + constraint + ".");
2003 return;
2004 }
2005 DeviceIdleConstraintTracker tracker = new DeviceIdleConstraintTracker(name, minState);
2006 mConstraints.put(constraint, tracker);
2007 updateActiveConstraintsLocked();
2008 }
2009 }
2010
2011 private void unregisterDeviceIdleConstraintInternal(IDeviceIdleConstraint constraint) {
2012 synchronized (this) {
2013 // Artifically force the constraint to inactive to unblock anything waiting for it.
2014 onConstraintStateChangedLocked(constraint, /* active= */ false);
2015
2016 // Let the constraint know that we are not listening to it any more.
2017 setConstraintMonitoringLocked(constraint, /* monitoring= */ false);
2018 mConstraints.remove(constraint);
2019 }
2020 }
2021
2022 @GuardedBy("this")
2023 private void onConstraintStateChangedLocked(IDeviceIdleConstraint constraint, boolean active) {
2024 DeviceIdleConstraintTracker tracker = mConstraints.get(constraint);
2025 if (tracker == null) {
2026 Slog.e(TAG, "device-idle constraint " + constraint + " has not been registered.");
2027 return;
2028 }
2029 if (active != tracker.active && tracker.monitoring) {
2030 tracker.active = active;
2031 mNumBlockingConstraints += (tracker.active ? +1 : -1);
2032 if (mNumBlockingConstraints == 0) {
2033 if (mState == STATE_ACTIVE) {
2034 becomeInactiveIfAppropriateLocked();
2035 } else if (mNextAlarmTime == 0 || mNextAlarmTime < SystemClock.elapsedRealtime()) {
2036 stepIdleStateLocked("s:" + tracker.name);
2037 }
2038 }
2039 }
2040 }
2041
2042 @GuardedBy("this")
2043 private void setConstraintMonitoringLocked(IDeviceIdleConstraint constraint, boolean monitor) {
2044 DeviceIdleConstraintTracker tracker = mConstraints.get(constraint);
2045 if (tracker.monitoring != monitor) {
2046 tracker.monitoring = monitor;
2047 updateActiveConstraintsLocked();
2048 // We send the callback on a separate thread instead of just relying on oneway as
2049 // the client could be in the system server with us and cause re-entry problems.
2050 mHandler.obtainMessage(MSG_SEND_CONSTRAINT_MONITORING,
2051 /* monitoring= */ monitor ? 1 : 0,
2052 /* <not used>= */ -1,
2053 /* constraint= */ constraint).sendToTarget();
2054 }
2055 }
2056
2057 @GuardedBy("this")
2058 private void updateActiveConstraintsLocked() {
2059 mNumBlockingConstraints = 0;
2060 for (int i = 0; i < mConstraints.size(); i++) {
2061 final IDeviceIdleConstraint constraint = mConstraints.keyAt(i);
2062 final DeviceIdleConstraintTracker tracker = mConstraints.valueAt(i);
2063 final boolean monitoring = (tracker.minState == mState);
2064 if (monitoring != tracker.monitoring) {
2065 setConstraintMonitoringLocked(constraint, monitoring);
2066 tracker.active = monitoring;
2067 }
2068 if (tracker.monitoring && tracker.active) {
2069 mNumBlockingConstraints++;
2070 }
2071 }
2072 }
2073
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002074 public boolean addPowerSaveWhitelistAppInternal(String name) {
2075 synchronized (this) {
2076 try {
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07002077 ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name,
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -07002078 PackageManager.MATCH_ANY_USER);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002079 if (mPowerSaveWhitelistUserApps.put(name, UserHandle.getAppId(ai.uid)) == null) {
2080 reportPowerSaveWhitelistChangedLocked();
2081 updateWhitelistAppIdsLocked();
2082 writeConfigFileLocked();
2083 }
2084 return true;
2085 } catch (PackageManager.NameNotFoundException e) {
2086 return false;
2087 }
2088 }
2089 }
2090
2091 public boolean removePowerSaveWhitelistAppInternal(String name) {
2092 synchronized (this) {
2093 if (mPowerSaveWhitelistUserApps.remove(name) != null) {
2094 reportPowerSaveWhitelistChangedLocked();
2095 updateWhitelistAppIdsLocked();
2096 writeConfigFileLocked();
2097 return true;
2098 }
2099 }
2100 return false;
2101 }
2102
Felipe Lemef8a46232016-02-10 13:51:54 -08002103 public boolean getPowerSaveWhitelistAppInternal(String name) {
2104 synchronized (this) {
2105 return mPowerSaveWhitelistUserApps.containsKey(name);
2106 }
2107 }
2108
Suprabh Shukla08105642017-09-26 14:45:30 -07002109 void resetSystemPowerWhitelistInternal() {
2110 synchronized (this) {
2111 mPowerSaveWhitelistApps.putAll(mRemovedFromSystemWhitelistApps);
2112 mRemovedFromSystemWhitelistApps.clear();
2113 reportPowerSaveWhitelistChangedLocked();
2114 updateWhitelistAppIdsLocked();
2115 writeConfigFileLocked();
2116 }
2117 }
2118
2119 public boolean restoreSystemPowerWhitelistAppInternal(String name) {
2120 synchronized (this) {
2121 if (!mRemovedFromSystemWhitelistApps.containsKey(name)) {
2122 return false;
2123 }
2124 mPowerSaveWhitelistApps.put(name, mRemovedFromSystemWhitelistApps.remove(name));
2125 reportPowerSaveWhitelistChangedLocked();
2126 updateWhitelistAppIdsLocked();
2127 writeConfigFileLocked();
2128 return true;
2129 }
2130 }
2131
2132 public boolean removeSystemPowerWhitelistAppInternal(String name) {
2133 synchronized (this) {
2134 if (!mPowerSaveWhitelistApps.containsKey(name)) {
2135 return false;
2136 }
2137 mRemovedFromSystemWhitelistApps.put(name, mPowerSaveWhitelistApps.remove(name));
2138 reportPowerSaveWhitelistChangedLocked();
2139 updateWhitelistAppIdsLocked();
2140 writeConfigFileLocked();
2141 return true;
2142 }
2143 }
2144
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07002145 public boolean addPowerSaveWhitelistExceptIdleInternal(String name) {
2146 synchronized (this) {
2147 try {
2148 final ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name,
2149 PackageManager.MATCH_ANY_USER);
2150 if (mPowerSaveWhitelistAppsExceptIdle.put(name, UserHandle.getAppId(ai.uid))
2151 == null) {
2152 mPowerSaveWhitelistUserAppsExceptIdle.add(name);
2153 reportPowerSaveWhitelistChangedLocked();
2154 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(
2155 mPowerSaveWhitelistAppsExceptIdle, mPowerSaveWhitelistUserApps,
2156 mPowerSaveWhitelistExceptIdleAppIds);
Makoto Onuki71755c92018-01-16 14:15:44 -08002157
Suprabh Shukla5bf49812018-05-24 18:38:50 -07002158 passWhiteListsToForceAppStandbyTrackerLocked();
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07002159 }
2160 return true;
2161 } catch (PackageManager.NameNotFoundException e) {
2162 return false;
2163 }
2164 }
2165 }
2166
2167 public void resetPowerSaveWhitelistExceptIdleInternal() {
2168 synchronized (this) {
2169 if (mPowerSaveWhitelistAppsExceptIdle.removeAll(
2170 mPowerSaveWhitelistUserAppsExceptIdle)) {
2171 reportPowerSaveWhitelistChangedLocked();
2172 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(
2173 mPowerSaveWhitelistAppsExceptIdle, mPowerSaveWhitelistUserApps,
2174 mPowerSaveWhitelistExceptIdleAppIds);
2175 mPowerSaveWhitelistUserAppsExceptIdle.clear();
Makoto Onuki71755c92018-01-16 14:15:44 -08002176
Suprabh Shukla5bf49812018-05-24 18:38:50 -07002177 passWhiteListsToForceAppStandbyTrackerLocked();
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07002178 }
2179 }
2180 }
2181
2182 public boolean getPowerSaveWhitelistExceptIdleInternal(String name) {
2183 synchronized (this) {
2184 return mPowerSaveWhitelistAppsExceptIdle.containsKey(name);
2185 }
2186 }
2187
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002188 public String[] getSystemPowerWhitelistExceptIdleInternal() {
2189 synchronized (this) {
2190 int size = mPowerSaveWhitelistAppsExceptIdle.size();
2191 String[] apps = new String[size];
2192 for (int i = 0; i < size; i++) {
2193 apps[i] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i);
2194 }
2195 return apps;
2196 }
2197 }
2198
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002199 public String[] getSystemPowerWhitelistInternal() {
2200 synchronized (this) {
2201 int size = mPowerSaveWhitelistApps.size();
2202 String[] apps = new String[size];
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002203 for (int i = 0; i < size; i++) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002204 apps[i] = mPowerSaveWhitelistApps.keyAt(i);
2205 }
2206 return apps;
2207 }
2208 }
2209
Suprabh Shukla08105642017-09-26 14:45:30 -07002210 public String[] getRemovedSystemPowerWhitelistAppsInternal() {
2211 synchronized (this) {
2212 int size = mRemovedFromSystemWhitelistApps.size();
2213 final String[] apps = new String[size];
2214 for (int i = 0; i < size; i++) {
2215 apps[i] = mRemovedFromSystemWhitelistApps.keyAt(i);
2216 }
2217 return apps;
2218 }
2219 }
2220
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002221 public String[] getUserPowerWhitelistInternal() {
2222 synchronized (this) {
2223 int size = mPowerSaveWhitelistUserApps.size();
2224 String[] apps = new String[size];
2225 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
2226 apps[i] = mPowerSaveWhitelistUserApps.keyAt(i);
2227 }
2228 return apps;
2229 }
2230 }
2231
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002232 public String[] getFullPowerWhitelistExceptIdleInternal() {
2233 synchronized (this) {
2234 int size = mPowerSaveWhitelistAppsExceptIdle.size() + mPowerSaveWhitelistUserApps.size();
2235 String[] apps = new String[size];
2236 int cur = 0;
2237 for (int i = 0; i < mPowerSaveWhitelistAppsExceptIdle.size(); i++) {
2238 apps[cur] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i);
2239 cur++;
2240 }
2241 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
2242 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i);
2243 cur++;
2244 }
2245 return apps;
2246 }
2247 }
2248
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002249 public String[] getFullPowerWhitelistInternal() {
2250 synchronized (this) {
2251 int size = mPowerSaveWhitelistApps.size() + mPowerSaveWhitelistUserApps.size();
2252 String[] apps = new String[size];
2253 int cur = 0;
2254 for (int i = 0; i < mPowerSaveWhitelistApps.size(); i++) {
2255 apps[cur] = mPowerSaveWhitelistApps.keyAt(i);
2256 cur++;
2257 }
2258 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
2259 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i);
2260 cur++;
2261 }
2262 return apps;
2263 }
2264 }
2265
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002266 public boolean isPowerSaveWhitelistExceptIdleAppInternal(String packageName) {
2267 synchronized (this) {
2268 return mPowerSaveWhitelistAppsExceptIdle.containsKey(packageName)
2269 || mPowerSaveWhitelistUserApps.containsKey(packageName);
2270 }
2271 }
2272
Amith Yamasani06bf8242015-05-08 16:36:21 -07002273 public boolean isPowerSaveWhitelistAppInternal(String packageName) {
2274 synchronized (this) {
2275 return mPowerSaveWhitelistApps.containsKey(packageName)
2276 || mPowerSaveWhitelistUserApps.containsKey(packageName);
2277 }
2278 }
2279
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002280 public int[] getAppIdWhitelistExceptIdleInternal() {
2281 synchronized (this) {
2282 return mPowerSaveWhitelistExceptIdleAppIdArray;
2283 }
2284 }
2285
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002286 public int[] getAppIdWhitelistInternal() {
2287 synchronized (this) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002288 return mPowerSaveWhitelistAllAppIdArray;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002289 }
2290 }
2291
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002292 public int[] getAppIdUserWhitelistInternal() {
2293 synchronized (this) {
2294 return mPowerSaveWhitelistUserAppIdArray;
2295 }
2296 }
2297
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002298 public int[] getAppIdTempWhitelistInternal() {
2299 synchronized (this) {
2300 return mTempWhitelistAppIdArray;
2301 }
2302 }
2303
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002304 void addPowerSaveTempWhitelistAppChecked(String packageName, long duration,
2305 int userId, String reason) throws RemoteException {
2306 getContext().enforceCallingPermission(
2307 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
2308 "No permission to change device idle whitelist");
2309 final int callingUid = Binder.getCallingUid();
Sudheer Shankadc589ac2016-11-10 15:30:17 -08002310 userId = ActivityManager.getService().handleIncomingUser(
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002311 Binder.getCallingPid(),
2312 callingUid,
2313 userId,
2314 /*allowAll=*/ false,
2315 /*requireFull=*/ false,
2316 "addPowerSaveTempWhitelistApp", null);
2317 final long token = Binder.clearCallingIdentity();
2318 try {
2319 addPowerSaveTempWhitelistAppInternal(callingUid,
2320 packageName, duration, userId, true, reason);
2321 } finally {
2322 Binder.restoreCallingIdentity(token);
2323 }
2324 }
2325
Sudheer Shanka326b3112017-11-27 14:40:57 -08002326 void removePowerSaveTempWhitelistAppChecked(String packageName, int userId)
2327 throws RemoteException {
2328 getContext().enforceCallingPermission(
2329 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
2330 "No permission to change device idle whitelist");
2331 final int callingUid = Binder.getCallingUid();
2332 userId = ActivityManager.getService().handleIncomingUser(
2333 Binder.getCallingPid(),
2334 callingUid,
2335 userId,
2336 /*allowAll=*/ false,
2337 /*requireFull=*/ false,
2338 "removePowerSaveTempWhitelistApp", null);
2339 final long token = Binder.clearCallingIdentity();
2340 try {
2341 removePowerSaveTempWhitelistAppInternal(packageName, userId);
2342 } finally {
2343 Binder.restoreCallingIdentity(token);
2344 }
2345 }
2346
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002347 /**
2348 * Adds an app to the temporary whitelist and resets the endTime for granting the
2349 * app an exemption to access network and acquire wakelocks.
2350 */
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002351 void addPowerSaveTempWhitelistAppInternal(int callingUid, String packageName,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002352 long duration, int userId, boolean sync, String reason) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002353 try {
Jeff Sharkeye06b4d12016-01-06 14:51:50 -07002354 int uid = getContext().getPackageManager().getPackageUidAsUser(packageName, userId);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002355 int appId = UserHandle.getAppId(uid);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002356 addPowerSaveTempWhitelistAppDirectInternal(callingUid, appId, duration, sync, reason);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002357 } catch (NameNotFoundException e) {
2358 }
2359 }
2360
Dianne Hackborna750a632015-06-16 17:18:23 -07002361 /**
2362 * Adds an app to the temporary whitelist and resets the endTime for granting the
2363 * app an exemption to access network and acquire wakelocks.
2364 */
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002365 void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int appId,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002366 long duration, boolean sync, String reason) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002367 final long timeNow = SystemClock.elapsedRealtime();
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07002368 boolean informWhitelistChanged = false;
Dianne Hackborna750a632015-06-16 17:18:23 -07002369 synchronized (this) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002370 int callingAppId = UserHandle.getAppId(callingUid);
2371 if (callingAppId >= Process.FIRST_APPLICATION_UID) {
2372 if (!mPowerSaveWhitelistSystemAppIds.get(callingAppId)) {
2373 throw new SecurityException("Calling app " + UserHandle.formatUid(callingUid)
2374 + " is not on whitelist");
2375 }
2376 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002377 duration = Math.min(duration, mConstants.MAX_TEMP_APP_WHITELIST_DURATION);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002378 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId);
2379 final boolean newEntry = entry == null;
Dianne Hackborna750a632015-06-16 17:18:23 -07002380 // Set the new end time
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002381 if (newEntry) {
2382 entry = new Pair<>(new MutableLong(0), reason);
2383 mTempWhitelistAppIdEndTimes.put(appId, entry);
2384 }
2385 entry.first.value = timeNow + duration;
Dianne Hackborna750a632015-06-16 17:18:23 -07002386 if (DEBUG) {
Felipe Lemea1b79bf2016-05-24 13:06:54 -07002387 Slog.d(TAG, "Adding AppId " + appId + " to temp whitelist. New entry: " + newEntry);
Dianne Hackborna750a632015-06-16 17:18:23 -07002388 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002389 if (newEntry) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002390 // No pending timeout for the app id, post a delayed message
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002391 try {
2392 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_START,
2393 reason, appId);
2394 } catch (RemoteException e) {
2395 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002396 postTempActiveTimeoutMessage(appId, duration);
Dianne Hackborn85e35642017-01-12 15:10:57 -08002397 updateTempWhitelistAppIdsLocked(appId, true);
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07002398 if (sync) {
2399 informWhitelistChanged = true;
2400 } else {
2401 mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED, appId, 1)
2402 .sendToTarget();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002403 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002404 reportTempWhitelistChangedLocked();
2405 }
2406 }
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07002407 if (informWhitelistChanged) {
2408 mNetworkPolicyManagerInternal.onTempPowerSaveWhitelistChange(appId, true);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002409 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002410 }
2411
Sudheer Shanka326b3112017-11-27 14:40:57 -08002412 /**
2413 * Removes an app from the temporary whitelist and notifies the observers.
2414 */
2415 private void removePowerSaveTempWhitelistAppInternal(String packageName, int userId) {
2416 try {
2417 final int uid = getContext().getPackageManager().getPackageUidAsUser(
2418 packageName, userId);
2419 final int appId = UserHandle.getAppId(uid);
2420 removePowerSaveTempWhitelistAppDirectInternal(appId);
2421 } catch (NameNotFoundException e) {
2422 }
2423 }
2424
2425 private void removePowerSaveTempWhitelistAppDirectInternal(int appId) {
2426 synchronized (this) {
2427 final int idx = mTempWhitelistAppIdEndTimes.indexOfKey(appId);
2428 if (idx < 0) {
2429 // Nothing else to do
2430 return;
2431 }
2432 final String reason = mTempWhitelistAppIdEndTimes.valueAt(idx).second;
2433 mTempWhitelistAppIdEndTimes.removeAt(idx);
2434 onAppRemovedFromTempWhitelistLocked(appId, reason);
2435 }
2436 }
2437
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002438 private void postTempActiveTimeoutMessage(int uid, long delay) {
Felipe Lemea1b79bf2016-05-24 13:06:54 -07002439 if (DEBUG) {
2440 Slog.d(TAG, "postTempActiveTimeoutMessage: uid=" + uid + ", delay=" + delay);
2441 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002442 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, uid, 0),
2443 delay);
2444 }
2445
2446 void checkTempAppWhitelistTimeout(int uid) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002447 final long timeNow = SystemClock.elapsedRealtime();
Felipe Lemea1b79bf2016-05-24 13:06:54 -07002448 if (DEBUG) {
2449 Slog.d(TAG, "checkTempAppWhitelistTimeout: uid=" + uid + ", timeNow=" + timeNow);
2450 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002451 synchronized (this) {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002452 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(uid);
2453 if (entry == null) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002454 // Nothing to do
2455 return;
2456 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002457 if (timeNow >= entry.first.value) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002458 mTempWhitelistAppIdEndTimes.delete(uid);
Sudheer Shanka326b3112017-11-27 14:40:57 -08002459 onAppRemovedFromTempWhitelistLocked(uid, entry.second);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002460 } else {
2461 // Need more time
Felipe Lemea1b79bf2016-05-24 13:06:54 -07002462 if (DEBUG) {
2463 Slog.d(TAG, "Time to remove UID " + uid + ": " + entry.first.value);
2464 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002465 postTempActiveTimeoutMessage(uid, entry.first.value - timeNow);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002466 }
2467 }
2468 }
2469
Sudheer Shanka326b3112017-11-27 14:40:57 -08002470 @GuardedBy("this")
2471 private void onAppRemovedFromTempWhitelistLocked(int appId, String reason) {
2472 if (DEBUG) {
2473 Slog.d(TAG, "Removing appId " + appId + " from temp whitelist");
2474 }
2475 updateTempWhitelistAppIdsLocked(appId, false);
2476 mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED, appId, 0)
2477 .sendToTarget();
2478 reportTempWhitelistChangedLocked();
2479 try {
2480 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH,
2481 reason, appId);
2482 } catch (RemoteException e) {
2483 }
2484 }
2485
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002486 public void exitIdleInternal(String reason) {
2487 synchronized (this) {
Denny cy Leec5a7c292019-01-01 17:37:55 +08002488 mActiveReason = ACTIVE_REASON_FROM_BINDER_CALL;
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002489 becomeActiveLocked(reason, Binder.getCallingUid());
2490 }
2491 }
2492
Kweku Adams799858b2018-10-08 17:19:08 -07002493 @VisibleForTesting
2494 boolean isNetworkConnected() {
2495 synchronized (this) {
2496 return mNetworkConnected;
2497 }
2498 }
2499
Dianne Hackborn4cb96ca2016-05-17 13:55:29 -07002500 void updateConnectivityState(Intent connIntent) {
2501 ConnectivityService cm;
2502 synchronized (this) {
Kweku Adams799858b2018-10-08 17:19:08 -07002503 cm = mInjector.getConnectivityService();
Dianne Hackborn4cb96ca2016-05-17 13:55:29 -07002504 }
2505 if (cm == null) {
2506 return;
2507 }
2508 // Note: can't call out to ConnectivityService with our lock held.
2509 NetworkInfo ni = cm.getActiveNetworkInfo();
2510 synchronized (this) {
Dianne Hackborn88c41352016-04-07 15:18:58 -07002511 boolean conn;
2512 if (ni == null) {
2513 conn = false;
2514 } else {
2515 if (connIntent == null) {
2516 conn = ni.isConnected();
2517 } else {
2518 final int networkType =
2519 connIntent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE,
2520 ConnectivityManager.TYPE_NONE);
2521 if (ni.getType() != networkType) {
2522 return;
2523 }
2524 conn = !connIntent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,
2525 false);
2526 }
2527 }
2528 if (conn != mNetworkConnected) {
2529 mNetworkConnected = conn;
2530 if (conn && mLightState == LIGHT_STATE_WAITING_FOR_NETWORK) {
2531 stepLightIdleStateLocked("network");
2532 }
2533 }
2534 }
2535 }
2536
Kweku Adams00e3a372018-09-28 16:57:09 -07002537 @VisibleForTesting
2538 boolean isScreenOn() {
Kweku Adamsb396ccf2018-09-17 16:37:15 -07002539 synchronized (this) {
2540 return mScreenOn;
2541 }
Kweku Adams00e3a372018-09-28 16:57:09 -07002542 }
2543
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -07002544 void updateInteractivityLocked() {
2545 // The interactivity state from the power manager tells us whether the display is
2546 // in a state that we need to keep things running so they will update at a normal
2547 // frequency.
2548 boolean screenOn = mPowerManager.isInteractive();
2549 if (DEBUG) Slog.d(TAG, "updateInteractivityLocked: screenOn=" + screenOn);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002550 if (!screenOn && mScreenOn) {
2551 mScreenOn = false;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002552 if (!mForceIdle) {
2553 becomeInactiveIfAppropriateLocked();
2554 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002555 } else if (screenOn) {
2556 mScreenOn = true;
Amith Yamasani396a10c2018-01-19 10:58:07 -08002557 if (!mForceIdle && (!mScreenLocked || !mConstants.WAIT_FOR_UNLOCK)) {
Denny cy Leec5a7c292019-01-01 17:37:55 +08002558 mActiveReason = ACTIVE_REASON_SCREEN;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002559 becomeActiveLocked("screen", Process.myUid());
2560 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002561 }
2562 }
2563
Kweku Adams00e3a372018-09-28 16:57:09 -07002564 @VisibleForTesting
2565 boolean isCharging() {
Kweku Adamsb396ccf2018-09-17 16:37:15 -07002566 synchronized (this) {
2567 return mCharging;
2568 }
Kweku Adams00e3a372018-09-28 16:57:09 -07002569 }
2570
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002571 void updateChargingLocked(boolean charging) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002572 if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002573 if (!charging && mCharging) {
2574 mCharging = false;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002575 if (!mForceIdle) {
2576 becomeInactiveIfAppropriateLocked();
2577 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002578 } else if (charging) {
2579 mCharging = charging;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002580 if (!mForceIdle) {
Denny cy Leec5a7c292019-01-01 17:37:55 +08002581 mActiveReason = ACTIVE_REASON_CHARGING;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002582 becomeActiveLocked("charging", Process.myUid());
2583 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002584 }
2585 }
2586
Kweku Adamsb396ccf2018-09-17 16:37:15 -07002587 @VisibleForTesting
2588 boolean isQuickDozeEnabled() {
2589 synchronized (this) {
2590 return mQuickDozeActivated;
2591 }
2592 }
2593
2594 /** Updates the quick doze flag and enters deep doze if appropriate. */
2595 @VisibleForTesting
2596 void updateQuickDozeFlagLocked(boolean enabled) {
2597 if (DEBUG) Slog.i(TAG, "updateQuickDozeFlagLocked: enabled=" + enabled);
2598 mQuickDozeActivated = enabled;
2599 if (enabled) {
2600 // If Quick Doze is enabled, see if we should go straight into it.
2601 becomeInactiveIfAppropriateLocked();
2602 }
2603 // Going from Deep Doze to Light Idle (if quick doze becomes disabled) is tricky and
2604 // probably not worth the overhead, so leave in deep doze if that's the case until the
2605 // next natural time to come out of it.
2606 }
2607
Amith Yamasani396a10c2018-01-19 10:58:07 -08002608 void keyguardShowingLocked(boolean showing) {
2609 if (DEBUG) Slog.i(TAG, "keyguardShowing=" + showing);
2610 if (mScreenLocked != showing) {
2611 mScreenLocked = showing;
2612 if (mScreenOn && !mForceIdle && !mScreenLocked) {
Denny cy Leec5a7c292019-01-01 17:37:55 +08002613 mActiveReason = ACTIVE_REASON_UNLOCKED;
Amith Yamasani396a10c2018-01-19 10:58:07 -08002614 becomeActiveLocked("unlocked", Process.myUid());
2615 }
2616 }
2617 }
2618
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002619 void scheduleReportActiveLocked(String activeReason, int activeUid) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002620 Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid, 0, activeReason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002621 mHandler.sendMessage(msg);
2622 }
2623
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002624 void becomeActiveLocked(String activeReason, int activeUid) {
2625 if (DEBUG) Slog.i(TAG, "becomeActiveLocked, reason = " + activeReason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002626 if (mState != STATE_ACTIVE || mLightState != STATE_ACTIVE) {
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002627 EventLogTags.writeDeviceIdle(STATE_ACTIVE, activeReason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002628 EventLogTags.writeDeviceIdleLight(LIGHT_STATE_ACTIVE, activeReason);
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002629 scheduleReportActiveLocked(activeReason, activeUid);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002630 mState = STATE_ACTIVE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002631 mLightState = LIGHT_STATE_ACTIVE;
Adam Lesinski31c05d12015-06-09 17:34:04 -07002632 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002633 mCurIdleBudget = 0;
2634 mMaintenanceStartTime = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002635 resetIdleManagementLocked();
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002636 resetLightIdleManagementLocked();
Amith Yamasaniac6517a2018-04-23 12:19:34 -07002637 addEvent(EVENT_NORMAL, activeReason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002638 }
2639 }
2640
Kweku Adams00e3a372018-09-28 16:57:09 -07002641 /** Must only be used in tests. */
2642 @VisibleForTesting
2643 void setDeepEnabledForTest(boolean enabled) {
Kweku Adams799858b2018-10-08 17:19:08 -07002644 synchronized (this) {
2645 mDeepEnabled = enabled;
2646 }
Kweku Adams00e3a372018-09-28 16:57:09 -07002647 }
2648
2649 /** Must only be used in tests. */
2650 @VisibleForTesting
2651 void setLightEnabledForTest(boolean enabled) {
Kweku Adams799858b2018-10-08 17:19:08 -07002652 synchronized (this) {
2653 mLightEnabled = enabled;
2654 }
Kweku Adams00e3a372018-09-28 16:57:09 -07002655 }
2656
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002657 void becomeInactiveIfAppropriateLocked() {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002658 if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()");
Dianne Hackbornb6843652016-02-22 12:20:13 -08002659 if ((!mScreenOn && !mCharging) || mForceIdle) {
Kweku Adamsb396ccf2018-09-17 16:37:15 -07002660 // Become inactive and determine if we will ultimately go idle.
2661 if (mDeepEnabled) {
2662 if (mQuickDozeActivated) {
2663 if (mState == STATE_QUICK_DOZE_DELAY || mState == STATE_IDLE
2664 || mState == STATE_IDLE_MAINTENANCE) {
2665 // Already "idling". Don't want to restart the process.
2666 // mLightState can't be LIGHT_STATE_ACTIVE if mState is any of these 3
2667 // values, so returning here is safe.
2668 return;
2669 }
2670 if (DEBUG) {
2671 Slog.d(TAG, "Moved from "
2672 + stateToString(mState) + " to STATE_QUICK_DOZE_DELAY");
2673 }
2674 mState = STATE_QUICK_DOZE_DELAY;
2675 // Make sure any motion sensing or locating is stopped.
2676 resetIdleManagementLocked();
2677 // Wait a small amount of time in case something (eg: background service from
2678 // recently closed app) needs to finish running.
2679 scheduleAlarmLocked(mConstants.QUICK_DOZE_DELAY_TIMEOUT, false);
2680 EventLogTags.writeDeviceIdle(mState, "no activity");
2681 } else if (mState == STATE_ACTIVE) {
2682 mState = STATE_INACTIVE;
2683 if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE");
2684 resetIdleManagementLocked();
Denny cy Leec5a7c292019-01-01 17:37:55 +08002685 long delay = mInactiveTimeout;
2686 if (shouldUseIdleTimeoutFactorLocked()) {
2687 delay = (long) (mPreIdleFactor * delay);
2688 }
2689 scheduleAlarmLocked(delay, false);
Kweku Adamsb396ccf2018-09-17 16:37:15 -07002690 EventLogTags.writeDeviceIdle(mState, "no activity");
2691 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002692 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08002693 if (mLightState == LIGHT_STATE_ACTIVE && mLightEnabled) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002694 mLightState = LIGHT_STATE_INACTIVE;
2695 if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE");
2696 resetLightIdleManagementLocked();
Dianne Hackborn953fc942016-03-29 15:36:24 -07002697 scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002698 EventLogTags.writeDeviceIdleLight(mLightState, "no activity");
2699 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002700 }
2701 }
2702
Kweku Adams00e3a372018-09-28 16:57:09 -07002703 private void resetIdleManagementLocked() {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002704 mNextIdlePendingDelay = 0;
2705 mNextIdleDelay = 0;
Dianne Hackborn953fc942016-03-29 15:36:24 -07002706 mNextLightIdleDelay = 0;
Denny cy Leec5a7c292019-01-01 17:37:55 +08002707 mIdleStartTime = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002708 cancelAlarmLocked();
Kevin Gabayan92f15e62016-04-04 17:52:22 -07002709 cancelSensingTimeoutAlarmLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002710 cancelLocatingLocked();
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002711 stopMonitoringMotionLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002712 mAnyMotionDetector.stop();
Robin Lee876b88542018-11-13 17:22:24 +01002713 updateActiveConstraintsLocked();
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002714 }
2715
Kweku Adams00e3a372018-09-28 16:57:09 -07002716 private void resetLightIdleManagementLocked() {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002717 cancelLightAlarmLocked();
2718 }
2719
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002720 void exitForceIdleLocked() {
2721 if (mForceIdle) {
2722 mForceIdle = false;
2723 if (mScreenOn || mCharging) {
Denny cy Leec5a7c292019-01-01 17:37:55 +08002724 mActiveReason = ACTIVE_REASON_FORCED;
Dianne Hackborn88c41352016-04-07 15:18:58 -07002725 becomeActiveLocked("exit-force", Process.myUid());
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002726 }
2727 }
2728 }
2729
Kweku Adamsa457f4e2018-10-03 15:56:06 -07002730 /**
2731 * Must only be used in tests.
2732 *
2733 * This sets the state value directly and thus doesn't trigger any behavioral changes.
2734 */
2735 @VisibleForTesting
2736 void setLightStateForTest(int lightState) {
Kweku Adams799858b2018-10-08 17:19:08 -07002737 synchronized (this) {
2738 mLightState = lightState;
2739 }
Kweku Adamsa457f4e2018-10-03 15:56:06 -07002740 }
2741
Kweku Adams00e3a372018-09-28 16:57:09 -07002742 @VisibleForTesting
2743 int getLightState() {
2744 return mLightState;
2745 }
2746
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002747 void stepLightIdleStateLocked(String reason) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002748 if (mLightState == LIGHT_STATE_OVERRIDE) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08002749 // If we are already in deep device idle mode, then
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002750 // there is nothing left to do for light mode.
2751 return;
2752 }
2753
2754 if (DEBUG) Slog.d(TAG, "stepLightIdleStateLocked: mLightState=" + mLightState);
2755 EventLogTags.writeDeviceIdleLightStep();
2756
2757 switch (mLightState) {
2758 case LIGHT_STATE_INACTIVE:
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002759 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
Dianne Hackborn953fc942016-03-29 15:36:24 -07002760 // Reset the upcoming idle delays.
2761 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002762 mMaintenanceStartTime = 0;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002763 if (!isOpsInactiveLocked()) {
2764 // We have some active ops going on... give them a chance to finish
2765 // before going in to our first idle.
2766 mLightState = LIGHT_STATE_PRE_IDLE;
2767 EventLogTags.writeDeviceIdleLight(mLightState, reason);
2768 scheduleLightAlarmLocked(mConstants.LIGHT_PRE_IDLE_TIMEOUT);
2769 break;
2770 }
2771 // Nothing active, fall through to immediately idle.
2772 case LIGHT_STATE_PRE_IDLE:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002773 case LIGHT_STATE_IDLE_MAINTENANCE:
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002774 if (mMaintenanceStartTime != 0) {
2775 long duration = SystemClock.elapsedRealtime() - mMaintenanceStartTime;
2776 if (duration < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
2777 // We didn't use up all of our minimum budget; add this to the reserve.
2778 mCurIdleBudget += (mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET-duration);
2779 } else {
2780 // We used more than our minimum budget; this comes out of the reserve.
2781 mCurIdleBudget -= (duration-mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET);
2782 }
2783 }
2784 mMaintenanceStartTime = 0;
Dianne Hackborn953fc942016-03-29 15:36:24 -07002785 scheduleLightAlarmLocked(mNextLightIdleDelay);
2786 mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT,
2787 (long)(mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR));
2788 if (mNextLightIdleDelay < mConstants.LIGHT_IDLE_TIMEOUT) {
2789 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT;
2790 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002791 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_STATE_IDLE.");
2792 mLightState = LIGHT_STATE_IDLE;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002793 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Amith Yamasaniac6517a2018-04-23 12:19:34 -07002794 addEvent(EVENT_LIGHT_IDLE, null);
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08002795 mGoingIdleWakeLock.acquire();
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002796 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON_LIGHT);
2797 break;
2798 case LIGHT_STATE_IDLE:
Dianne Hackborn88c41352016-04-07 15:18:58 -07002799 case LIGHT_STATE_WAITING_FOR_NETWORK:
2800 if (mNetworkConnected || mLightState == LIGHT_STATE_WAITING_FOR_NETWORK) {
2801 // We have been idling long enough, now it is time to do some work.
2802 mActiveIdleOpCount = 1;
2803 mActiveIdleWakeLock.acquire();
2804 mMaintenanceStartTime = SystemClock.elapsedRealtime();
2805 if (mCurIdleBudget < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
2806 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
2807 } else if (mCurIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) {
2808 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
2809 }
2810 scheduleLightAlarmLocked(mCurIdleBudget);
2811 if (DEBUG) Slog.d(TAG,
2812 "Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE.");
2813 mLightState = LIGHT_STATE_IDLE_MAINTENANCE;
2814 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Amith Yamasaniac6517a2018-04-23 12:19:34 -07002815 addEvent(EVENT_LIGHT_MAINTENANCE, null);
Dianne Hackborn88c41352016-04-07 15:18:58 -07002816 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
2817 } else {
2818 // We'd like to do maintenance, but currently don't have network
2819 // connectivity... let's try to wait until the network comes back.
2820 // We'll only wait for another full idle period, however, and then give up.
2821 scheduleLightAlarmLocked(mNextLightIdleDelay);
2822 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_WAITING_FOR_NETWORK.");
2823 mLightState = LIGHT_STATE_WAITING_FOR_NETWORK;
2824 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002825 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002826 break;
2827 }
2828 }
2829
Kweku Adams00e3a372018-09-28 16:57:09 -07002830 @VisibleForTesting
2831 int getState() {
2832 return mState;
2833 }
2834
2835 @VisibleForTesting
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002836 void stepIdleStateLocked(String reason) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002837 if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002838 EventLogTags.writeDeviceIdleStep();
2839
2840 final long now = SystemClock.elapsedRealtime();
Adam Lesinski31c05d12015-06-09 17:34:04 -07002841 if ((now+mConstants.MIN_TIME_TO_ALARM) > mAlarmManager.getNextWakeFromIdleTime()) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002842 // Whoops, there is an upcoming alarm. We don't actually want to go idle.
2843 if (mState != STATE_ACTIVE) {
Denny cy Leec5a7c292019-01-01 17:37:55 +08002844 mActiveReason = ACTIVE_REASON_ALARM;
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002845 becomeActiveLocked("alarm", Process.myUid());
Koji Fukui27b33302015-12-16 19:43:01 +09002846 becomeInactiveIfAppropriateLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002847 }
2848 return;
2849 }
2850
Robin Lee876b88542018-11-13 17:22:24 +01002851 if (mNumBlockingConstraints != 0 && !mForceIdle) {
2852 // We have some constraints from other parts of the system server preventing
2853 // us from moving to the next state.
2854 if (DEBUG) {
2855 Slog.i(TAG, "Cannot step idle state. Blocked by: " + mConstraints.values().stream()
2856 .filter(x -> x.active)
2857 .map(x -> x.name)
2858 .collect(Collectors.joining(",")));
2859 }
2860 return;
2861 }
2862
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002863 switch (mState) {
2864 case STATE_INACTIVE:
2865 // We have now been inactive long enough, it is time to start looking
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002866 // for motion and sleep some more while doing so.
2867 startMonitoringMotionLocked();
Denny cy Leec5a7c292019-01-01 17:37:55 +08002868 long delay = mConstants.IDLE_AFTER_INACTIVE_TIMEOUT;
2869 if (shouldUseIdleTimeoutFactorLocked()) {
2870 delay = (long) (mPreIdleFactor * delay);
2871 }
2872 scheduleAlarmLocked(delay, false);
Robin Lee876b88542018-11-13 17:22:24 +01002873 moveToStateLocked(STATE_IDLE_PENDING, reason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002874 break;
2875 case STATE_IDLE_PENDING:
Robin Lee876b88542018-11-13 17:22:24 +01002876 moveToStateLocked(STATE_SENSING, reason);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002877 cancelLocatingLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002878 mLocated = false;
2879 mLastGenericLocation = null;
2880 mLastGpsLocation = null;
Robin Lee876b88542018-11-13 17:22:24 +01002881 updateActiveConstraintsLocked();
Robin Leec4d424c2018-12-07 15:09:13 +01002882
Robin Lee876b88542018-11-13 17:22:24 +01002883 // Wait for open constraints and an accelerometer reading before moving on.
Robin Leec4d424c2018-12-07 15:09:13 +01002884 if (mUseMotionSensor && mAnyMotionDetector.hasSensor()) {
2885 scheduleSensingTimeoutAlarmLocked(mConstants.SENSING_TIMEOUT);
2886 mNotMoving = false;
2887 mAnyMotionDetector.checkForAnyMotion();
2888 break;
Robin Lee876b88542018-11-13 17:22:24 +01002889 } else if (mNumBlockingConstraints != 0) {
2890 cancelAlarmLocked();
2891 break;
Robin Leec4d424c2018-12-07 15:09:13 +01002892 }
2893
2894 mNotMoving = true;
2895 // Otherwise, fall through and check this off the list of requirements.
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002896 case STATE_SENSING:
Kevin Gabayan92f15e62016-04-04 17:52:22 -07002897 cancelSensingTimeoutAlarmLocked();
Robin Lee876b88542018-11-13 17:22:24 +01002898 moveToStateLocked(STATE_LOCATING, reason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002899 scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT, false);
Kweku Adams799858b2018-10-08 17:19:08 -07002900 LocationManager locationManager = mInjector.getLocationManager();
2901 if (locationManager != null
2902 && locationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
2903 locationManager.requestLocationUpdates(mLocationRequest,
Joe LaPenna23d681b2015-08-27 15:12:11 -07002904 mGenericLocationListener, mHandler.getLooper());
2905 mLocating = true;
2906 } else {
2907 mHasNetworkLocation = false;
2908 }
Kweku Adams799858b2018-10-08 17:19:08 -07002909 if (locationManager != null
2910 && locationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
Joe LaPenna23d681b2015-08-27 15:12:11 -07002911 mHasGps = true;
Kweku Adams799858b2018-10-08 17:19:08 -07002912 locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5,
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002913 mGpsLocationListener, mHandler.getLooper());
Joe LaPenna23d681b2015-08-27 15:12:11 -07002914 mLocating = true;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002915 } else {
Joe LaPenna23d681b2015-08-27 15:12:11 -07002916 mHasGps = false;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002917 }
Joe LaPenna23d681b2015-08-27 15:12:11 -07002918 // If we have a location provider, we're all set, the listeners will move state
2919 // forward.
2920 if (mLocating) {
2921 break;
2922 }
2923
2924 // Otherwise, we have to move from locating into idle maintenance.
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002925 case STATE_LOCATING:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002926 cancelAlarmLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002927 cancelLocatingLocked();
2928 mAnyMotionDetector.stop();
Dianne Hackborn953fc942016-03-29 15:36:24 -07002929
Kweku Adamsb396ccf2018-09-17 16:37:15 -07002930 // Intentional fallthrough -- time to go into IDLE state.
2931 case STATE_QUICK_DOZE_DELAY:
2932 // Reset the upcoming idle delays.
2933 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
2934 mNextIdleDelay = mConstants.IDLE_TIMEOUT;
2935
2936 // Everything is in place to go into IDLE state.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002937 case STATE_IDLE_MAINTENANCE:
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002938 scheduleAlarmLocked(mNextIdleDelay, true);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002939 if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay +
2940 " ms.");
Adam Lesinski31c05d12015-06-09 17:34:04 -07002941 mNextIdleDelay = (long)(mNextIdleDelay * mConstants.IDLE_FACTOR);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002942 if (DEBUG) Slog.d(TAG, "Setting mNextIdleDelay = " + mNextIdleDelay);
Denny cy Leec5a7c292019-01-01 17:37:55 +08002943 mIdleStartTime = SystemClock.elapsedRealtime();
Adam Lesinski31c05d12015-06-09 17:34:04 -07002944 mNextIdleDelay = Math.min(mNextIdleDelay, mConstants.MAX_IDLE_TIMEOUT);
Dianne Hackborn953fc942016-03-29 15:36:24 -07002945 if (mNextIdleDelay < mConstants.IDLE_TIMEOUT) {
2946 mNextIdleDelay = mConstants.IDLE_TIMEOUT;
2947 }
Robin Lee876b88542018-11-13 17:22:24 +01002948 moveToStateLocked(STATE_IDLE, reason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002949 if (mLightState != LIGHT_STATE_OVERRIDE) {
2950 mLightState = LIGHT_STATE_OVERRIDE;
2951 cancelLightAlarmLocked();
2952 }
Amith Yamasaniac6517a2018-04-23 12:19:34 -07002953 addEvent(EVENT_DEEP_IDLE, null);
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08002954 mGoingIdleWakeLock.acquire();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002955 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON);
2956 break;
2957 case STATE_IDLE:
2958 // We have been idling long enough, now it is time to do some work.
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002959 mActiveIdleOpCount = 1;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002960 mActiveIdleWakeLock.acquire();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002961 scheduleAlarmLocked(mNextIdlePendingDelay, false);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002962 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE to STATE_IDLE_MAINTENANCE. " +
2963 "Next alarm in " + mNextIdlePendingDelay + " ms.");
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002964 mMaintenanceStartTime = SystemClock.elapsedRealtime();
Adam Lesinski31c05d12015-06-09 17:34:04 -07002965 mNextIdlePendingDelay = Math.min(mConstants.MAX_IDLE_PENDING_TIMEOUT,
2966 (long)(mNextIdlePendingDelay * mConstants.IDLE_PENDING_FACTOR));
Dianne Hackborn953fc942016-03-29 15:36:24 -07002967 if (mNextIdlePendingDelay < mConstants.IDLE_PENDING_TIMEOUT) {
2968 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
2969 }
Robin Lee876b88542018-11-13 17:22:24 +01002970 moveToStateLocked(STATE_IDLE_MAINTENANCE, reason);
Amith Yamasaniac6517a2018-04-23 12:19:34 -07002971 addEvent(EVENT_DEEP_MAINTENANCE, null);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002972 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
2973 break;
2974 }
2975 }
2976
Robin Lee876b88542018-11-13 17:22:24 +01002977 private void moveToStateLocked(int state, String reason) {
2978 final int oldState = mState;
2979 mState = state;
2980 if (DEBUG) {
2981 Slog.d(TAG, String.format("Moved from STATE_%s to STATE_%s.",
2982 stateToString(oldState), stateToString(mState)));
2983 }
2984 EventLogTags.writeDeviceIdle(mState, reason);
2985 updateActiveConstraintsLocked();
2986 }
2987
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002988 void incActiveIdleOps() {
2989 synchronized (this) {
2990 mActiveIdleOpCount++;
2991 }
2992 }
2993
2994 void decActiveIdleOps() {
2995 synchronized (this) {
2996 mActiveIdleOpCount--;
2997 if (mActiveIdleOpCount <= 0) {
2998 exitMaintenanceEarlyIfNeededLocked();
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002999 mActiveIdleWakeLock.release();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003000 }
3001 }
3002 }
3003
Kweku Adamsa457f4e2018-10-03 15:56:06 -07003004 /** Must only be used in tests. */
3005 @VisibleForTesting
3006 void setActiveIdleOpsForTest(int count) {
Kweku Adams799858b2018-10-08 17:19:08 -07003007 synchronized (this) {
3008 mActiveIdleOpCount = count;
3009 }
Kweku Adamsa457f4e2018-10-03 15:56:06 -07003010 }
3011
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003012 void setJobsActive(boolean active) {
3013 synchronized (this) {
3014 mJobsActive = active;
Yao Chenca5edbb2016-01-13 14:44:36 -08003015 reportMaintenanceActivityIfNeededLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003016 if (!active) {
3017 exitMaintenanceEarlyIfNeededLocked();
3018 }
3019 }
3020 }
3021
3022 void setAlarmsActive(boolean active) {
3023 synchronized (this) {
3024 mAlarmsActive = active;
3025 if (!active) {
3026 exitMaintenanceEarlyIfNeededLocked();
3027 }
3028 }
3029 }
3030
Yao Chenca5edbb2016-01-13 14:44:36 -08003031 boolean registerMaintenanceActivityListener(IMaintenanceActivityListener listener) {
3032 synchronized (this) {
3033 mMaintenanceActivityListeners.register(listener);
3034 return mReportedMaintenanceActivity;
3035 }
3036 }
3037
3038 void unregisterMaintenanceActivityListener(IMaintenanceActivityListener listener) {
3039 synchronized (this) {
3040 mMaintenanceActivityListeners.unregister(listener);
3041 }
3042 }
3043
Denny cy Leec5a7c292019-01-01 17:37:55 +08003044 @VisibleForTesting
3045 int setPreIdleTimeoutMode(int mode) {
3046 return setPreIdleTimeoutFactor(getPreIdleTimeoutByMode(mode));
3047 }
3048
3049 @VisibleForTesting
3050 float getPreIdleTimeoutByMode(int mode) {
3051 switch (mode) {
3052 case PowerManager.PRE_IDLE_TIMEOUT_MODE_LONG: {
3053 return mConstants.PRE_IDLE_FACTOR_LONG;
3054 }
3055 case PowerManager.PRE_IDLE_TIMEOUT_MODE_SHORT: {
3056 return mConstants.PRE_IDLE_FACTOR_SHORT;
3057 }
3058 case PowerManager.PRE_IDLE_TIMEOUT_MODE_NORMAL: {
3059 return 1.0f;
3060 }
3061 default: {
3062 Slog.w(TAG, "Invalid time out factor mode: " + mode);
3063 return 1.0f;
3064 }
3065 }
3066 }
3067
3068 @VisibleForTesting
3069 float getPreIdleTimeoutFactor() {
3070 return mPreIdleFactor;
3071 }
3072
3073 @VisibleForTesting
3074 int setPreIdleTimeoutFactor(float ratio) {
3075 if (!mDeepEnabled) {
3076 if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: Deep Idle disable");
3077 return SET_IDLE_FACTOR_RESULT_NOT_SUPPORT;
3078 } else if (ratio <= MIN_PRE_IDLE_FACTOR_CHANGE) {
3079 if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: Invalid input");
3080 return SET_IDLE_FACTOR_RESULT_INVALID;
3081 } else if (Math.abs(ratio - mPreIdleFactor) < MIN_PRE_IDLE_FACTOR_CHANGE) {
3082 if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: New factor same as previous factor");
3083 return SET_IDLE_FACTOR_RESULT_IGNORED;
3084 }
3085 synchronized (this) {
3086 mLastPreIdleFactor = mPreIdleFactor;
3087 mPreIdleFactor = ratio;
3088 }
3089 if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: " + ratio);
3090 postUpdatePreIdleFactor();
3091 return SET_IDLE_FACTOR_RESULT_OK;
3092 }
3093
3094 @VisibleForTesting
3095 void resetPreIdleTimeoutMode() {
3096 synchronized (this) {
3097 mLastPreIdleFactor = mPreIdleFactor;
3098 mPreIdleFactor = 1.0f;
3099 }
3100 if (DEBUG) Slog.d(TAG, "resetPreIdleTimeoutMode to 1.0");
3101 postResetPreIdleTimeoutFactor();
3102 }
3103
3104 private void postUpdatePreIdleFactor() {
3105 mHandler.sendEmptyMessage(MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR);
3106 }
3107
3108 private void postResetPreIdleTimeoutFactor() {
3109 mHandler.sendEmptyMessage(MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR);
3110 }
3111
3112 @VisibleForTesting
3113 void updatePreIdleFactor() {
3114 synchronized (this) {
3115 if (!shouldUseIdleTimeoutFactorLocked()) {
3116 return;
3117 }
3118 if (mState == STATE_INACTIVE || mState == STATE_IDLE_PENDING) {
3119 if (mNextAlarmTime == 0) {
3120 return;
3121 }
3122 long delay = mNextAlarmTime - SystemClock.elapsedRealtime();
3123 if (delay < MIN_STATE_STEP_ALARM_CHANGE) {
3124 return;
3125 }
3126 long newDelay = (long) (delay / mLastPreIdleFactor * mPreIdleFactor);
3127 if (Math.abs(delay - newDelay) < MIN_STATE_STEP_ALARM_CHANGE) {
3128 return;
3129 }
3130 scheduleAlarmLocked(newDelay, false);
3131 }
3132 }
3133 }
3134
3135 @VisibleForTesting
3136 void maybeDoImmediateMaintenance() {
3137 synchronized (this) {
3138 if (mState == STATE_IDLE) {
3139 long duration = SystemClock.elapsedRealtime() - mIdleStartTime;
3140 /* Let's trgger a immediate maintenance,
3141 * if it has been idle for a long time */
3142 if (duration > mConstants.IDLE_TIMEOUT) {
3143 scheduleAlarmLocked(0, false);
3144 }
3145 }
3146 }
3147 }
3148
3149 private boolean shouldUseIdleTimeoutFactorLocked() {
3150 // exclude ACTIVE_REASON_MOTION, for exclude device in pocket case
3151 if (mActiveReason == ACTIVE_REASON_MOTION) {
3152 return false;
3153 }
3154 return true;
3155 }
3156
3157 /** Must only be used in tests. */
3158 @VisibleForTesting
3159 void setIdleStartTimeForTest(long idleStartTime) {
3160 synchronized (this) {
3161 mIdleStartTime = idleStartTime;
3162 }
3163 }
3164
Yao Chenca5edbb2016-01-13 14:44:36 -08003165 void reportMaintenanceActivityIfNeededLocked() {
Dianne Hackborn7ab40252016-06-15 17:30:24 -07003166 boolean active = mJobsActive;
Yao Chenca5edbb2016-01-13 14:44:36 -08003167 if (active == mReportedMaintenanceActivity) {
3168 return;
3169 }
3170 mReportedMaintenanceActivity = active;
3171 Message msg = mHandler.obtainMessage(MSG_REPORT_MAINTENANCE_ACTIVITY,
3172 mReportedMaintenanceActivity ? 1 : 0, 0);
3173 mHandler.sendMessage(msg);
3174 }
3175
Denny cy Leec5a7c292019-01-01 17:37:55 +08003176 @VisibleForTesting
3177 long getNextAlarmTime() {
3178 return mNextAlarmTime;
3179 }
3180
Dianne Hackborn945c9c92016-03-30 14:55:00 -07003181 boolean isOpsInactiveLocked() {
Dianne Hackborn7ab40252016-06-15 17:30:24 -07003182 return mActiveIdleOpCount <= 0 && !mJobsActive && !mAlarmsActive;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07003183 }
3184
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003185 void exitMaintenanceEarlyIfNeededLocked() {
Dianne Hackborn945c9c92016-03-30 14:55:00 -07003186 if (mState == STATE_IDLE_MAINTENANCE || mLightState == LIGHT_STATE_IDLE_MAINTENANCE
3187 || mLightState == LIGHT_STATE_PRE_IDLE) {
3188 if (isOpsInactiveLocked()) {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003189 final long now = SystemClock.elapsedRealtime();
3190 if (DEBUG) {
3191 StringBuilder sb = new StringBuilder();
3192 sb.append("Exit: start=");
3193 TimeUtils.formatDuration(mMaintenanceStartTime, sb);
3194 sb.append(" now=");
3195 TimeUtils.formatDuration(now, sb);
3196 Slog.d(TAG, sb.toString());
3197 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003198 if (mState == STATE_IDLE_MAINTENANCE) {
Dianne Hackborn945c9c92016-03-30 14:55:00 -07003199 stepIdleStateLocked("s:early");
3200 } else if (mLightState == LIGHT_STATE_PRE_IDLE) {
3201 stepLightIdleStateLocked("s:predone");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003202 } else {
Dianne Hackborn945c9c92016-03-30 14:55:00 -07003203 stepLightIdleStateLocked("s:early");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003204 }
3205 }
3206 }
3207 }
3208
Nick Vaccaro20feaea2015-09-17 17:22:44 -07003209 void motionLocked() {
3210 if (DEBUG) Slog.d(TAG, "motionLocked()");
3211 // The motion sensor will have been disabled at this point
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003212 handleMotionDetectedLocked(mConstants.MOTION_INACTIVE_TIMEOUT, "motion");
3213 }
3214
3215 void handleMotionDetectedLocked(long timeout, String type) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003216 // The device is not yet active, so we want to go back to the pending idle
Nick Vaccaro20feaea2015-09-17 17:22:44 -07003217 // state to wait again for no motion. Note that we only monitor for motion
3218 // after moving out of the inactive state, so no need to worry about that.
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003219 boolean becomeInactive = false;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003220 if (mState != STATE_ACTIVE) {
Amith Yamasani4cb42572018-04-27 10:02:57 -07003221 // Motion shouldn't affect light state, if it's already in doze-light or maintenance
3222 boolean lightIdle = mLightState == LIGHT_STATE_IDLE
3223 || mLightState == LIGHT_STATE_WAITING_FOR_NETWORK
3224 || mLightState == LIGHT_STATE_IDLE_MAINTENANCE;
3225 if (!lightIdle) {
3226 // Only switch to active state if we're not in either idle state
3227 scheduleReportActiveLocked(type, Process.myUid());
3228 addEvent(EVENT_NORMAL, type);
3229 }
Denny cy Leec5a7c292019-01-01 17:37:55 +08003230 mActiveReason = ACTIVE_REASON_MOTION;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003231 mState = STATE_ACTIVE;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003232 mInactiveTimeout = timeout;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08003233 mCurIdleBudget = 0;
3234 mMaintenanceStartTime = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003235 EventLogTags.writeDeviceIdle(mState, type);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003236 becomeInactive = true;
Robin Lee876b88542018-11-13 17:22:24 +01003237 updateActiveConstraintsLocked();
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003238 }
3239 if (mLightState == LIGHT_STATE_OVERRIDE) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08003240 // We went out of light idle mode because we had started deep idle mode... let's
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003241 // now go back and reset things so we resume light idling if appropriate.
Amith Yamasani4cb42572018-04-27 10:02:57 -07003242 mLightState = LIGHT_STATE_ACTIVE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003243 EventLogTags.writeDeviceIdleLight(mLightState, type);
3244 becomeInactive = true;
3245 }
3246 if (becomeInactive) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003247 becomeInactiveIfAppropriateLocked();
3248 }
3249 }
3250
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003251 void receivedGenericLocationLocked(Location location) {
3252 if (mState != STATE_LOCATING) {
3253 cancelLocatingLocked();
3254 return;
3255 }
3256 if (DEBUG) Slog.d(TAG, "Generic location: " + location);
3257 mLastGenericLocation = new Location(location);
Joe LaPenna23d681b2015-08-27 15:12:11 -07003258 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHasGps) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003259 return;
3260 }
3261 mLocated = true;
3262 if (mNotMoving) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003263 stepIdleStateLocked("s:location");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003264 }
3265 }
3266
3267 void receivedGpsLocationLocked(Location location) {
3268 if (mState != STATE_LOCATING) {
3269 cancelLocatingLocked();
3270 return;
3271 }
3272 if (DEBUG) Slog.d(TAG, "GPS location: " + location);
3273 mLastGpsLocation = new Location(location);
3274 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY) {
3275 return;
3276 }
3277 mLocated = true;
3278 if (mNotMoving) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003279 stepIdleStateLocked("s:gps");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003280 }
3281 }
3282
Nick Vaccaro20feaea2015-09-17 17:22:44 -07003283 void startMonitoringMotionLocked() {
3284 if (DEBUG) Slog.d(TAG, "startMonitoringMotionLocked()");
3285 if (mMotionSensor != null && !mMotionListener.active) {
3286 mMotionListener.registerLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003287 }
3288 }
3289
Nick Vaccaro20feaea2015-09-17 17:22:44 -07003290 void stopMonitoringMotionLocked() {
3291 if (DEBUG) Slog.d(TAG, "stopMonitoringMotionLocked()");
3292 if (mMotionSensor != null && mMotionListener.active) {
3293 mMotionListener.unregisterLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003294 }
3295 }
3296
3297 void cancelAlarmLocked() {
3298 if (mNextAlarmTime != 0) {
3299 mNextAlarmTime = 0;
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003300 mAlarmManager.cancel(mDeepAlarmListener);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003301 }
3302 }
3303
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003304 void cancelLightAlarmLocked() {
3305 if (mNextLightAlarmTime != 0) {
3306 mNextLightAlarmTime = 0;
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003307 mAlarmManager.cancel(mLightAlarmListener);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003308 }
3309 }
3310
3311 void cancelLocatingLocked() {
3312 if (mLocating) {
Kweku Adams799858b2018-10-08 17:19:08 -07003313 LocationManager locationManager = mInjector.getLocationManager();
3314 locationManager.removeUpdates(mGenericLocationListener);
3315 locationManager.removeUpdates(mGpsLocationListener);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003316 mLocating = false;
3317 }
Kevin Gabayan89ecf822015-05-18 12:10:07 -07003318 }
3319
Kevin Gabayan92f15e62016-04-04 17:52:22 -07003320 void cancelSensingTimeoutAlarmLocked() {
3321 if (mNextSensingTimeoutAlarmTime != 0) {
3322 mNextSensingTimeoutAlarmTime = 0;
3323 mAlarmManager.cancel(mSensingTimeoutAlarmListener);
3324 }
3325 }
3326
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003327 void scheduleAlarmLocked(long delay, boolean idleUntil) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07003328 if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")");
Robin Leec4d424c2018-12-07 15:09:13 +01003329
3330 if (mUseMotionSensor && mMotionSensor == null
3331 && mState != STATE_QUICK_DOZE_DELAY
3332 && mState != STATE_IDLE
3333 && mState != STATE_IDLE_MAINTENANCE) {
3334 // 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 -07003335 // alarms, because we can't determine if the device is not moving. This effectively
Joe LaPenna23d681b2015-08-27 15:12:11 -07003336 // turns off normal execution of device idling, although it is still possible to
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003337 // manually poke it by pretending like the alarm is going off.
Kweku Adamsb396ccf2018-09-17 16:37:15 -07003338 // STATE_QUICK_DOZE_DELAY skips the motion sensing so if the state is past the motion
3339 // sensing stage (ie, is QUICK_DOZE_DELAY, IDLE, or IDLE_MAINTENANCE), then idling
3340 // can continue until the user interacts with the device.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003341 return;
3342 }
3343 mNextAlarmTime = SystemClock.elapsedRealtime() + delay;
3344 if (idleUntil) {
3345 mAlarmManager.setIdleUntil(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003346 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003347 } else {
3348 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003349 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003350 }
3351 }
3352
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003353 void scheduleLightAlarmLocked(long delay) {
3354 if (DEBUG) Slog.d(TAG, "scheduleLightAlarmLocked(" + delay + ")");
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003355 mNextLightAlarmTime = SystemClock.elapsedRealtime() + delay;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003356 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003357 mNextLightAlarmTime, "DeviceIdleController.light", mLightAlarmListener, mHandler);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07003358 }
3359
Kevin Gabayan92f15e62016-04-04 17:52:22 -07003360 void scheduleSensingTimeoutAlarmLocked(long delay) {
3361 if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")");
3362 mNextSensingTimeoutAlarmTime = SystemClock.elapsedRealtime() + delay;
3363 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextSensingTimeoutAlarmTime,
3364 "DeviceIdleController.sensing", mSensingTimeoutAlarmListener, mHandler);
3365 }
3366
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003367 private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps,
3368 ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds) {
3369 outAppIds.clear();
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08003370 if (systemApps != null) {
3371 for (int i = 0; i < systemApps.size(); i++) {
3372 outAppIds.put(systemApps.valueAt(i), true);
3373 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003374 }
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08003375 if (userApps != null) {
3376 for (int i = 0; i < userApps.size(); i++) {
3377 outAppIds.put(userApps.valueAt(i), true);
3378 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003379 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003380 int size = outAppIds.size();
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003381 int[] appids = new int[size];
3382 for (int i = 0; i < size; i++) {
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003383 appids[i] = outAppIds.keyAt(i);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003384 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003385 return appids;
3386 }
3387
3388 private void updateWhitelistAppIdsLocked() {
3389 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(mPowerSaveWhitelistAppsExceptIdle,
3390 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistExceptIdleAppIds);
3391 mPowerSaveWhitelistAllAppIdArray = buildAppIdArray(mPowerSaveWhitelistApps,
3392 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistAllAppIds);
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08003393 mPowerSaveWhitelistUserAppIdArray = buildAppIdArray(null,
3394 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistUserAppIds);
Dianne Hackborn85e35642017-01-12 15:10:57 -08003395 if (mLocalActivityManager != null) {
Makoto Onukiaf8ff4f2018-06-04 14:44:19 -07003396 mLocalActivityManager.setDeviceIdleWhitelist(
3397 mPowerSaveWhitelistAllAppIdArray, mPowerSaveWhitelistExceptIdleAppIdArray);
Dianne Hackborn85e35642017-01-12 15:10:57 -08003398 }
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003399 if (mLocalPowerManager != null) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003400 if (DEBUG) {
3401 Slog.d(TAG, "Setting wakelock whitelist to "
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07003402 + Arrays.toString(mPowerSaveWhitelistAllAppIdArray));
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003403 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07003404 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003405 }
Suprabh Shukla5bf49812018-05-24 18:38:50 -07003406 passWhiteListsToForceAppStandbyTrackerLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003407 }
3408
Dianne Hackborn85e35642017-01-12 15:10:57 -08003409 private void updateTempWhitelistAppIdsLocked(int appId, boolean adding) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003410 final int size = mTempWhitelistAppIdEndTimes.size();
3411 if (mTempWhitelistAppIdArray.length != size) {
3412 mTempWhitelistAppIdArray = new int[size];
3413 }
3414 for (int i = 0; i < size; i++) {
3415 mTempWhitelistAppIdArray[i] = mTempWhitelistAppIdEndTimes.keyAt(i);
3416 }
Dianne Hackborn85e35642017-01-12 15:10:57 -08003417 if (mLocalActivityManager != null) {
3418 if (DEBUG) {
3419 Slog.d(TAG, "Setting activity manager temp whitelist to "
3420 + Arrays.toString(mTempWhitelistAppIdArray));
3421 }
3422 mLocalActivityManager.updateDeviceIdleTempWhitelist(mTempWhitelistAppIdArray, appId,
3423 adding);
3424 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003425 if (mLocalPowerManager != null) {
3426 if (DEBUG) {
3427 Slog.d(TAG, "Setting wakelock temp whitelist to "
3428 + Arrays.toString(mTempWhitelistAppIdArray));
3429 }
3430 mLocalPowerManager.setDeviceIdleTempWhitelist(mTempWhitelistAppIdArray);
3431 }
Suprabh Shukla5bf49812018-05-24 18:38:50 -07003432 passWhiteListsToForceAppStandbyTrackerLocked();
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003433 }
3434
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003435 private void reportPowerSaveWhitelistChangedLocked() {
3436 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
3437 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Xiaohui Chene4de5a02015-09-22 15:33:31 -07003438 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003439 }
3440
3441 private void reportTempWhitelistChangedLocked() {
3442 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED);
3443 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Xiaohui Chene4de5a02015-09-22 15:33:31 -07003444 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003445 }
3446
Suprabh Shukla5bf49812018-05-24 18:38:50 -07003447 private void passWhiteListsToForceAppStandbyTrackerLocked() {
Makoto Onukie4918212018-02-06 11:30:15 -08003448 mAppStateTracker.setPowerSaveWhitelistAppIds(
Makoto Onuki71755c92018-01-16 14:15:44 -08003449 mPowerSaveWhitelistExceptIdleAppIdArray,
Suprabh Shukla5bf49812018-05-24 18:38:50 -07003450 mPowerSaveWhitelistUserAppIdArray,
Makoto Onuki2206af32017-11-21 16:25:35 -08003451 mTempWhitelistAppIdArray);
3452 }
3453
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003454 void readConfigFileLocked() {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003455 if (DEBUG) Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003456 mPowerSaveWhitelistUserApps.clear();
3457 FileInputStream stream;
3458 try {
3459 stream = mConfigFile.openRead();
3460 } catch (FileNotFoundException e) {
3461 return;
3462 }
3463 try {
3464 XmlPullParser parser = Xml.newPullParser();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01003465 parser.setInput(stream, StandardCharsets.UTF_8.name());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003466 readConfigFileLocked(parser);
3467 } catch (XmlPullParserException e) {
3468 } finally {
3469 try {
3470 stream.close();
3471 } catch (IOException e) {
3472 }
3473 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003474 }
3475
3476 private void readConfigFileLocked(XmlPullParser parser) {
3477 final PackageManager pm = getContext().getPackageManager();
3478
3479 try {
3480 int type;
3481 while ((type = parser.next()) != XmlPullParser.START_TAG
3482 && type != XmlPullParser.END_DOCUMENT) {
3483 ;
3484 }
3485
3486 if (type != XmlPullParser.START_TAG) {
3487 throw new IllegalStateException("no start tag found");
3488 }
3489
3490 int outerDepth = parser.getDepth();
3491 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3492 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3493 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3494 continue;
3495 }
3496
3497 String tagName = parser.getName();
Suprabh Shukla08105642017-09-26 14:45:30 -07003498 switch (tagName) {
3499 case "wl":
3500 String name = parser.getAttributeValue(null, "n");
3501 if (name != null) {
3502 try {
3503 ApplicationInfo ai = pm.getApplicationInfo(name,
3504 PackageManager.MATCH_ANY_USER);
3505 mPowerSaveWhitelistUserApps.put(ai.packageName,
3506 UserHandle.getAppId(ai.uid));
3507 } catch (PackageManager.NameNotFoundException e) {
3508 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003509 }
Suprabh Shukla08105642017-09-26 14:45:30 -07003510 break;
3511 case "un-wl":
3512 final String packageName = parser.getAttributeValue(null, "n");
3513 if (mPowerSaveWhitelistApps.containsKey(packageName)) {
3514 mRemovedFromSystemWhitelistApps.put(packageName,
3515 mPowerSaveWhitelistApps.remove(packageName));
3516 }
3517 break;
3518 default:
3519 Slog.w(TAG, "Unknown element under <config>: "
3520 + parser.getName());
3521 XmlUtils.skipCurrentTag(parser);
3522 break;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003523 }
3524 }
3525
3526 } catch (IllegalStateException e) {
3527 Slog.w(TAG, "Failed parsing config " + e);
3528 } catch (NullPointerException e) {
3529 Slog.w(TAG, "Failed parsing config " + e);
3530 } catch (NumberFormatException e) {
3531 Slog.w(TAG, "Failed parsing config " + e);
3532 } catch (XmlPullParserException e) {
3533 Slog.w(TAG, "Failed parsing config " + e);
3534 } catch (IOException e) {
3535 Slog.w(TAG, "Failed parsing config " + e);
3536 } catch (IndexOutOfBoundsException e) {
3537 Slog.w(TAG, "Failed parsing config " + e);
3538 }
3539 }
3540
3541 void writeConfigFileLocked() {
3542 mHandler.removeMessages(MSG_WRITE_CONFIG);
3543 mHandler.sendEmptyMessageDelayed(MSG_WRITE_CONFIG, 5000);
3544 }
3545
3546 void handleWriteConfigFile() {
3547 final ByteArrayOutputStream memStream = new ByteArrayOutputStream();
3548
3549 try {
3550 synchronized (this) {
3551 XmlSerializer out = new FastXmlSerializer();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01003552 out.setOutput(memStream, StandardCharsets.UTF_8.name());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003553 writeConfigFileLocked(out);
3554 }
3555 } catch (IOException e) {
3556 }
3557
3558 synchronized (mConfigFile) {
3559 FileOutputStream stream = null;
3560 try {
3561 stream = mConfigFile.startWrite();
3562 memStream.writeTo(stream);
3563 stream.flush();
3564 FileUtils.sync(stream);
3565 stream.close();
3566 mConfigFile.finishWrite(stream);
3567 } catch (IOException e) {
3568 Slog.w(TAG, "Error writing config file", e);
3569 mConfigFile.failWrite(stream);
3570 }
3571 }
3572 }
3573
3574 void writeConfigFileLocked(XmlSerializer out) throws IOException {
3575 out.startDocument(null, true);
3576 out.startTag(null, "config");
3577 for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) {
3578 String name = mPowerSaveWhitelistUserApps.keyAt(i);
3579 out.startTag(null, "wl");
3580 out.attribute(null, "n", name);
3581 out.endTag(null, "wl");
3582 }
Suprabh Shukla08105642017-09-26 14:45:30 -07003583 for (int i = 0; i < mRemovedFromSystemWhitelistApps.size(); i++) {
3584 out.startTag(null, "un-wl");
3585 out.attribute(null, "n", mRemovedFromSystemWhitelistApps.keyAt(i));
3586 out.endTag(null, "un-wl");
3587 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003588 out.endTag(null, "config");
3589 out.endDocument();
3590 }
3591
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003592 static void dumpHelp(PrintWriter pw) {
3593 pw.println("Device idle controller (deviceidle) commands:");
3594 pw.println(" help");
3595 pw.println(" Print this help text.");
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003596 pw.println(" step [light|deep]");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003597 pw.println(" Immediately step to next state, without waiting for alarm.");
Dianne Hackborn88c41352016-04-07 15:18:58 -07003598 pw.println(" force-idle [light|deep]");
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003599 pw.println(" Force directly into idle mode, regardless of other device state.");
Dianne Hackborn88c41352016-04-07 15:18:58 -07003600 pw.println(" force-inactive");
3601 pw.println(" Force to be inactive, ready to freely step idle states.");
3602 pw.println(" unforce");
3603 pw.println(" Resume normal functioning after force-idle or force-inactive.");
3604 pw.println(" get [light|deep|force|screen|charging|network]");
3605 pw.println(" Retrieve the current given state.");
Dianne Hackbornb6843652016-02-22 12:20:13 -08003606 pw.println(" disable [light|deep|all]");
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003607 pw.println(" Completely disable device idle mode.");
Dianne Hackbornb6843652016-02-22 12:20:13 -08003608 pw.println(" enable [light|deep|all]");
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003609 pw.println(" Re-enable device idle mode after it had previously been disabled.");
Dianne Hackbornb6843652016-02-22 12:20:13 -08003610 pw.println(" enabled [light|deep|all]");
Dianne Hackborn92617032015-06-19 15:32:19 -07003611 pw.println(" Print 1 if device idle mode is currently enabled, else 0.");
Dianne Hackborn1b139682015-07-06 15:13:37 -07003612 pw.println(" whitelist");
3613 pw.println(" Print currently whitelisted apps.");
Dianne Hackborn92617032015-06-19 15:32:19 -07003614 pw.println(" whitelist [package ...]");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003615 pw.println(" Add (prefix with +) or remove (prefix with -) packages.");
Suprabh Shukla08105642017-09-26 14:45:30 -07003616 pw.println(" sys-whitelist [package ...|reset]");
3617 pw.println(" Prefix the package with '-' to remove it from the system whitelist or '+'"
3618 + " to put it back in the system whitelist.");
3619 pw.println(" Note that only packages that were"
3620 + " earlier removed from the system whitelist can be added back.");
3621 pw.println(" reset will reset the whitelist to the original state");
3622 pw.println(" Prints the system whitelist if no arguments are specified");
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07003623 pw.println(" except-idle-whitelist [package ...|reset]");
3624 pw.println(" Prefix the package with '+' to add it to whitelist or "
3625 + "'=' to check if it is already whitelisted");
3626 pw.println(" [reset] will reset the whitelist to it's original state");
3627 pw.println(" Note that unlike <whitelist> cmd, "
3628 + "changes made using this won't be persisted across boots");
Felipe Lemea1b79bf2016-05-24 13:06:54 -07003629 pw.println(" tempwhitelist");
3630 pw.println(" Print packages that are temporarily whitelisted.");
Sudheer Shanka326b3112017-11-27 14:40:57 -08003631 pw.println(" tempwhitelist [-u USER] [-d DURATION] [-r] [package]");
3632 pw.println(" Temporarily place package in whitelist for DURATION milliseconds.");
Dianne Hackborn85e35642017-01-12 15:10:57 -08003633 pw.println(" If no DURATION is specified, 10 seconds is used");
Sudheer Shanka326b3112017-11-27 14:40:57 -08003634 pw.println(" If [-r] option is used, then the package is removed from temp whitelist "
3635 + "and any [-d] is ignored");
Amith Yamasani4cb42572018-04-27 10:02:57 -07003636 pw.println(" motion");
3637 pw.println(" Simulate a motion event to bring the device out of deep doze");
Denny cy Leec5a7c292019-01-01 17:37:55 +08003638 pw.println(" pre-idle-factor [0|1|2]");
3639 pw.println(" Set a new factor to idle time before step to idle"
3640 + "(inactive_to and idle_after_inactive_to)");
3641 pw.println(" reset-pre-idle-factor");
3642 pw.println(" Reset factor to idle time to default");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003643 }
3644
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003645 class Shell extends ShellCommand {
3646 int userId = UserHandle.USER_SYSTEM;
3647
3648 @Override
3649 public int onCommand(String cmd) {
3650 return onShellCommand(this, cmd);
3651 }
3652
3653 @Override
3654 public void onHelp() {
3655 PrintWriter pw = getOutPrintWriter();
3656 dumpHelp(pw);
3657 }
3658 }
3659
3660 int onShellCommand(Shell shell, String cmd) {
3661 PrintWriter pw = shell.getOutPrintWriter();
3662 if ("step".equals(cmd)) {
3663 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3664 null);
3665 synchronized (this) {
3666 long token = Binder.clearCallingIdentity();
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003667 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003668 try {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003669 if (arg == null || "deep".equals(arg)) {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003670 stepIdleStateLocked("s:shell");
3671 pw.print("Stepped to deep: ");
3672 pw.println(stateToString(mState));
3673 } else if ("light".equals(arg)) {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003674 stepLightIdleStateLocked("s:shell");
3675 pw.print("Stepped to light: "); pw.println(lightStateToString(mLightState));
3676 } else {
3677 pw.println("Unknown idle mode: " + arg);
3678 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003679 } finally {
3680 Binder.restoreCallingIdentity(token);
3681 }
3682 }
3683 } else if ("force-idle".equals(cmd)) {
3684 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3685 null);
3686 synchronized (this) {
3687 long token = Binder.clearCallingIdentity();
Dianne Hackborn88c41352016-04-07 15:18:58 -07003688 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003689 try {
Dianne Hackborn88c41352016-04-07 15:18:58 -07003690 if (arg == null || "deep".equals(arg)) {
3691 if (!mDeepEnabled) {
3692 pw.println("Unable to go deep idle; not enabled");
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003693 return -1;
3694 }
Dianne Hackborn88c41352016-04-07 15:18:58 -07003695 mForceIdle = true;
3696 becomeInactiveIfAppropriateLocked();
3697 int curState = mState;
3698 while (curState != STATE_IDLE) {
3699 stepIdleStateLocked("s:shell");
3700 if (curState == mState) {
3701 pw.print("Unable to go deep idle; stopped at ");
3702 pw.println(stateToString(mState));
3703 exitForceIdleLocked();
3704 return -1;
3705 }
3706 curState = mState;
3707 }
3708 pw.println("Now forced in to deep idle mode");
3709 } else if ("light".equals(arg)) {
3710 mForceIdle = true;
3711 becomeInactiveIfAppropriateLocked();
3712 int curLightState = mLightState;
3713 while (curLightState != LIGHT_STATE_IDLE) {
Tej Singh93cf3e32017-12-07 13:05:38 -08003714 stepLightIdleStateLocked("s:shell");
Dianne Hackborn88c41352016-04-07 15:18:58 -07003715 if (curLightState == mLightState) {
3716 pw.print("Unable to go light idle; stopped at ");
3717 pw.println(lightStateToString(mLightState));
3718 exitForceIdleLocked();
3719 return -1;
3720 }
3721 curLightState = mLightState;
3722 }
3723 pw.println("Now forced in to light idle mode");
3724 } else {
3725 pw.println("Unknown idle mode: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003726 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003727 } finally {
3728 Binder.restoreCallingIdentity(token);
3729 }
3730 }
Dianne Hackborn88c41352016-04-07 15:18:58 -07003731 } else if ("force-inactive".equals(cmd)) {
3732 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3733 null);
3734 synchronized (this) {
3735 long token = Binder.clearCallingIdentity();
3736 try {
3737 mForceIdle = true;
3738 becomeInactiveIfAppropriateLocked();
3739 pw.print("Light state: ");
3740 pw.print(lightStateToString(mLightState));
3741 pw.print(", deep state: ");
3742 pw.println(stateToString(mState));
3743 } finally {
3744 Binder.restoreCallingIdentity(token);
3745 }
3746 }
3747 } else if ("unforce".equals(cmd)) {
3748 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3749 null);
3750 synchronized (this) {
3751 long token = Binder.clearCallingIdentity();
3752 try {
3753 exitForceIdleLocked();
3754 pw.print("Light state: ");
3755 pw.print(lightStateToString(mLightState));
3756 pw.print(", deep state: ");
3757 pw.println(stateToString(mState));
3758 } finally {
3759 Binder.restoreCallingIdentity(token);
3760 }
3761 }
3762 } else if ("get".equals(cmd)) {
3763 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3764 null);
3765 synchronized (this) {
3766 String arg = shell.getNextArg();
3767 if (arg != null) {
3768 long token = Binder.clearCallingIdentity();
3769 try {
3770 switch (arg) {
3771 case "light": pw.println(lightStateToString(mLightState)); break;
3772 case "deep": pw.println(stateToString(mState)); break;
3773 case "force": pw.println(mForceIdle); break;
Kweku Adamsb396ccf2018-09-17 16:37:15 -07003774 case "quick": pw.println(mQuickDozeActivated); break;
Dianne Hackborn88c41352016-04-07 15:18:58 -07003775 case "screen": pw.println(mScreenOn); break;
3776 case "charging": pw.println(mCharging); break;
3777 case "network": pw.println(mNetworkConnected); break;
3778 default: pw.println("Unknown get option: " + arg); break;
3779 }
3780 } finally {
3781 Binder.restoreCallingIdentity(token);
3782 }
3783 } else {
3784 pw.println("Argument required");
3785 }
3786 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003787 } else if ("disable".equals(cmd)) {
3788 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3789 null);
3790 synchronized (this) {
3791 long token = Binder.clearCallingIdentity();
Dianne Hackbornb6843652016-02-22 12:20:13 -08003792 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003793 try {
Dianne Hackbornb6843652016-02-22 12:20:13 -08003794 boolean becomeActive = false;
3795 boolean valid = false;
3796 if (arg == null || "deep".equals(arg) || "all".equals(arg)) {
3797 valid = true;
3798 if (mDeepEnabled) {
3799 mDeepEnabled = false;
3800 becomeActive = true;
3801 pw.println("Deep idle mode disabled");
3802 }
3803 }
3804 if (arg == null || "light".equals(arg) || "all".equals(arg)) {
3805 valid = true;
3806 if (mLightEnabled) {
3807 mLightEnabled = false;
3808 becomeActive = true;
3809 pw.println("Light idle mode disabled");
3810 }
3811 }
3812 if (becomeActive) {
Denny cy Leec5a7c292019-01-01 17:37:55 +08003813 mActiveReason = ACTIVE_REASON_FORCED;
Dianne Hackbornb6843652016-02-22 12:20:13 -08003814 becomeActiveLocked((arg == null ? "all" : arg) + "-disabled",
3815 Process.myUid());
3816 }
3817 if (!valid) {
3818 pw.println("Unknown idle mode: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003819 }
3820 } finally {
3821 Binder.restoreCallingIdentity(token);
3822 }
3823 }
3824 } else if ("enable".equals(cmd)) {
3825 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3826 null);
3827 synchronized (this) {
3828 long token = Binder.clearCallingIdentity();
Dianne Hackbornb6843652016-02-22 12:20:13 -08003829 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003830 try {
Dianne Hackbornb6843652016-02-22 12:20:13 -08003831 boolean becomeInactive = false;
3832 boolean valid = false;
3833 if (arg == null || "deep".equals(arg) || "all".equals(arg)) {
3834 valid = true;
3835 if (!mDeepEnabled) {
3836 mDeepEnabled = true;
3837 becomeInactive = true;
3838 pw.println("Deep idle mode enabled");
3839 }
3840 }
3841 if (arg == null || "light".equals(arg) || "all".equals(arg)) {
3842 valid = true;
3843 if (!mLightEnabled) {
3844 mLightEnabled = true;
3845 becomeInactive = true;
3846 pw.println("Light idle mode enable");
3847 }
3848 }
3849 if (becomeInactive) {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003850 becomeInactiveIfAppropriateLocked();
Dianne Hackbornb6843652016-02-22 12:20:13 -08003851 }
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 ("enabled".equals(cmd)) {
3860 synchronized (this) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08003861 String arg = shell.getNextArg();
3862 if (arg == null || "all".equals(arg)) {
3863 pw.println(mDeepEnabled && mLightEnabled ? "1" : 0);
3864 } else if ("deep".equals(arg)) {
3865 pw.println(mDeepEnabled ? "1" : 0);
3866 } else if ("light".equals(arg)) {
3867 pw.println(mLightEnabled ? "1" : 0);
3868 } else {
3869 pw.println("Unknown idle mode: " + arg);
3870 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003871 }
3872 } else if ("whitelist".equals(cmd)) {
Dianne Hackborneb909e32016-09-29 14:35:15 -07003873 String arg = shell.getNextArg();
3874 if (arg != null) {
3875 getContext().enforceCallingOrSelfPermission(
3876 android.Manifest.permission.DEVICE_POWER, null);
3877 long token = Binder.clearCallingIdentity();
3878 try {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003879 do {
3880 if (arg.length() < 1 || (arg.charAt(0) != '-'
Felipe Lemef8a46232016-02-10 13:51:54 -08003881 && arg.charAt(0) != '+' && arg.charAt(0) != '=')) {
3882 pw.println("Package must be prefixed with +, -, or =: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003883 return -1;
3884 }
3885 char op = arg.charAt(0);
3886 String pkg = arg.substring(1);
3887 if (op == '+') {
3888 if (addPowerSaveWhitelistAppInternal(pkg)) {
3889 pw.println("Added: " + pkg);
3890 } else {
3891 pw.println("Unknown package: " + pkg);
3892 }
Felipe Lemef8a46232016-02-10 13:51:54 -08003893 } else if (op == '-') {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003894 if (removePowerSaveWhitelistAppInternal(pkg)) {
3895 pw.println("Removed: " + pkg);
3896 }
Felipe Lemef8a46232016-02-10 13:51:54 -08003897 } else {
3898 pw.println(getPowerSaveWhitelistAppInternal(pkg));
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003899 }
3900 } while ((arg=shell.getNextArg()) != null);
Dianne Hackborneb909e32016-09-29 14:35:15 -07003901 } finally {
3902 Binder.restoreCallingIdentity(token);
3903 }
3904 } else {
3905 synchronized (this) {
3906 for (int j=0; j<mPowerSaveWhitelistAppsExceptIdle.size(); j++) {
3907 pw.print("system-excidle,");
3908 pw.print(mPowerSaveWhitelistAppsExceptIdle.keyAt(j));
3909 pw.print(",");
3910 pw.println(mPowerSaveWhitelistAppsExceptIdle.valueAt(j));
3911 }
3912 for (int j=0; j<mPowerSaveWhitelistApps.size(); j++) {
3913 pw.print("system,");
3914 pw.print(mPowerSaveWhitelistApps.keyAt(j));
3915 pw.print(",");
3916 pw.println(mPowerSaveWhitelistApps.valueAt(j));
3917 }
3918 for (int j=0; j<mPowerSaveWhitelistUserApps.size(); j++) {
3919 pw.print("user,");
3920 pw.print(mPowerSaveWhitelistUserApps.keyAt(j));
3921 pw.print(",");
3922 pw.println(mPowerSaveWhitelistUserApps.valueAt(j));
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003923 }
3924 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003925 }
3926 } else if ("tempwhitelist".equals(cmd)) {
Dianne Hackborn85e35642017-01-12 15:10:57 -08003927 long duration = 10000;
Sudheer Shanka326b3112017-11-27 14:40:57 -08003928 boolean removePkg = false;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003929 String opt;
3930 while ((opt=shell.getNextOption()) != null) {
3931 if ("-u".equals(opt)) {
3932 opt = shell.getNextArg();
3933 if (opt == null) {
3934 pw.println("-u requires a user number");
3935 return -1;
3936 }
3937 shell.userId = Integer.parseInt(opt);
Dianne Hackborn85e35642017-01-12 15:10:57 -08003938 } else if ("-d".equals(opt)) {
3939 opt = shell.getNextArg();
3940 if (opt == null) {
3941 pw.println("-d requires a duration");
3942 return -1;
3943 }
3944 duration = Long.parseLong(opt);
Sudheer Shanka326b3112017-11-27 14:40:57 -08003945 } else if ("-r".equals(opt)) {
3946 removePkg = true;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003947 }
3948 }
3949 String arg = shell.getNextArg();
3950 if (arg != null) {
3951 try {
Sudheer Shanka326b3112017-11-27 14:40:57 -08003952 if (removePkg) {
3953 removePowerSaveTempWhitelistAppChecked(arg, shell.userId);
3954 } else {
3955 addPowerSaveTempWhitelistAppChecked(arg, duration, shell.userId, "shell");
3956 }
Christopher Tateec3a9f32017-03-21 17:43:47 -07003957 } catch (Exception e) {
3958 pw.println("Failed: " + e);
3959 return -1;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003960 }
Sudheer Shanka326b3112017-11-27 14:40:57 -08003961 } else if (removePkg) {
3962 pw.println("[-r] requires a package name");
3963 return -1;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003964 } else {
Felipe Lemea1b79bf2016-05-24 13:06:54 -07003965 dumpTempWhitelistSchedule(pw, false);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003966 }
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07003967 } else if ("except-idle-whitelist".equals(cmd)) {
3968 getContext().enforceCallingOrSelfPermission(
3969 android.Manifest.permission.DEVICE_POWER, null);
3970 final long token = Binder.clearCallingIdentity();
3971 try {
3972 String arg = shell.getNextArg();
3973 if (arg == null) {
3974 pw.println("No arguments given");
3975 return -1;
3976 } else if ("reset".equals(arg)) {
3977 resetPowerSaveWhitelistExceptIdleInternal();
3978 } else {
3979 do {
3980 if (arg.length() < 1 || (arg.charAt(0) != '-'
3981 && arg.charAt(0) != '+' && arg.charAt(0) != '=')) {
3982 pw.println("Package must be prefixed with +, -, or =: " + arg);
3983 return -1;
3984 }
3985 char op = arg.charAt(0);
3986 String pkg = arg.substring(1);
3987 if (op == '+') {
3988 if (addPowerSaveWhitelistExceptIdleInternal(pkg)) {
3989 pw.println("Added: " + pkg);
3990 } else {
3991 pw.println("Unknown package: " + pkg);
3992 }
3993 } else if (op == '=') {
3994 pw.println(getPowerSaveWhitelistExceptIdleInternal(pkg));
3995 } else {
3996 pw.println("Unknown argument: " + arg);
3997 return -1;
3998 }
3999 } while ((arg = shell.getNextArg()) != null);
4000 }
4001 } finally {
4002 Binder.restoreCallingIdentity(token);
4003 }
Suprabh Shukla08105642017-09-26 14:45:30 -07004004 } else if ("sys-whitelist".equals(cmd)) {
4005 String arg = shell.getNextArg();
4006 if (arg != null) {
4007 getContext().enforceCallingOrSelfPermission(
4008 android.Manifest.permission.DEVICE_POWER, null);
4009 final long token = Binder.clearCallingIdentity();
4010 try {
4011 if ("reset".equals(arg)) {
4012 resetSystemPowerWhitelistInternal();
4013 } else {
4014 do {
4015 if (arg.length() < 1
4016 || (arg.charAt(0) != '-' && arg.charAt(0) != '+')) {
4017 pw.println("Package must be prefixed with + or - " + arg);
4018 return -1;
4019 }
4020 final char op = arg.charAt(0);
4021 final String pkg = arg.substring(1);
4022 switch (op) {
4023 case '+':
4024 if (restoreSystemPowerWhitelistAppInternal(pkg)) {
4025 pw.println("Restored " + pkg);
4026 }
4027 break;
4028 case '-':
4029 if (removeSystemPowerWhitelistAppInternal(pkg)) {
4030 pw.println("Removed " + pkg);
4031 }
4032 break;
4033 }
4034 } while ((arg = shell.getNextArg()) != null);
4035 }
4036 } finally {
4037 Binder.restoreCallingIdentity(token);
4038 }
4039 } else {
4040 synchronized (this) {
Amith Yamasani4cb42572018-04-27 10:02:57 -07004041 for (int j = 0; j < mPowerSaveWhitelistApps.size(); j++) {
Suprabh Shukla08105642017-09-26 14:45:30 -07004042 pw.print(mPowerSaveWhitelistApps.keyAt(j));
4043 pw.print(",");
4044 pw.println(mPowerSaveWhitelistApps.valueAt(j));
4045 }
4046 }
4047 }
Amith Yamasani4cb42572018-04-27 10:02:57 -07004048 } else if ("motion".equals(cmd)) {
4049 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
4050 null);
4051 synchronized (this) {
4052 long token = Binder.clearCallingIdentity();
4053 try {
4054 motionLocked();
4055 pw.print("Light state: ");
4056 pw.print(lightStateToString(mLightState));
4057 pw.print(", deep state: ");
4058 pw.println(stateToString(mState));
4059 } finally {
4060 Binder.restoreCallingIdentity(token);
4061 }
4062 }
Denny cy Leec5a7c292019-01-01 17:37:55 +08004063 } else if ("pre-idle-factor".equals(cmd)) {
4064 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
4065 null);
4066 synchronized (this) {
4067 long token = Binder.clearCallingIdentity();
4068 int ret = SET_IDLE_FACTOR_RESULT_UNINIT;
4069 try {
4070 String arg = shell.getNextArg();
4071 boolean valid = false;
4072 int mode = 0;
4073 if (arg != null) {
4074 mode = Integer.parseInt(arg);
4075 ret = setPreIdleTimeoutMode(mode);
4076 if (ret == SET_IDLE_FACTOR_RESULT_OK) {
4077 pw.println("pre-idle-factor: " + mode);
4078 valid = true;
4079 } else if (ret == SET_IDLE_FACTOR_RESULT_NOT_SUPPORT) {
4080 valid = true;
4081 pw.println("Deep idle not supported");
4082 } else if (ret == SET_IDLE_FACTOR_RESULT_IGNORED) {
4083 valid = true;
4084 pw.println("Idle timeout factor not changed");
4085 }
4086 }
4087 if (!valid) {
4088 pw.println("Unknown idle timeout factor: " + arg
4089 + ",(error code: " + ret + ")");
4090 }
4091 } catch (NumberFormatException e) {
4092 pw.println("Unknown idle timeout factor"
4093 + ",(error code: " + ret + ")");
4094 } finally {
4095 Binder.restoreCallingIdentity(token);
4096 }
4097 }
4098 } else if ("reset-pre-idle-factor".equals(cmd)) {
4099 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
4100 null);
4101 synchronized (this) {
4102 long token = Binder.clearCallingIdentity();
4103 try {
4104 resetPreIdleTimeoutMode();
4105 } finally {
4106 Binder.restoreCallingIdentity(token);
4107 }
4108 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07004109 } else {
4110 return shell.handleDefaultCommands(cmd);
4111 }
4112 return 0;
4113 }
4114
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004115 void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06004116 if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004117
4118 if (args != null) {
Xiaohui Chen7c696362015-09-16 09:56:14 -07004119 int userId = UserHandle.USER_SYSTEM;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004120 for (int i=0; i<args.length; i++) {
4121 String arg = args[i];
4122 if ("-h".equals(arg)) {
4123 dumpHelp(pw);
4124 return;
Amith Yamasaniaf575b92015-05-29 15:35:26 -07004125 } else if ("-u".equals(arg)) {
4126 i++;
4127 if (i < args.length) {
4128 arg = args[i];
4129 userId = Integer.parseInt(arg);
4130 }
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07004131 } else if ("-a".equals(arg)) {
4132 // Ignore, we always dump all.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004133 } else if (arg.length() > 0 && arg.charAt(0) == '-'){
4134 pw.println("Unknown option: " + arg);
4135 return;
4136 } else {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07004137 Shell shell = new Shell();
4138 shell.userId = userId;
4139 String[] newArgs = new String[args.length-i];
4140 System.arraycopy(args, i, newArgs, 0, args.length-i);
Dianne Hackborn354736e2016-08-22 17:00:05 -07004141 shell.exec(mBinderService, null, fd, null, newArgs, null,
4142 new ResultReceiver(null));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004143 return;
4144 }
4145 }
4146 }
4147
4148 synchronized (this) {
Dianne Hackborna750a632015-06-16 17:18:23 -07004149 mConstants.dump(pw);
4150
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08004151 if (mEventCmds[0] != EVENT_NULL) {
4152 pw.println(" Idling history:");
4153 long now = SystemClock.elapsedRealtime();
4154 for (int i=EVENT_BUFFER_SIZE-1; i>=0; i--) {
4155 int cmd = mEventCmds[i];
4156 if (cmd == EVENT_NULL) {
4157 continue;
4158 }
4159 String label;
4160 switch (mEventCmds[i]) {
4161 case EVENT_NORMAL: label = " normal"; break;
4162 case EVENT_LIGHT_IDLE: label = " light-idle"; break;
4163 case EVENT_LIGHT_MAINTENANCE: label = "light-maint"; break;
Dianne Hackbornb6843652016-02-22 12:20:13 -08004164 case EVENT_DEEP_IDLE: label = " deep-idle"; break;
4165 case EVENT_DEEP_MAINTENANCE: label = " deep-maint"; break;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08004166 default: label = " ??"; break;
4167 }
4168 pw.print(" ");
4169 pw.print(label);
4170 pw.print(": ");
Amith Yamasaniac6517a2018-04-23 12:19:34 -07004171 TimeUtils.formatDuration(mEventTimes[i], now, pw);
4172 if (mEventReasons[i] != null) {
4173 pw.print(" (");
4174 pw.print(mEventReasons[i]);
4175 pw.print(")");
4176 }
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08004177 pw.println();
Amith Yamasaniac6517a2018-04-23 12:19:34 -07004178
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08004179 }
4180 }
4181
Dianne Hackborn4a503b12015-08-06 22:19:06 -07004182 int size = mPowerSaveWhitelistAppsExceptIdle.size();
4183 if (size > 0) {
4184 pw.println(" Whitelist (except idle) system apps:");
4185 for (int i = 0; i < size; i++) {
4186 pw.print(" ");
4187 pw.println(mPowerSaveWhitelistAppsExceptIdle.keyAt(i));
4188 }
4189 }
4190 size = mPowerSaveWhitelistApps.size();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004191 if (size > 0) {
4192 pw.println(" Whitelist system apps:");
4193 for (int i = 0; i < size; i++) {
4194 pw.print(" ");
4195 pw.println(mPowerSaveWhitelistApps.keyAt(i));
4196 }
4197 }
Suprabh Shukla08105642017-09-26 14:45:30 -07004198 size = mRemovedFromSystemWhitelistApps.size();
4199 if (size > 0) {
4200 pw.println(" Removed from whitelist system apps:");
4201 for (int i = 0; i < size; i++) {
4202 pw.print(" ");
4203 pw.println(mRemovedFromSystemWhitelistApps.keyAt(i));
4204 }
4205 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004206 size = mPowerSaveWhitelistUserApps.size();
4207 if (size > 0) {
4208 pw.println(" Whitelist user apps:");
4209 for (int i = 0; i < size; i++) {
4210 pw.print(" ");
4211 pw.println(mPowerSaveWhitelistUserApps.keyAt(i));
4212 }
4213 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07004214 size = mPowerSaveWhitelistExceptIdleAppIds.size();
4215 if (size > 0) {
4216 pw.println(" Whitelist (except idle) all app ids:");
4217 for (int i = 0; i < size; i++) {
4218 pw.print(" ");
4219 pw.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
4220 pw.println();
4221 }
4222 }
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08004223 size = mPowerSaveWhitelistUserAppIds.size();
4224 if (size > 0) {
4225 pw.println(" Whitelist user app ids:");
4226 for (int i = 0; i < size; i++) {
4227 pw.print(" ");
4228 pw.print(mPowerSaveWhitelistUserAppIds.keyAt(i));
4229 pw.println();
4230 }
4231 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07004232 size = mPowerSaveWhitelistAllAppIds.size();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004233 if (size > 0) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07004234 pw.println(" Whitelist all app ids:");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004235 for (int i = 0; i < size; i++) {
Dianne Hackborna750a632015-06-16 17:18:23 -07004236 pw.print(" ");
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07004237 pw.print(mPowerSaveWhitelistAllAppIds.keyAt(i));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004238 pw.println();
4239 }
4240 }
Felipe Lemea1b79bf2016-05-24 13:06:54 -07004241 dumpTempWhitelistSchedule(pw, true);
4242
Dianne Hackborna750a632015-06-16 17:18:23 -07004243 size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0;
4244 if (size > 0) {
4245 pw.println(" Temp whitelist app ids:");
4246 for (int i = 0; i < size; i++) {
4247 pw.print(" ");
4248 pw.print(mTempWhitelistAppIdArray[i]);
4249 pw.println();
4250 }
4251 }
Adam Lesinski31c05d12015-06-09 17:34:04 -07004252
Dianne Hackbornb6843652016-02-22 12:20:13 -08004253 pw.print(" mLightEnabled="); pw.print(mLightEnabled);
Felipe Lemea1b79bf2016-05-24 13:06:54 -07004254 pw.print(" mDeepEnabled="); pw.println(mDeepEnabled);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07004255 pw.print(" mForceIdle="); pw.println(mForceIdle);
Robin Leec4d424c2018-12-07 15:09:13 +01004256 pw.print(" mUseMotionSensor="); pw.print(mUseMotionSensor);
4257 if (mUseMotionSensor) {
4258 pw.print(" mMotionSensor="); pw.println(mMotionSensor);
4259 } else {
4260 pw.println();
4261 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004262 pw.print(" mScreenOn="); pw.println(mScreenOn);
Amith Yamasani396a10c2018-01-19 10:58:07 -08004263 pw.print(" mScreenLocked="); pw.println(mScreenLocked);
Dianne Hackborn88c41352016-04-07 15:18:58 -07004264 pw.print(" mNetworkConnected="); pw.println(mNetworkConnected);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004265 pw.print(" mCharging="); pw.println(mCharging);
Robin Lee876b88542018-11-13 17:22:24 +01004266 if (mConstraints.size() != 0) {
4267 pw.println(" mConstraints={");
4268 for (int i = 0; i < mConstraints.size(); i++) {
4269 final DeviceIdleConstraintTracker tracker = mConstraints.valueAt(i);
4270 pw.print(" \""); pw.print(tracker.name); pw.print("\"=");
4271 if (tracker.minState == mState) {
4272 pw.println(tracker.active);
4273 } else {
4274 pw.print("ignored <mMinState="); pw.print(stateToString(tracker.minState));
4275 pw.println(">");
4276 }
4277 }
4278 pw.println(" }");
4279 }
Robin Leec4d424c2018-12-07 15:09:13 +01004280 if (mUseMotionSensor) {
Robin Lee876b88542018-11-13 17:22:24 +01004281 pw.print(" mMotionActive="); pw.println(mMotionListener.active);
Robin Leec4d424c2018-12-07 15:09:13 +01004282 pw.print(" mNotMoving="); pw.println(mNotMoving);
4283 }
Joe LaPenna23d681b2015-08-27 15:12:11 -07004284 pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHasGps=");
4285 pw.print(mHasGps); pw.print(" mHasNetwork=");
4286 pw.print(mHasNetworkLocation); pw.print(" mLocated="); pw.println(mLocated);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07004287 if (mLastGenericLocation != null) {
4288 pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation);
4289 }
4290 if (mLastGpsLocation != null) {
4291 pw.print(" mLastGpsLocation="); pw.println(mLastGpsLocation);
4292 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004293 pw.print(" mState="); pw.print(stateToString(mState));
4294 pw.print(" mLightState=");
4295 pw.println(lightStateToString(mLightState));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004296 pw.print(" mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw);
4297 pw.println();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08004298 if (mActiveIdleOpCount != 0) {
4299 pw.print(" mActiveIdleOpCount="); pw.println(mActiveIdleOpCount);
4300 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004301 if (mNextAlarmTime != 0) {
4302 pw.print(" mNextAlarmTime=");
4303 TimeUtils.formatDuration(mNextAlarmTime, SystemClock.elapsedRealtime(), pw);
4304 pw.println();
4305 }
4306 if (mNextIdlePendingDelay != 0) {
4307 pw.print(" mNextIdlePendingDelay=");
4308 TimeUtils.formatDuration(mNextIdlePendingDelay, pw);
4309 pw.println();
4310 }
4311 if (mNextIdleDelay != 0) {
4312 pw.print(" mNextIdleDelay=");
4313 TimeUtils.formatDuration(mNextIdleDelay, pw);
4314 pw.println();
4315 }
Dianne Hackborn953fc942016-03-29 15:36:24 -07004316 if (mNextLightIdleDelay != 0) {
4317 pw.print(" mNextIdleDelay=");
4318 TimeUtils.formatDuration(mNextLightIdleDelay, pw);
4319 pw.println();
4320 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004321 if (mNextLightAlarmTime != 0) {
4322 pw.print(" mNextLightAlarmTime=");
4323 TimeUtils.formatDuration(mNextLightAlarmTime, SystemClock.elapsedRealtime(), pw);
4324 pw.println();
4325 }
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08004326 if (mCurIdleBudget != 0) {
4327 pw.print(" mCurIdleBudget=");
4328 TimeUtils.formatDuration(mCurIdleBudget, pw);
4329 pw.println();
4330 }
4331 if (mMaintenanceStartTime != 0) {
4332 pw.print(" mMaintenanceStartTime=");
4333 TimeUtils.formatDuration(mMaintenanceStartTime, SystemClock.elapsedRealtime(), pw);
4334 pw.println();
4335 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08004336 if (mJobsActive) {
4337 pw.print(" mJobsActive="); pw.println(mJobsActive);
4338 }
4339 if (mAlarmsActive) {
4340 pw.print(" mAlarmsActive="); pw.println(mAlarmsActive);
4341 }
Denny cy Leec5a7c292019-01-01 17:37:55 +08004342 if (Math.abs(mPreIdleFactor - 1.0f) > MIN_PRE_IDLE_FACTOR_CHANGE) {
4343 pw.print(" mPreIdleFactor="); pw.println(mPreIdleFactor);
4344 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004345 }
4346 }
Felipe Lemea1b79bf2016-05-24 13:06:54 -07004347
4348 void dumpTempWhitelistSchedule(PrintWriter pw, boolean printTitle) {
4349 final int size = mTempWhitelistAppIdEndTimes.size();
4350 if (size > 0) {
4351 String prefix = "";
4352 if (printTitle) {
4353 pw.println(" Temp whitelist schedule:");
4354 prefix = " ";
4355 }
4356 final long timeNow = SystemClock.elapsedRealtime();
4357 for (int i = 0; i < size; i++) {
4358 pw.print(prefix);
4359 pw.print("UID=");
4360 pw.print(mTempWhitelistAppIdEndTimes.keyAt(i));
4361 pw.print(": ");
4362 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.valueAt(i);
4363 TimeUtils.formatDuration(entry.first.value, timeNow, pw);
4364 pw.print(" - ");
4365 pw.println(entry.second);
4366 }
4367 }
4368 }
4369 }