blob: 121a830f05f5ebab9528368cb2a3b0c995f6c6ac [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
Kweku Adams00e3a372018-09-28 16:57:09 -0700344 @VisibleForTesting
345 static String stateToString(int state) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700346 switch (state) {
347 case STATE_ACTIVE: return "ACTIVE";
348 case STATE_INACTIVE: return "INACTIVE";
349 case STATE_IDLE_PENDING: return "IDLE_PENDING";
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700350 case STATE_SENSING: return "SENSING";
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700351 case STATE_LOCATING: return "LOCATING";
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700352 case STATE_IDLE: return "IDLE";
353 case STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE";
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700354 case STATE_QUICK_DOZE_DELAY: return "QUICK_DOZE_DELAY";
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700355 default: return Integer.toString(state);
356 }
357 }
358
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700359 /** Device is currently active. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700360 @VisibleForTesting
361 static final int LIGHT_STATE_ACTIVE = 0;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700362 /** Device is inactive (screen off) and we are waiting to for the first light idle. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700363 @VisibleForTesting
364 static final int LIGHT_STATE_INACTIVE = 1;
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700365 /** Device is about to go idle for the first time, wait for current work to complete. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700366 @VisibleForTesting
367 static final int LIGHT_STATE_PRE_IDLE = 3;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700368 /** Device is in the light idle state, trying to stay asleep as much as possible. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700369 @VisibleForTesting
370 static final int LIGHT_STATE_IDLE = 4;
Dianne Hackborn88c41352016-04-07 15:18:58 -0700371 /** Device is in the light idle state, we want to go in to idle maintenance but are
372 * waiting for network connectivity before doing so. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700373 @VisibleForTesting
374 static final int LIGHT_STATE_WAITING_FOR_NETWORK = 5;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700375 /** Device is in the light idle state, but temporarily out of idle to do regular maintenance. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700376 @VisibleForTesting
377 static final int LIGHT_STATE_IDLE_MAINTENANCE = 6;
Dianne Hackbornb6843652016-02-22 12:20:13 -0800378 /** Device light idle state is overriden, now applying deep doze state. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700379 @VisibleForTesting
380 static final int LIGHT_STATE_OVERRIDE = 7;
381
382 @VisibleForTesting
383 static String lightStateToString(int state) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700384 switch (state) {
385 case LIGHT_STATE_ACTIVE: return "ACTIVE";
386 case LIGHT_STATE_INACTIVE: return "INACTIVE";
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700387 case LIGHT_STATE_PRE_IDLE: return "PRE_IDLE";
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700388 case LIGHT_STATE_IDLE: return "IDLE";
Dianne Hackborn88c41352016-04-07 15:18:58 -0700389 case LIGHT_STATE_WAITING_FOR_NETWORK: return "WAITING_FOR_NETWORK";
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700390 case LIGHT_STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE";
391 case LIGHT_STATE_OVERRIDE: return "OVERRIDE";
392 default: return Integer.toString(state);
393 }
394 }
395
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700396 private int mState;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700397 private int mLightState;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700398
399 private long mInactiveTimeout;
400 private long mNextAlarmTime;
401 private long mNextIdlePendingDelay;
402 private long mNextIdleDelay;
Dianne Hackborn953fc942016-03-29 15:36:24 -0700403 private long mNextLightIdleDelay;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700404 private long mNextLightAlarmTime;
Kevin Gabayan92f15e62016-04-04 17:52:22 -0700405 private long mNextSensingTimeoutAlarmTime;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800406 private long mCurIdleBudget;
407 private long mMaintenanceStartTime;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700408
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800409 private int mActiveIdleOpCount;
Joe Onorato8f0e9ced2016-12-08 17:48:49 -0800410 private PowerManager.WakeLock mActiveIdleWakeLock; // held when there are operations in progress
411 private PowerManager.WakeLock mGoingIdleWakeLock; // held when we are going idle so hardware
412 // (especially NetworkPolicyManager) can shut
413 // down.
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800414 private boolean mJobsActive;
415 private boolean mAlarmsActive;
Yao Chenca5edbb2016-01-13 14:44:36 -0800416 private boolean mReportedMaintenanceActivity;
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800417
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700418 public final AtomicFile mConfigFile;
419
Yao Chenca5edbb2016-01-13 14:44:36 -0800420 private final RemoteCallbackList<IMaintenanceActivityListener> mMaintenanceActivityListeners =
421 new RemoteCallbackList<IMaintenanceActivityListener>();
422
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700423 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700424 * Package names the system has white-listed to opt out of power save restrictions,
425 * except for device idle mode.
426 */
427 private final ArrayMap<String, Integer> mPowerSaveWhitelistAppsExceptIdle = new ArrayMap<>();
428
429 /**
Sudheer Shanka3f4d7702017-04-28 17:38:03 -0700430 * Package names the user has white-listed using commandline option to opt out of
431 * power save restrictions, except for device idle mode.
432 */
433 private final ArraySet<String> mPowerSaveWhitelistUserAppsExceptIdle = new ArraySet<>();
434
435 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700436 * Package names the system has white-listed to opt out of power save restrictions for
437 * all modes.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700438 */
439 private final ArrayMap<String, Integer> mPowerSaveWhitelistApps = new ArrayMap<>();
440
441 /**
442 * Package names the user has white-listed to opt out of power save restrictions.
443 */
444 private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>();
445
446 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700447 * App IDs of built-in system apps that have been white-listed except for idle modes.
448 */
449 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIdsExceptIdle
450 = new SparseBooleanArray();
451
452 /**
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700453 * App IDs of built-in system apps that have been white-listed.
454 */
455 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray();
456
457 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700458 * App IDs that have been white-listed to opt out of power save restrictions, except
459 * for device idle modes.
460 */
461 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
462
463 /**
464 * Current app IDs that are in the complete power save white list, but shouldn't be
465 * excluded from idle modes. This array can be shared with others because it will not be
466 * modified once set.
467 */
468 private int[] mPowerSaveWhitelistExceptIdleAppIdArray = new int[0];
469
470 /**
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700471 * App IDs that have been white-listed to opt out of power save restrictions.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700472 */
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700473 private final SparseBooleanArray mPowerSaveWhitelistAllAppIds = new SparseBooleanArray();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700474
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700475 /**
476 * Current app IDs that are in the complete power save white list. This array can
477 * be shared with others because it will not be modified once set.
478 */
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700479 private int[] mPowerSaveWhitelistAllAppIdArray = new int[0];
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700480
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700481 /**
Dianne Hackborn262ae5c2016-02-10 16:28:29 -0800482 * App IDs that have been white-listed by the user to opt out of power save restrictions.
483 */
484 private final SparseBooleanArray mPowerSaveWhitelistUserAppIds = new SparseBooleanArray();
485
486 /**
487 * Current app IDs that are in the user power save white list. This array can
488 * be shared with others because it will not be modified once set.
489 */
490 private int[] mPowerSaveWhitelistUserAppIdArray = new int[0];
491
492 /**
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700493 * List of end times for UIDs that are temporarily marked as being allowed to access
494 * the network and acquire wakelocks. Times are in milliseconds.
495 */
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700496 private final SparseArray<Pair<MutableLong, String>> mTempWhitelistAppIdEndTimes
497 = new SparseArray<>();
498
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -0700499 private NetworkPolicyManagerInternal mNetworkPolicyManagerInternal;
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700500
501 /**
502 * Current app IDs of temporarily whitelist apps for high-priority messages.
503 */
504 private int[] mTempWhitelistAppIdArray = new int[0];
505
Suprabh Shukla08105642017-09-26 14:45:30 -0700506 /**
507 * Apps in the system whitelist that have been taken out (probably because the user wanted to).
508 * They can be restored back by calling restoreAppToSystemWhitelist(String).
509 */
510 private ArrayMap<String, Integer> mRemovedFromSystemWhitelistApps = new ArrayMap<>();
511
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800512 private static final int EVENT_NULL = 0;
513 private static final int EVENT_NORMAL = 1;
514 private static final int EVENT_LIGHT_IDLE = 2;
515 private static final int EVENT_LIGHT_MAINTENANCE = 3;
Dianne Hackbornb6843652016-02-22 12:20:13 -0800516 private static final int EVENT_DEEP_IDLE = 4;
517 private static final int EVENT_DEEP_MAINTENANCE = 5;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800518
Dianne Hackbornef3aa6e2016-04-29 18:18:08 -0700519 private final int[] mEventCmds = new int[EVENT_BUFFER_SIZE];
520 private final long[] mEventTimes = new long[EVENT_BUFFER_SIZE];
Amith Yamasaniac6517a2018-04-23 12:19:34 -0700521 private final String[] mEventReasons = new String[EVENT_BUFFER_SIZE];
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800522
Amith Yamasaniac6517a2018-04-23 12:19:34 -0700523 private void addEvent(int cmd, String reason) {
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800524 if (mEventCmds[0] != cmd) {
525 System.arraycopy(mEventCmds, 0, mEventCmds, 1, EVENT_BUFFER_SIZE - 1);
526 System.arraycopy(mEventTimes, 0, mEventTimes, 1, EVENT_BUFFER_SIZE - 1);
Amith Yamasaniac6517a2018-04-23 12:19:34 -0700527 System.arraycopy(mEventReasons, 0, mEventReasons, 1, EVENT_BUFFER_SIZE - 1);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800528 mEventCmds[0] = cmd;
529 mEventTimes[0] = SystemClock.elapsedRealtime();
Amith Yamasaniac6517a2018-04-23 12:19:34 -0700530 mEventReasons[0] = reason;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800531 }
532 }
533
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700534 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
535 @Override public void onReceive(Context context, Intent intent) {
Dianne Hackborn88c41352016-04-07 15:18:58 -0700536 switch (intent.getAction()) {
537 case ConnectivityManager.CONNECTIVITY_ACTION: {
Dianne Hackborn4cb96ca2016-05-17 13:55:29 -0700538 updateConnectivityState(intent);
Dianne Hackborn88c41352016-04-07 15:18:58 -0700539 } break;
540 case Intent.ACTION_BATTERY_CHANGED: {
Robin Lee204cb222018-12-07 15:17:44 +0100541 boolean present = intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, true);
542 boolean plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
Dianne Hackborn88c41352016-04-07 15:18:58 -0700543 synchronized (DeviceIdleController.this) {
Robin Lee204cb222018-12-07 15:17:44 +0100544 updateChargingLocked(present && plugged);
Dianne Hackborn88c41352016-04-07 15:18:58 -0700545 }
546 } break;
547 case Intent.ACTION_PACKAGE_REMOVED: {
548 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
549 Uri data = intent.getData();
550 String ssp;
551 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
552 removePowerSaveWhitelistAppInternal(ssp);
553 }
554 }
555 } break;
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700556 }
557 }
558 };
559
560 private final AlarmManager.OnAlarmListener mLightAlarmListener
561 = new AlarmManager.OnAlarmListener() {
562 @Override
563 public void onAlarm() {
564 synchronized (DeviceIdleController.this) {
565 stepLightIdleStateLocked("s:alarm");
566 }
567 }
568 };
569
Kevin Gabayan92f15e62016-04-04 17:52:22 -0700570 private final AlarmManager.OnAlarmListener mSensingTimeoutAlarmListener
571 = new AlarmManager.OnAlarmListener() {
572 @Override
573 public void onAlarm() {
574 if (mState == STATE_SENSING) {
575 synchronized (DeviceIdleController.this) {
Kweku Adams00e3a372018-09-28 16:57:09 -0700576 // Restart the device idle progression in case the device moved but the screen
577 // didn't turn on.
Kevin Gabayan92f15e62016-04-04 17:52:22 -0700578 becomeInactiveIfAppropriateLocked();
579 }
580 }
581 }
582 };
583
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700584 private final AlarmManager.OnAlarmListener mDeepAlarmListener
585 = new AlarmManager.OnAlarmListener() {
586 @Override
587 public void onAlarm() {
588 synchronized (DeviceIdleController.this) {
589 stepIdleStateLocked("s:alarm");
590 }
591 }
592 };
593
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800594 private final BroadcastReceiver mIdleStartedDoneReceiver = new BroadcastReceiver() {
595 @Override public void onReceive(Context context, Intent intent) {
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700596 // When coming out of a deep idle, we will add in some delay before we allow
597 // the system to settle down and finish the maintenance window. This is
598 // to give a chance for any pending work to be scheduled.
599 if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(intent.getAction())) {
600 mHandler.sendEmptyMessageDelayed(MSG_FINISH_IDLE_OP,
601 mConstants.MIN_DEEP_MAINTENANCE_TIME);
602 } else {
603 mHandler.sendEmptyMessageDelayed(MSG_FINISH_IDLE_OP,
604 mConstants.MIN_LIGHT_MAINTENANCE_TIME);
605 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800606 }
607 };
608
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -0700609 private final BroadcastReceiver mInteractivityReceiver = new BroadcastReceiver() {
610 @Override
611 public void onReceive(Context context, Intent intent) {
Dianne Hackborn9b5ebc92017-09-08 13:45:35 -0700612 synchronized (DeviceIdleController.this) {
613 updateInteractivityLocked();
614 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700615 }
616 };
617
Kweku Adams00e3a372018-09-28 16:57:09 -0700618 @VisibleForTesting
619 final class MotionListener extends TriggerEventListener
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700620 implements SensorEventListener {
621
622 boolean active = false;
623
Kweku Adams00e3a372018-09-28 16:57:09 -0700624 public boolean isActive() {
625 return active;
626 }
627
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700628 @Override
629 public void onTrigger(TriggerEvent event) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700630 synchronized (DeviceIdleController.this) {
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700631 active = false;
632 motionLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700633 }
634 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700635
636 @Override
637 public void onSensorChanged(SensorEvent event) {
638 synchronized (DeviceIdleController.this) {
639 mSensorManager.unregisterListener(this, mMotionSensor);
640 active = false;
641 motionLocked();
642 }
643 }
644
645 @Override
646 public void onAccuracyChanged(Sensor sensor, int accuracy) {}
647
648 public boolean registerLocked() {
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700649 boolean success;
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700650 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
651 success = mSensorManager.requestTriggerSensor(mMotionListener, mMotionSensor);
652 } else {
653 success = mSensorManager.registerListener(
654 mMotionListener, mMotionSensor, SensorManager.SENSOR_DELAY_NORMAL);
655 }
656 if (success) {
657 active = true;
658 } else {
659 Slog.e(TAG, "Unable to register for " + mMotionSensor);
660 }
661 return success;
662 }
663
664 public void unregisterLocked() {
665 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
666 mSensorManager.cancelTriggerSensor(mMotionListener, mMotionSensor);
667 } else {
668 mSensorManager.unregisterListener(mMotionListener);
669 }
670 active = false;
671 }
672 }
Kweku Adams00e3a372018-09-28 16:57:09 -0700673 @VisibleForTesting final MotionListener mMotionListener = new MotionListener();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700674
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700675 private final LocationListener mGenericLocationListener = new LocationListener() {
676 @Override
677 public void onLocationChanged(Location location) {
678 synchronized (DeviceIdleController.this) {
679 receivedGenericLocationLocked(location);
680 }
681 }
682
683 @Override
684 public void onStatusChanged(String provider, int status, Bundle extras) {
685 }
686
687 @Override
688 public void onProviderEnabled(String provider) {
689 }
690
691 @Override
692 public void onProviderDisabled(String provider) {
693 }
694 };
695
696 private final LocationListener mGpsLocationListener = new LocationListener() {
697 @Override
698 public void onLocationChanged(Location location) {
699 synchronized (DeviceIdleController.this) {
700 receivedGpsLocationLocked(location);
701 }
702 }
703
704 @Override
705 public void onStatusChanged(String provider, int status, Bundle extras) {
706 }
707
708 @Override
709 public void onProviderEnabled(String provider) {
710 }
711
712 @Override
713 public void onProviderDisabled(String provider) {
714 }
715 };
716
Adam Lesinski31c05d12015-06-09 17:34:04 -0700717 /**
718 * All times are in milliseconds. These constants are kept synchronized with the system
719 * global Settings. Any access to this class or its fields should be done while
720 * holding the DeviceIdleController lock.
721 */
Robin Lee876b88542018-11-13 17:22:24 +0100722 public final class Constants extends ContentObserver {
Adam Lesinski31c05d12015-06-09 17:34:04 -0700723 // Key names stored in the settings value.
Dianne Hackborn953fc942016-03-29 15:36:24 -0700724 private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT
725 = "light_after_inactive_to";
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700726 private static final String KEY_LIGHT_PRE_IDLE_TIMEOUT = "light_pre_idle_to";
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700727 private static final String KEY_LIGHT_IDLE_TIMEOUT = "light_idle_to";
Dianne Hackborn953fc942016-03-29 15:36:24 -0700728 private static final String KEY_LIGHT_IDLE_FACTOR = "light_idle_factor";
729 private static final String KEY_LIGHT_MAX_IDLE_TIMEOUT = "light_max_idle_to";
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800730 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET
731 = "light_idle_maintenance_min_budget";
732 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET
733 = "light_idle_maintenance_max_budget";
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700734 private static final String KEY_MIN_LIGHT_MAINTENANCE_TIME = "min_light_maintenance_time";
735 private static final String KEY_MIN_DEEP_MAINTENANCE_TIME = "min_deep_maintenance_time";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700736 private static final String KEY_INACTIVE_TIMEOUT = "inactive_to";
737 private static final String KEY_SENSING_TIMEOUT = "sensing_to";
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700738 private static final String KEY_LOCATING_TIMEOUT = "locating_to";
739 private static final String KEY_LOCATION_ACCURACY = "location_accuracy";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700740 private static final String KEY_MOTION_INACTIVE_TIMEOUT = "motion_inactive_to";
741 private static final String KEY_IDLE_AFTER_INACTIVE_TIMEOUT = "idle_after_inactive_to";
742 private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to";
743 private static final String KEY_MAX_IDLE_PENDING_TIMEOUT = "max_idle_pending_to";
744 private static final String KEY_IDLE_PENDING_FACTOR = "idle_pending_factor";
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700745 private static final String KEY_QUICK_DOZE_DELAY_TIMEOUT = "quick_doze_delay_to";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700746 private static final String KEY_IDLE_TIMEOUT = "idle_to";
747 private static final String KEY_MAX_IDLE_TIMEOUT = "max_idle_to";
748 private static final String KEY_IDLE_FACTOR = "idle_factor";
749 private static final String KEY_MIN_TIME_TO_ALARM = "min_time_to_alarm";
750 private static final String KEY_MAX_TEMP_APP_WHITELIST_DURATION =
751 "max_temp_app_whitelist_duration";
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700752 private static final String KEY_MMS_TEMP_APP_WHITELIST_DURATION =
753 "mms_temp_app_whitelist_duration";
Dianne Hackborn451c3462015-07-21 17:39:46 -0700754 private static final String KEY_SMS_TEMP_APP_WHITELIST_DURATION =
755 "sms_temp_app_whitelist_duration";
Felipe Lemea1b79bf2016-05-24 13:06:54 -0700756 private static final String KEY_NOTIFICATION_WHITELIST_DURATION =
757 "notification_whitelist_duration";
Amith Yamasani396a10c2018-01-19 10:58:07 -0800758 /**
759 * Whether to wait for the user to unlock the device before causing screen-on to
760 * exit doze. Default = true
761 */
762 private static final String KEY_WAIT_FOR_UNLOCK = "wait_for_unlock";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700763
764 /**
Dianne Hackborn953fc942016-03-29 15:36:24 -0700765 * This is the time, after becoming inactive, that we go in to the first
766 * light-weight idle mode.
767 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
768 * @see #KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT
769 */
770 public long LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT;
771
772 /**
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700773 * This is amount of time we will wait from the point where we decide we would
774 * like to go idle until we actually do, while waiting for jobs and other current
775 * activity to finish.
776 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
777 * @see #KEY_LIGHT_PRE_IDLE_TIMEOUT
778 */
779 public long LIGHT_PRE_IDLE_TIMEOUT;
780
781 /**
Dianne Hackborn953fc942016-03-29 15:36:24 -0700782 * This is the initial time that we will run in idle maintenance mode.
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700783 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
784 * @see #KEY_LIGHT_IDLE_TIMEOUT
785 */
786 public long LIGHT_IDLE_TIMEOUT;
787
788 /**
Dianne Hackborn953fc942016-03-29 15:36:24 -0700789 * Scaling factor to apply to the light idle mode time each time we complete a cycle.
790 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
791 * @see #KEY_LIGHT_IDLE_FACTOR
792 */
793 public float LIGHT_IDLE_FACTOR;
794
795 /**
Kweku Adams00e3a372018-09-28 16:57:09 -0700796 * This is the maximum time we will run in idle maintenance mode.
Dianne Hackborn953fc942016-03-29 15:36:24 -0700797 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
798 * @see #KEY_LIGHT_MAX_IDLE_TIMEOUT
799 */
800 public long LIGHT_MAX_IDLE_TIMEOUT;
801
802 /**
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800803 * This is the minimum amount of time we want to make available for maintenance mode
804 * when lightly idling. That is, we will always have at least this amount of time
805 * available maintenance before timing out and cutting off maintenance mode.
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700806 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800807 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700808 */
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800809 public long LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
810
811 /**
812 * This is the maximum amount of time we want to make available for maintenance mode
813 * when lightly idling. That is, if the system isn't using up its minimum maintenance
814 * budget and this time is being added to the budget reserve, this is the maximum
815 * reserve size we will allow to grow and thus the maximum amount of time we will
816 * allow for the maintenance window.
817 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
818 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET
819 */
820 public long LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700821
822 /**
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700823 * This is the minimum amount of time that we will stay in maintenance mode after
824 * a light doze. We have this minimum to allow various things to respond to switching
825 * in to maintenance mode and scheduling their work -- otherwise we may
Dianne Hackborn7ab40252016-06-15 17:30:24 -0700826 * see there is nothing to do (no jobs pending) and go out of maintenance
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700827 * mode immediately.
828 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
829 * @see #KEY_MIN_LIGHT_MAINTENANCE_TIME
830 */
831 public long MIN_LIGHT_MAINTENANCE_TIME;
832
833 /**
834 * This is the minimum amount of time that we will stay in maintenance mode after
835 * a full doze. We have this minimum to allow various things to respond to switching
836 * in to maintenance mode and scheduling their work -- otherwise we may
Dianne Hackborn7ab40252016-06-15 17:30:24 -0700837 * see there is nothing to do (no jobs pending) and go out of maintenance
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700838 * mode immediately.
839 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
840 * @see #KEY_MIN_DEEP_MAINTENANCE_TIME
841 */
842 public long MIN_DEEP_MAINTENANCE_TIME;
843
844 /**
Adam Lesinski31c05d12015-06-09 17:34:04 -0700845 * This is the time, after becoming inactive, at which we start looking at the
846 * motion sensor to determine if the device is being left alone. We don't do this
847 * immediately after going inactive just because we don't want to be continually running
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700848 * the motion sensor whenever the screen is off.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700849 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
850 * @see #KEY_INACTIVE_TIMEOUT
851 */
852 public long INACTIVE_TIMEOUT;
853
854 /**
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700855 * If we don't receive a callback from AnyMotion in this amount of time +
856 * {@link #LOCATING_TIMEOUT}, we will change from
Adam Lesinski31c05d12015-06-09 17:34:04 -0700857 * STATE_SENSING to STATE_INACTIVE, and any AnyMotion callbacks while not in STATE_SENSING
858 * will be ignored.
859 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
860 * @see #KEY_SENSING_TIMEOUT
861 */
862 public long SENSING_TIMEOUT;
863
864 /**
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700865 * This is how long we will wait to try to get a good location fix before going in to
866 * idle mode.
867 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
868 * @see #KEY_LOCATING_TIMEOUT
869 */
870 public long LOCATING_TIMEOUT;
871
872 /**
873 * The desired maximum accuracy (in meters) we consider the location to be good enough to go
874 * on to idle. We will be trying to get an accuracy fix at least this good or until
875 * {@link #LOCATING_TIMEOUT} expires.
876 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
877 * @see #KEY_LOCATION_ACCURACY
878 */
879 public float LOCATION_ACCURACY;
880
881 /**
Adam Lesinski31c05d12015-06-09 17:34:04 -0700882 * This is the time, after seeing motion, that we wait after becoming inactive from
883 * that until we start looking for motion again.
884 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
885 * @see #KEY_MOTION_INACTIVE_TIMEOUT
886 */
887 public long MOTION_INACTIVE_TIMEOUT;
888
889 /**
890 * This is the time, after the inactive timeout elapses, that we will wait looking
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700891 * for motion until we truly consider the device to be idle.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700892 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
893 * @see #KEY_IDLE_AFTER_INACTIVE_TIMEOUT
894 */
895 public long IDLE_AFTER_INACTIVE_TIMEOUT;
896
897 /**
898 * This is the initial time, after being idle, that we will allow ourself to be back
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700899 * in the IDLE_MAINTENANCE state allowing the system to run normally until we return to
900 * idle.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700901 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
902 * @see #KEY_IDLE_PENDING_TIMEOUT
903 */
904 public long IDLE_PENDING_TIMEOUT;
905
906 /**
907 * Maximum pending idle timeout (time spent running) we will be allowed to use.
908 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
909 * @see #KEY_MAX_IDLE_PENDING_TIMEOUT
910 */
911 public long MAX_IDLE_PENDING_TIMEOUT;
912
913 /**
914 * Scaling factor to apply to current pending idle timeout each time we cycle through
915 * that state.
916 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
917 * @see #KEY_IDLE_PENDING_FACTOR
918 */
919 public float IDLE_PENDING_FACTOR;
920
921 /**
Kweku Adamsb396ccf2018-09-17 16:37:15 -0700922 * This is amount of time we will wait from the point where we go into
923 * STATE_QUICK_DOZE_DELAY until we actually go into STATE_IDLE, while waiting for jobs
924 * and other current activity to finish.
925 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
926 * @see #KEY_QUICK_DOZE_DELAY_TIMEOUT
927 */
928 public long QUICK_DOZE_DELAY_TIMEOUT;
929
930 /**
Adam Lesinski31c05d12015-06-09 17:34:04 -0700931 * This is the initial time that we want to sit in the idle state before waking up
932 * again to return to pending idle and allowing normal work to run.
933 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
934 * @see #KEY_IDLE_TIMEOUT
935 */
936 public long IDLE_TIMEOUT;
937
938 /**
939 * Maximum idle duration we will be allowed to use.
940 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
941 * @see #KEY_MAX_IDLE_TIMEOUT
942 */
943 public long MAX_IDLE_TIMEOUT;
944
945 /**
946 * Scaling factor to apply to current idle timeout each time we cycle through that state.
947 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
948 * @see #KEY_IDLE_FACTOR
949 */
950 public float IDLE_FACTOR;
951
952 /**
953 * This is the minimum time we will allow until the next upcoming alarm for us to
954 * actually go in to idle mode.
955 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
956 * @see #KEY_MIN_TIME_TO_ALARM
957 */
958 public long MIN_TIME_TO_ALARM;
959
960 /**
961 * Max amount of time to temporarily whitelist an app when it receives a high priority
962 * tickle.
963 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
964 * @see #KEY_MAX_TEMP_APP_WHITELIST_DURATION
965 */
966 public long MAX_TEMP_APP_WHITELIST_DURATION;
967
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700968 /**
969 * Amount of time we would like to whitelist an app that is receiving an MMS.
970 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
971 * @see #KEY_MMS_TEMP_APP_WHITELIST_DURATION
972 */
973 public long MMS_TEMP_APP_WHITELIST_DURATION;
974
Dianne Hackborn451c3462015-07-21 17:39:46 -0700975 /**
976 * Amount of time we would like to whitelist an app that is receiving an SMS.
977 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
978 * @see #KEY_SMS_TEMP_APP_WHITELIST_DURATION
979 */
980 public long SMS_TEMP_APP_WHITELIST_DURATION;
981
Felipe Lemea1b79bf2016-05-24 13:06:54 -0700982 /**
983 * Amount of time we would like to whitelist an app that is handling a
984 * {@link android.app.PendingIntent} triggered by a {@link android.app.Notification}.
985 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
986 * @see #KEY_NOTIFICATION_WHITELIST_DURATION
987 */
988 public long NOTIFICATION_WHITELIST_DURATION;
989
Amith Yamasani396a10c2018-01-19 10:58:07 -0800990 public boolean WAIT_FOR_UNLOCK;
991
Adam Lesinski31c05d12015-06-09 17:34:04 -0700992 private final ContentResolver mResolver;
shreerag597da8a2017-07-21 14:24:14 -0700993 private final boolean mSmallBatteryDevice;
Adam Lesinski31c05d12015-06-09 17:34:04 -0700994 private final KeyValueListParser mParser = new KeyValueListParser(',');
995
996 public Constants(Handler handler, ContentResolver resolver) {
997 super(handler);
998 mResolver = resolver;
shreerag597da8a2017-07-21 14:24:14 -0700999 mSmallBatteryDevice = ActivityManager.isSmallBatteryDevice();
1000 mResolver.registerContentObserver(
1001 Settings.Global.getUriFor(Settings.Global.DEVICE_IDLE_CONSTANTS),
Joe LaPennaf33b5bf2016-03-23 15:19:47 -07001002 false, this);
Adam Lesinski31c05d12015-06-09 17:34:04 -07001003 updateConstants();
1004 }
1005
1006 @Override
1007 public void onChange(boolean selfChange, Uri uri) {
1008 updateConstants();
1009 }
1010
1011 private void updateConstants() {
1012 synchronized (DeviceIdleController.this) {
1013 try {
1014 mParser.setString(Settings.Global.getString(mResolver,
shreerag597da8a2017-07-21 14:24:14 -07001015 Settings.Global.DEVICE_IDLE_CONSTANTS));
Adam Lesinski31c05d12015-06-09 17:34:04 -07001016 } catch (IllegalArgumentException e) {
1017 // Failed to parse the settings string, log this and move on
1018 // with defaults.
1019 Slog.e(TAG, "Bad device idle settings", e);
1020 }
1021
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001022 LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getDurationMillis(
Dianne Hackborn953fc942016-03-29 15:36:24 -07001023 KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
Suprabh Shukla85fff7d2018-05-08 17:39:24 -07001024 !COMPRESS_TIME ? 3 * 60 * 1000L : 15 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001025 LIGHT_PRE_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_LIGHT_PRE_IDLE_TIMEOUT,
Suprabh Shukla85fff7d2018-05-08 17:39:24 -07001026 !COMPRESS_TIME ? 3 * 60 * 1000L : 30 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001027 LIGHT_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_LIGHT_IDLE_TIMEOUT,
Dianne Hackborn953fc942016-03-29 15:36:24 -07001028 !COMPRESS_TIME ? 5 * 60 * 1000L : 15 * 1000L);
1029 LIGHT_IDLE_FACTOR = mParser.getFloat(KEY_LIGHT_IDLE_FACTOR,
1030 2f);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001031 LIGHT_MAX_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_LIGHT_MAX_IDLE_TIMEOUT,
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001032 !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001033 LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = mParser.getDurationMillis(
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001034 KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET,
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001035 !COMPRESS_TIME ? 1 * 60 * 1000L : 15 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001036 LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = mParser.getDurationMillis(
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001037 KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET,
1038 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001039 MIN_LIGHT_MAINTENANCE_TIME = mParser.getDurationMillis(
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001040 KEY_MIN_LIGHT_MAINTENANCE_TIME,
1041 !COMPRESS_TIME ? 5 * 1000L : 1 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001042 MIN_DEEP_MAINTENANCE_TIME = mParser.getDurationMillis(
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001043 KEY_MIN_DEEP_MAINTENANCE_TIME,
1044 !COMPRESS_TIME ? 30 * 1000L : 5 * 1000L);
Michael Kwan88871462017-08-21 13:13:37 -07001045 long inactiveTimeoutDefault = (mSmallBatteryDevice ? 15 : 30) * 60 * 1000L;
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001046 INACTIVE_TIMEOUT = mParser.getDurationMillis(KEY_INACTIVE_TIMEOUT,
Joe LaPenna0c5d3e92016-03-24 13:29:56 -07001047 !COMPRESS_TIME ? inactiveTimeoutDefault : (inactiveTimeoutDefault / 10));
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001048 SENSING_TIMEOUT = mParser.getDurationMillis(KEY_SENSING_TIMEOUT,
Kweku Adams9da2bb92018-12-20 06:34:39 -08001049 !COMPRESS_TIME ? 4 * 60 * 1000L : 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001050 LOCATING_TIMEOUT = mParser.getDurationMillis(KEY_LOCATING_TIMEOUT,
Kweku Adams9da2bb92018-12-20 06:34:39 -08001051 !COMPRESS_TIME ? 30 * 1000L : 15 * 1000L);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001052 LOCATION_ACCURACY = mParser.getFloat(KEY_LOCATION_ACCURACY, 20);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001053 MOTION_INACTIVE_TIMEOUT = mParser.getDurationMillis(KEY_MOTION_INACTIVE_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001054 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
Michael Kwan88871462017-08-21 13:13:37 -07001055 long idleAfterInactiveTimeout = (mSmallBatteryDevice ? 15 : 30) * 60 * 1000L;
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001056 IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getDurationMillis(
1057 KEY_IDLE_AFTER_INACTIVE_TIMEOUT,
Joe LaPenna0c5d3e92016-03-24 13:29:56 -07001058 !COMPRESS_TIME ? idleAfterInactiveTimeout
1059 : (idleAfterInactiveTimeout / 10));
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001060 IDLE_PENDING_TIMEOUT = mParser.getDurationMillis(KEY_IDLE_PENDING_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001061 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001062 MAX_IDLE_PENDING_TIMEOUT = mParser.getDurationMillis(KEY_MAX_IDLE_PENDING_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001063 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
1064 IDLE_PENDING_FACTOR = mParser.getFloat(KEY_IDLE_PENDING_FACTOR,
1065 2f);
Kweku Adamsb396ccf2018-09-17 16:37:15 -07001066 QUICK_DOZE_DELAY_TIMEOUT = mParser.getDurationMillis(
1067 KEY_QUICK_DOZE_DELAY_TIMEOUT, !COMPRESS_TIME ? 60 * 1000L : 15 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001068 IDLE_TIMEOUT = mParser.getDurationMillis(KEY_IDLE_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001069 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001070 MAX_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_MAX_IDLE_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001071 !COMPRESS_TIME ? 6 * 60 * 60 * 1000L : 30 * 60 * 1000L);
1072 IDLE_FACTOR = mParser.getFloat(KEY_IDLE_FACTOR,
1073 2f);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001074 MIN_TIME_TO_ALARM = mParser.getDurationMillis(KEY_MIN_TIME_TO_ALARM,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001075 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001076 MAX_TEMP_APP_WHITELIST_DURATION = mParser.getDurationMillis(
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001077 KEY_MAX_TEMP_APP_WHITELIST_DURATION, 5 * 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001078 MMS_TEMP_APP_WHITELIST_DURATION = mParser.getDurationMillis(
Dianne Hackborn0b6134b2015-07-14 18:48:07 -07001079 KEY_MMS_TEMP_APP_WHITELIST_DURATION, 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001080 SMS_TEMP_APP_WHITELIST_DURATION = mParser.getDurationMillis(
Dianne Hackborn451c3462015-07-21 17:39:46 -07001081 KEY_SMS_TEMP_APP_WHITELIST_DURATION, 20 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001082 NOTIFICATION_WHITELIST_DURATION = mParser.getDurationMillis(
Felipe Lemea1b79bf2016-05-24 13:06:54 -07001083 KEY_NOTIFICATION_WHITELIST_DURATION, 30 * 1000L);
Amith Yamasani396a10c2018-01-19 10:58:07 -08001084 WAIT_FOR_UNLOCK = mParser.getBoolean(KEY_WAIT_FOR_UNLOCK, false);
Adam Lesinski31c05d12015-06-09 17:34:04 -07001085 }
1086 }
1087
1088 void dump(PrintWriter pw) {
1089 pw.println(" Settings:");
1090
Dianne Hackborn953fc942016-03-29 15:36:24 -07001091 pw.print(" "); pw.print(KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("=");
1092 TimeUtils.formatDuration(LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT, pw);
1093 pw.println();
1094
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001095 pw.print(" "); pw.print(KEY_LIGHT_PRE_IDLE_TIMEOUT); pw.print("=");
1096 TimeUtils.formatDuration(LIGHT_PRE_IDLE_TIMEOUT, pw);
1097 pw.println();
1098
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001099 pw.print(" "); pw.print(KEY_LIGHT_IDLE_TIMEOUT); pw.print("=");
1100 TimeUtils.formatDuration(LIGHT_IDLE_TIMEOUT, pw);
1101 pw.println();
1102
Dianne Hackborn953fc942016-03-29 15:36:24 -07001103 pw.print(" "); pw.print(KEY_LIGHT_IDLE_FACTOR); pw.print("=");
1104 pw.print(LIGHT_IDLE_FACTOR);
1105 pw.println();
1106
1107 pw.print(" "); pw.print(KEY_LIGHT_MAX_IDLE_TIMEOUT); pw.print("=");
1108 TimeUtils.formatDuration(LIGHT_MAX_IDLE_TIMEOUT, pw);
1109 pw.println();
1110
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001111 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET); pw.print("=");
1112 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MIN_BUDGET, pw);
1113 pw.println();
1114
1115 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET); pw.print("=");
1116 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MAX_BUDGET, pw);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001117 pw.println();
1118
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001119 pw.print(" "); pw.print(KEY_MIN_LIGHT_MAINTENANCE_TIME); pw.print("=");
1120 TimeUtils.formatDuration(MIN_LIGHT_MAINTENANCE_TIME, pw);
1121 pw.println();
1122
1123 pw.print(" "); pw.print(KEY_MIN_DEEP_MAINTENANCE_TIME); pw.print("=");
1124 TimeUtils.formatDuration(MIN_DEEP_MAINTENANCE_TIME, pw);
1125 pw.println();
1126
Dianne Hackborna750a632015-06-16 17:18:23 -07001127 pw.print(" "); pw.print(KEY_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001128 TimeUtils.formatDuration(INACTIVE_TIMEOUT, pw);
1129 pw.println();
1130
Dianne Hackborna750a632015-06-16 17:18:23 -07001131 pw.print(" "); pw.print(KEY_SENSING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001132 TimeUtils.formatDuration(SENSING_TIMEOUT, pw);
1133 pw.println();
1134
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001135 pw.print(" "); pw.print(KEY_LOCATING_TIMEOUT); pw.print("=");
1136 TimeUtils.formatDuration(LOCATING_TIMEOUT, pw);
1137 pw.println();
1138
1139 pw.print(" "); pw.print(KEY_LOCATION_ACCURACY); pw.print("=");
1140 pw.print(LOCATION_ACCURACY); pw.print("m");
1141 pw.println();
1142
Dianne Hackborna750a632015-06-16 17:18:23 -07001143 pw.print(" "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001144 TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT, pw);
1145 pw.println();
1146
Dianne Hackborna750a632015-06-16 17:18:23 -07001147 pw.print(" "); pw.print(KEY_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001148 TimeUtils.formatDuration(IDLE_AFTER_INACTIVE_TIMEOUT, pw);
1149 pw.println();
1150
Dianne Hackborna750a632015-06-16 17:18:23 -07001151 pw.print(" "); pw.print(KEY_IDLE_PENDING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001152 TimeUtils.formatDuration(IDLE_PENDING_TIMEOUT, pw);
1153 pw.println();
1154
Dianne Hackborna750a632015-06-16 17:18:23 -07001155 pw.print(" "); pw.print(KEY_MAX_IDLE_PENDING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001156 TimeUtils.formatDuration(MAX_IDLE_PENDING_TIMEOUT, pw);
1157 pw.println();
1158
Dianne Hackborna750a632015-06-16 17:18:23 -07001159 pw.print(" "); pw.print(KEY_IDLE_PENDING_FACTOR); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001160 pw.println(IDLE_PENDING_FACTOR);
1161
Kweku Adamsb396ccf2018-09-17 16:37:15 -07001162 pw.print(" "); pw.print(KEY_QUICK_DOZE_DELAY_TIMEOUT); pw.print("=");
1163 TimeUtils.formatDuration(QUICK_DOZE_DELAY_TIMEOUT, pw);
1164 pw.println();
1165
Dianne Hackborna750a632015-06-16 17:18:23 -07001166 pw.print(" "); pw.print(KEY_IDLE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001167 TimeUtils.formatDuration(IDLE_TIMEOUT, pw);
1168 pw.println();
1169
Dianne Hackborna750a632015-06-16 17:18:23 -07001170 pw.print(" "); pw.print(KEY_MAX_IDLE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001171 TimeUtils.formatDuration(MAX_IDLE_TIMEOUT, pw);
1172 pw.println();
1173
Dianne Hackborna750a632015-06-16 17:18:23 -07001174 pw.print(" "); pw.print(KEY_IDLE_FACTOR); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001175 pw.println(IDLE_FACTOR);
1176
Dianne Hackborna750a632015-06-16 17:18:23 -07001177 pw.print(" "); pw.print(KEY_MIN_TIME_TO_ALARM); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001178 TimeUtils.formatDuration(MIN_TIME_TO_ALARM, pw);
1179 pw.println();
1180
Dianne Hackborna750a632015-06-16 17:18:23 -07001181 pw.print(" "); pw.print(KEY_MAX_TEMP_APP_WHITELIST_DURATION); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001182 TimeUtils.formatDuration(MAX_TEMP_APP_WHITELIST_DURATION, pw);
1183 pw.println();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001184
1185 pw.print(" "); pw.print(KEY_MMS_TEMP_APP_WHITELIST_DURATION); pw.print("=");
1186 TimeUtils.formatDuration(MMS_TEMP_APP_WHITELIST_DURATION, pw);
1187 pw.println();
Dianne Hackborn451c3462015-07-21 17:39:46 -07001188
1189 pw.print(" "); pw.print(KEY_SMS_TEMP_APP_WHITELIST_DURATION); pw.print("=");
1190 TimeUtils.formatDuration(SMS_TEMP_APP_WHITELIST_DURATION, pw);
1191 pw.println();
Felipe Lemea1b79bf2016-05-24 13:06:54 -07001192
1193 pw.print(" "); pw.print(KEY_NOTIFICATION_WHITELIST_DURATION); pw.print("=");
1194 TimeUtils.formatDuration(NOTIFICATION_WHITELIST_DURATION, pw);
1195 pw.println();
Amith Yamasani396a10c2018-01-19 10:58:07 -08001196
1197 pw.print(" "); pw.print(KEY_WAIT_FOR_UNLOCK); pw.print("=");
1198 pw.println(WAIT_FOR_UNLOCK);
Adam Lesinski31c05d12015-06-09 17:34:04 -07001199 }
1200 }
1201
1202 private Constants mConstants;
1203
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001204 @Override
1205 public void onAnyMotionResult(int result) {
1206 if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")");
Kevin Gabayan92f15e62016-04-04 17:52:22 -07001207 if (result != AnyMotionDetector.RESULT_UNKNOWN) {
1208 synchronized (this) {
1209 cancelSensingTimeoutAlarmLocked();
1210 }
1211 }
Kevin Gabayandcf47012016-07-08 10:41:24 -07001212 if ((result == AnyMotionDetector.RESULT_MOVED) ||
1213 (result == AnyMotionDetector.RESULT_UNKNOWN)) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001214 synchronized (this) {
Kevin Gabayandcf47012016-07-08 10:41:24 -07001215 handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "non_stationary");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001216 }
1217 } else if (result == AnyMotionDetector.RESULT_STATIONARY) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001218 if (mState == STATE_SENSING) {
1219 // If we are currently sensing, it is time to move to locating.
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001220 synchronized (this) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001221 mNotMoving = true;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001222 stepIdleStateLocked("s:stationary");
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001223 }
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001224 } else if (mState == STATE_LOCATING) {
1225 // If we are currently locating, note that we are not moving and step
1226 // if we have located the position.
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001227 synchronized (this) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001228 mNotMoving = true;
1229 if (mLocated) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001230 stepIdleStateLocked("s:stationary");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001231 }
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001232 }
1233 }
1234 }
1235 }
1236
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001237 private static final int MSG_WRITE_CONFIG = 1;
1238 private static final int MSG_REPORT_IDLE_ON = 2;
1239 private static final int MSG_REPORT_IDLE_ON_LIGHT = 3;
1240 private static final int MSG_REPORT_IDLE_OFF = 4;
1241 private static final int MSG_REPORT_ACTIVE = 5;
1242 private static final int MSG_TEMP_APP_WHITELIST_TIMEOUT = 6;
1243 private static final int MSG_REPORT_MAINTENANCE_ACTIVITY = 7;
1244 private static final int MSG_FINISH_IDLE_OP = 8;
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07001245 private static final int MSG_REPORT_TEMP_APP_WHITELIST_CHANGED = 9;
Robin Lee876b88542018-11-13 17:22:24 +01001246 private static final int MSG_SEND_CONSTRAINT_MONITORING = 10;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001247
1248 final class MyHandler extends Handler {
1249 MyHandler(Looper looper) {
1250 super(looper);
1251 }
1252
1253 @Override public void handleMessage(Message msg) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001254 if (DEBUG) Slog.d(TAG, "handleMessage(" + msg.what + ")");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001255 switch (msg.what) {
1256 case MSG_WRITE_CONFIG: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001257 // Does not hold a wakelock. Just let this happen whenever.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001258 handleWriteConfigFile();
1259 } break;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001260 case MSG_REPORT_IDLE_ON:
1261 case MSG_REPORT_IDLE_ON_LIGHT: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001262 // mGoingIdleWakeLock is held at this point
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001263 EventLogTags.writeDeviceIdleOnStart();
Dianne Hackbornb6843652016-02-22 12:20:13 -08001264 final boolean deepChanged;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001265 final boolean lightChanged;
1266 if (msg.what == MSG_REPORT_IDLE_ON) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08001267 deepChanged = mLocalPowerManager.setDeviceIdleMode(true);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001268 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
1269 } else {
Dianne Hackbornb6843652016-02-22 12:20:13 -08001270 deepChanged = mLocalPowerManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001271 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(true);
1272 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001273 try {
1274 mNetworkPolicyManager.setDeviceIdleMode(true);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001275 mBatteryStats.noteDeviceIdleMode(msg.what == MSG_REPORT_IDLE_ON
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001276 ? BatteryStats.DEVICE_IDLE_MODE_DEEP
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001277 : BatteryStats.DEVICE_IDLE_MODE_LIGHT, null, Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001278 } catch (RemoteException e) {
1279 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08001280 if (deepChanged) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001281 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
1282 }
1283 if (lightChanged) {
1284 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL);
1285 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001286 EventLogTags.writeDeviceIdleOnComplete();
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001287 mGoingIdleWakeLock.release();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001288 } break;
1289 case MSG_REPORT_IDLE_OFF: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001290 // mActiveIdleWakeLock is held at this point
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001291 EventLogTags.writeDeviceIdleOffStart("unknown");
Dianne Hackbornb6843652016-02-22 12:20:13 -08001292 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001293 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001294 try {
1295 mNetworkPolicyManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001296 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF,
1297 null, Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001298 } catch (RemoteException e) {
1299 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08001300 if (deepChanged) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001301 incActiveIdleOps();
1302 getContext().sendOrderedBroadcastAsUser(mIdleIntent, UserHandle.ALL,
1303 null, mIdleStartedDoneReceiver, null, 0, null, null);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001304 }
1305 if (lightChanged) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001306 incActiveIdleOps();
1307 getContext().sendOrderedBroadcastAsUser(mLightIdleIntent, UserHandle.ALL,
1308 null, mIdleStartedDoneReceiver, null, 0, null, null);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001309 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001310 // Always start with one active op for the message being sent here.
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001311 // Now we are done!
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001312 decActiveIdleOps();
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001313 EventLogTags.writeDeviceIdleOffComplete();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001314 } break;
1315 case MSG_REPORT_ACTIVE: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001316 // The device is awake at this point, so no wakelock necessary.
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001317 String activeReason = (String)msg.obj;
1318 int activeUid = msg.arg1;
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001319 EventLogTags.writeDeviceIdleOffStart(
1320 activeReason != null ? activeReason : "unknown");
Dianne Hackbornb6843652016-02-22 12:20:13 -08001321 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001322 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001323 try {
1324 mNetworkPolicyManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001325 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF,
1326 activeReason, activeUid);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001327 } catch (RemoteException e) {
1328 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08001329 if (deepChanged) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001330 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
1331 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001332 if (lightChanged) {
1333 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL);
1334 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001335 EventLogTags.writeDeviceIdleOffComplete();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001336 } break;
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001337 case MSG_TEMP_APP_WHITELIST_TIMEOUT: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001338 // TODO: What is keeping the device awake at this point? Does it need to be?
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001339 int uid = msg.arg1;
1340 checkTempAppWhitelistTimeout(uid);
1341 } break;
Yao Chenca5edbb2016-01-13 14:44:36 -08001342 case MSG_REPORT_MAINTENANCE_ACTIVITY: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001343 // TODO: What is keeping the device awake at this point? Does it need to be?
Yao Chenca5edbb2016-01-13 14:44:36 -08001344 boolean active = (msg.arg1 == 1);
1345 final int size = mMaintenanceActivityListeners.beginBroadcast();
1346 try {
1347 for (int i = 0; i < size; i++) {
1348 try {
1349 mMaintenanceActivityListeners.getBroadcastItem(i)
1350 .onMaintenanceActivityChanged(active);
1351 } catch (RemoteException ignored) {
1352 }
1353 }
1354 } finally {
1355 mMaintenanceActivityListeners.finishBroadcast();
1356 }
1357 } break;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001358 case MSG_FINISH_IDLE_OP: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001359 // mActiveIdleWakeLock is held at this point
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001360 decActiveIdleOps();
1361 } break;
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07001362 case MSG_REPORT_TEMP_APP_WHITELIST_CHANGED: {
1363 final int appId = msg.arg1;
1364 final boolean added = (msg.arg2 == 1);
1365 mNetworkPolicyManagerInternal.onTempPowerSaveWhitelistChange(appId, added);
1366 } break;
Robin Lee876b88542018-11-13 17:22:24 +01001367 case MSG_SEND_CONSTRAINT_MONITORING: {
1368 final IDeviceIdleConstraint constraint = (IDeviceIdleConstraint) msg.obj;
1369 final boolean monitoring = (msg.arg1 == 1);
1370 if (monitoring) {
1371 constraint.startMonitoring();
1372 } else {
1373 constraint.stopMonitoring();
1374 }
1375 } break;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001376 }
1377 }
1378 }
1379
1380 final MyHandler mHandler;
1381
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001382 BinderService mBinderService;
1383
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001384 private final class BinderService extends IDeviceIdleController.Stub {
1385 @Override public void addPowerSaveWhitelistApp(String name) {
Eugene Susla6a7006a2017-03-13 12:57:58 -07001386 if (DEBUG) {
1387 Slog.i(TAG, "addPowerSaveWhitelistApp(name = " + name + ")");
1388 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001389 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1390 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001391 long ident = Binder.clearCallingIdentity();
1392 try {
1393 addPowerSaveWhitelistAppInternal(name);
1394 } finally {
1395 Binder.restoreCallingIdentity(ident);
1396 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001397 }
1398
1399 @Override public void removePowerSaveWhitelistApp(String name) {
Eugene Susla6a7006a2017-03-13 12:57:58 -07001400 if (DEBUG) {
1401 Slog.i(TAG, "removePowerSaveWhitelistApp(name = " + name + ")");
1402 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001403 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1404 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001405 long ident = Binder.clearCallingIdentity();
1406 try {
1407 removePowerSaveWhitelistAppInternal(name);
1408 } finally {
1409 Binder.restoreCallingIdentity(ident);
1410 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001411 }
1412
Suprabh Shukla08105642017-09-26 14:45:30 -07001413 @Override public void removeSystemPowerWhitelistApp(String name) {
1414 if (DEBUG) {
1415 Slog.d(TAG, "removeAppFromSystemWhitelist(name = " + name + ")");
1416 }
1417 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1418 null);
1419 long ident = Binder.clearCallingIdentity();
1420 try {
1421 removeSystemPowerWhitelistAppInternal(name);
1422 } finally {
1423 Binder.restoreCallingIdentity(ident);
1424 }
1425 }
1426
1427 @Override public void restoreSystemPowerWhitelistApp(String name) {
1428 if (DEBUG) {
1429 Slog.d(TAG, "restoreAppToSystemWhitelist(name = " + name + ")");
1430 }
1431 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1432 null);
1433 long ident = Binder.clearCallingIdentity();
1434 try {
1435 restoreSystemPowerWhitelistAppInternal(name);
1436 } finally {
1437 Binder.restoreCallingIdentity(ident);
1438 }
1439 }
1440
1441 public String[] getRemovedSystemPowerWhitelistApps() {
1442 return getRemovedSystemPowerWhitelistAppsInternal();
1443 }
1444
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001445 @Override public String[] getSystemPowerWhitelistExceptIdle() {
1446 return getSystemPowerWhitelistExceptIdleInternal();
1447 }
1448
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001449 @Override public String[] getSystemPowerWhitelist() {
1450 return getSystemPowerWhitelistInternal();
1451 }
1452
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001453 @Override public String[] getUserPowerWhitelist() {
1454 return getUserPowerWhitelistInternal();
1455 }
1456
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001457 @Override public String[] getFullPowerWhitelistExceptIdle() {
1458 return getFullPowerWhitelistExceptIdleInternal();
1459 }
1460
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001461 @Override public String[] getFullPowerWhitelist() {
1462 return getFullPowerWhitelistInternal();
1463 }
1464
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001465 @Override public int[] getAppIdWhitelistExceptIdle() {
1466 return getAppIdWhitelistExceptIdleInternal();
1467 }
1468
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001469 @Override public int[] getAppIdWhitelist() {
1470 return getAppIdWhitelistInternal();
1471 }
1472
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001473 @Override public int[] getAppIdUserWhitelist() {
1474 return getAppIdUserWhitelistInternal();
1475 }
1476
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001477 @Override public int[] getAppIdTempWhitelist() {
1478 return getAppIdTempWhitelistInternal();
1479 }
1480
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001481 @Override public boolean isPowerSaveWhitelistExceptIdleApp(String name) {
1482 return isPowerSaveWhitelistExceptIdleAppInternal(name);
1483 }
1484
Amith Yamasani06bf8242015-05-08 16:36:21 -07001485 @Override public boolean isPowerSaveWhitelistApp(String name) {
1486 return isPowerSaveWhitelistAppInternal(name);
1487 }
1488
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001489 @Override public void addPowerSaveTempWhitelistApp(String packageName, long duration,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001490 int userId, String reason) throws RemoteException {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001491 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001492 }
1493
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001494 @Override public long addPowerSaveTempWhitelistAppForMms(String packageName,
1495 int userId, String reason) throws RemoteException {
1496 long duration = mConstants.MMS_TEMP_APP_WHITELIST_DURATION;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001497 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001498 return duration;
1499 }
1500
Dianne Hackborn451c3462015-07-21 17:39:46 -07001501 @Override public long addPowerSaveTempWhitelistAppForSms(String packageName,
1502 int userId, String reason) throws RemoteException {
1503 long duration = mConstants.SMS_TEMP_APP_WHITELIST_DURATION;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001504 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Dianne Hackborn451c3462015-07-21 17:39:46 -07001505 return duration;
1506 }
1507
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001508 @Override public void exitIdle(String reason) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001509 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER,
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001510 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001511 long ident = Binder.clearCallingIdentity();
1512 try {
1513 exitIdleInternal(reason);
1514 } finally {
1515 Binder.restoreCallingIdentity(ident);
1516 }
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001517 }
1518
Yao Chenca5edbb2016-01-13 14:44:36 -08001519 @Override public boolean registerMaintenanceActivityListener(
1520 IMaintenanceActivityListener listener) {
1521 return DeviceIdleController.this.registerMaintenanceActivityListener(listener);
1522 }
1523
1524 @Override public void unregisterMaintenanceActivityListener(
1525 IMaintenanceActivityListener listener) {
1526 DeviceIdleController.this.unregisterMaintenanceActivityListener(listener);
1527 }
1528
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001529 @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1530 DeviceIdleController.this.dump(fd, pw, args);
1531 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001532
1533 @Override public void onShellCommand(FileDescriptor in, FileDescriptor out,
Dianne Hackborn354736e2016-08-22 17:00:05 -07001534 FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
1535 (new Shell()).exec(this, in, out, err, args, callback, resultReceiver);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001536 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001537 }
1538
Felipe Lemeef134662016-08-10 14:46:39 -07001539 public class LocalService {
Robin Lee876b88542018-11-13 17:22:24 +01001540 public void onConstraintStateChanged(IDeviceIdleConstraint constraint, boolean active) {
1541 synchronized (DeviceIdleController.this) {
1542 onConstraintStateChangedLocked(constraint, active);
1543 }
1544 }
1545
1546 public void registerDeviceIdleConstraint(IDeviceIdleConstraint constraint, String name,
1547 @IDeviceIdleConstraint.MinimumState int minState) {
1548 registerDeviceIdleConstraintInternal(constraint, name, minState);
1549 }
1550
1551 public void unregisterDeviceIdleConstraint(IDeviceIdleConstraint constraint) {
1552 unregisterDeviceIdleConstraintInternal(constraint);
1553 }
1554
1555 public void exitIdle(String reason) {
1556 exitIdleInternal(reason);
1557 }
1558
Christopher Tatee0be7e82017-02-08 17:38:20 -08001559 // duration in milliseconds
1560 public void addPowerSaveTempWhitelistApp(int callingUid, String packageName,
1561 long duration, int userId, boolean sync, String reason) {
1562 addPowerSaveTempWhitelistAppInternal(callingUid, packageName, duration,
1563 userId, sync, reason);
1564 }
1565
1566 // duration in milliseconds
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001567 public void addPowerSaveTempWhitelistAppDirect(int appId, long duration, boolean sync,
1568 String reason) {
1569 addPowerSaveTempWhitelistAppDirectInternal(0, appId, duration, sync, reason);
1570 }
1571
Christopher Tatee0be7e82017-02-08 17:38:20 -08001572 // duration in milliseconds
Felipe Lemea1b79bf2016-05-24 13:06:54 -07001573 public long getNotificationWhitelistDuration() {
1574 return mConstants.NOTIFICATION_WHITELIST_DURATION;
1575 }
1576
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001577 public void setJobsActive(boolean active) {
1578 DeviceIdleController.this.setJobsActive(active);
1579 }
1580
1581 // Up-call from alarm manager.
1582 public void setAlarmsActive(boolean active) {
1583 DeviceIdleController.this.setAlarmsActive(active);
1584 }
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001585
Christopher Tate42a386b2016-11-07 12:21:21 -08001586 /** Is the app on any of the power save whitelists, whether system or user? */
1587 public boolean isAppOnWhitelist(int appid) {
1588 return DeviceIdleController.this.isAppOnWhitelistInternal(appid);
1589 }
1590
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001591 /**
1592 * Returns the array of app ids whitelisted by user. Take care not to
1593 * modify this, as it is a reference to the original copy. But the reference
1594 * can change when the list changes, so it needs to be re-acquired when
1595 * {@link PowerManager#ACTION_POWER_SAVE_WHITELIST_CHANGED} is sent.
1596 */
1597 public int[] getPowerSaveWhitelistUserAppIds() {
1598 return DeviceIdleController.this.getPowerSaveWhitelistUserAppIds();
1599 }
Suprabh Shuklaa78acfd2017-10-13 19:29:36 -07001600
1601 public int[] getPowerSaveTempWhitelistAppIds() {
1602 return DeviceIdleController.this.getAppIdTempWhitelistInternal();
1603 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001604 }
1605
Kweku Adams00e3a372018-09-28 16:57:09 -07001606 static class Injector {
1607 private final Context mContext;
Kweku Adams799858b2018-10-08 17:19:08 -07001608 private ConnectivityService mConnectivityService;
Kweku Adams9da2bb92018-12-20 06:34:39 -08001609 private Constants mConstants;
Kweku Adams799858b2018-10-08 17:19:08 -07001610 private LocationManager mLocationManager;
Kweku Adams00e3a372018-09-28 16:57:09 -07001611
1612 Injector(Context ctx) {
1613 mContext = ctx;
1614 }
1615
1616 AlarmManager getAlarmManager() {
1617 return mContext.getSystemService(AlarmManager.class);
1618 }
1619
1620 AnyMotionDetector getAnyMotionDetector(Handler handler, SensorManager sm,
1621 AnyMotionDetector.DeviceIdleCallback callback, float angleThreshold) {
1622 return new AnyMotionDetector(getPowerManager(), handler, sm, callback, angleThreshold);
1623 }
1624
1625 AppStateTracker getAppStateTracker(Context ctx, Looper looper) {
1626 return new AppStateTracker(ctx, looper);
1627 }
1628
1629 ConnectivityService getConnectivityService() {
Kweku Adams799858b2018-10-08 17:19:08 -07001630 if (mConnectivityService == null) {
1631 mConnectivityService = (ConnectivityService) ServiceManager.getService(
1632 Context.CONNECTIVITY_SERVICE);
1633 }
1634 return mConnectivityService;
Kweku Adams00e3a372018-09-28 16:57:09 -07001635 }
1636
Kweku Adamsa457f4e2018-10-03 15:56:06 -07001637 Constants getConstants(DeviceIdleController controller, Handler handler,
1638 ContentResolver resolver) {
Kweku Adams9da2bb92018-12-20 06:34:39 -08001639 if (mConstants == null) {
1640 mConstants = controller.new Constants(handler, resolver);
1641 }
1642 return mConstants;
Kweku Adamsa457f4e2018-10-03 15:56:06 -07001643 }
1644
Kweku Adams00e3a372018-09-28 16:57:09 -07001645 LocationManager getLocationManager() {
Kweku Adams799858b2018-10-08 17:19:08 -07001646 if (mLocationManager == null) {
1647 mLocationManager = mContext.getSystemService(LocationManager.class);
1648 }
1649 return mLocationManager;
Kweku Adams00e3a372018-09-28 16:57:09 -07001650 }
1651
Kweku Adamsa457f4e2018-10-03 15:56:06 -07001652 MyHandler getHandler(DeviceIdleController controller) {
1653 return controller.new MyHandler(BackgroundThread.getHandler().getLooper());
Kweku Adams00e3a372018-09-28 16:57:09 -07001654 }
1655
1656 PowerManager getPowerManager() {
1657 return mContext.getSystemService(PowerManager.class);
1658 }
Robin Lee876b88542018-11-13 17:22:24 +01001659
1660 SensorManager getSensorManager() {
1661 return mContext.getSystemService(SensorManager.class);
1662 }
1663
1664 ConstraintController getConstraintController(Handler handler, LocalService localService) {
1665 if (mContext.getPackageManager()
1666 .hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY)) {
1667 return new TvConstraintController(mContext, handler);
1668 }
1669 return null;
1670 }
1671
1672 boolean useMotionSensor() {
1673 return mContext.getResources().getBoolean(
1674 com.android.internal.R.bool.config_autoPowerModeUseMotionSensor);
1675 }
Kweku Adams00e3a372018-09-28 16:57:09 -07001676 }
1677
1678 private final Injector mInjector;
1679
Wale Ogunwale6767eae2018-05-03 15:52:51 -07001680 private ActivityTaskManagerInternal.ScreenObserver mScreenObserver =
1681 new ActivityTaskManagerInternal.ScreenObserver() {
Amith Yamasani396a10c2018-01-19 10:58:07 -08001682 @Override
1683 public void onAwakeStateChanged(boolean isAwake) { }
1684
1685 @Override
1686 public void onKeyguardStateChanged(boolean isShowing) {
1687 synchronized (DeviceIdleController.this) {
1688 DeviceIdleController.this.keyguardShowingLocked(isShowing);
1689 }
1690 }
1691 };
1692
Kweku Adams00e3a372018-09-28 16:57:09 -07001693 @VisibleForTesting DeviceIdleController(Context context, Injector injector) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001694 super(context);
Kweku Adams00e3a372018-09-28 16:57:09 -07001695 mInjector = injector;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001696 mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml"));
Kweku Adams00e3a372018-09-28 16:57:09 -07001697 mHandler = mInjector.getHandler(this);
1698 mAppStateTracker = mInjector.getAppStateTracker(context, FgThread.get().getLooper());
Makoto Onukie4918212018-02-06 11:30:15 -08001699 LocalServices.addService(AppStateTracker.class, mAppStateTracker);
Robin Lee876b88542018-11-13 17:22:24 +01001700 mUseMotionSensor = mInjector.useMotionSensor();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001701 }
1702
Kweku Adams00e3a372018-09-28 16:57:09 -07001703 public DeviceIdleController(Context context) {
1704 this(context, new Injector(context));
1705 }
1706
Christopher Tate42a386b2016-11-07 12:21:21 -08001707 boolean isAppOnWhitelistInternal(int appid) {
1708 synchronized (this) {
1709 return Arrays.binarySearch(mPowerSaveWhitelistAllAppIdArray, appid) >= 0;
1710 }
1711 }
1712
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001713 int[] getPowerSaveWhitelistUserAppIds() {
1714 synchronized (this) {
1715 return mPowerSaveWhitelistUserAppIdArray;
1716 }
1717 }
1718
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001719 private static File getSystemDir() {
1720 return new File(Environment.getDataDirectory(), "system");
1721 }
1722
1723 @Override
1724 public void onStart() {
1725 final PackageManager pm = getContext().getPackageManager();
1726
1727 synchronized (this) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08001728 mLightEnabled = mDeepEnabled = getContext().getResources().getBoolean(
Dianne Hackborn92617032015-06-19 15:32:19 -07001729 com.android.internal.R.bool.config_enableAutoPowerModes);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001730 SystemConfig sysConfig = SystemConfig.getInstance();
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001731 ArraySet<String> allowPowerExceptIdle = sysConfig.getAllowInPowerSaveExceptIdle();
1732 for (int i=0; i<allowPowerExceptIdle.size(); i++) {
1733 String pkg = allowPowerExceptIdle.valueAt(i);
1734 try {
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07001735 ApplicationInfo ai = pm.getApplicationInfo(pkg,
1736 PackageManager.MATCH_SYSTEM_ONLY);
1737 int appid = UserHandle.getAppId(ai.uid);
1738 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
1739 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001740 } catch (PackageManager.NameNotFoundException e) {
1741 }
1742 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001743 ArraySet<String> allowPower = sysConfig.getAllowInPowerSave();
1744 for (int i=0; i<allowPower.size(); i++) {
1745 String pkg = allowPower.valueAt(i);
1746 try {
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07001747 ApplicationInfo ai = pm.getApplicationInfo(pkg,
1748 PackageManager.MATCH_SYSTEM_ONLY);
1749 int appid = UserHandle.getAppId(ai.uid);
1750 // These apps are on both the whitelist-except-idle as well
1751 // as the full whitelist, so they apply in all cases.
1752 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
1753 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
1754 mPowerSaveWhitelistApps.put(ai.packageName, appid);
1755 mPowerSaveWhitelistSystemAppIds.put(appid, true);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001756 } catch (PackageManager.NameNotFoundException e) {
1757 }
1758 }
1759
Kweku Adamsa457f4e2018-10-03 15:56:06 -07001760 mConstants = mInjector.getConstants(this, mHandler, getContext().getContentResolver());
Adam Lesinski31c05d12015-06-09 17:34:04 -07001761
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001762 readConfigFileLocked();
1763 updateWhitelistAppIdsLocked();
1764
Dianne Hackborn88c41352016-04-07 15:18:58 -07001765 mNetworkConnected = true;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001766 mScreenOn = true;
Amith Yamasani396a10c2018-01-19 10:58:07 -08001767 mScreenLocked = false;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001768 // Start out assuming we are charging. If we aren't, we will at least get
1769 // a battery update the next time the level drops.
1770 mCharging = true;
1771 mState = STATE_ACTIVE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001772 mLightState = LIGHT_STATE_ACTIVE;
Adam Lesinski31c05d12015-06-09 17:34:04 -07001773 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001774 }
1775
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001776 mBinderService = new BinderService();
1777 publishBinderService(Context.DEVICE_IDLE_CONTROLLER, mBinderService);
Dianne Hackborna750a632015-06-16 17:18:23 -07001778 publishLocalService(LocalService.class, new LocalService());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001779 }
1780
1781 @Override
1782 public void onBootPhase(int phase) {
1783 if (phase == PHASE_SYSTEM_SERVICES_READY) {
1784 synchronized (this) {
Kweku Adams00e3a372018-09-28 16:57:09 -07001785 mAlarmManager = mInjector.getAlarmManager();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001786 mBatteryStats = BatteryStatsService.getService();
Dianne Hackborn85e35642017-01-12 15:10:57 -08001787 mLocalActivityManager = getLocalService(ActivityManagerInternal.class);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07001788 mLocalActivityTaskManager = getLocalService(ActivityTaskManagerInternal.class);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001789 mLocalPowerManager = getLocalService(PowerManagerInternal.class);
Kweku Adams00e3a372018-09-28 16:57:09 -07001790 mPowerManager = mInjector.getPowerManager();
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001791 mActiveIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
1792 "deviceidle_maint");
1793 mActiveIdleWakeLock.setReferenceCounted(false);
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001794 mGoingIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
1795 "deviceidle_going_idle");
1796 mGoingIdleWakeLock.setReferenceCounted(true);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001797 mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface(
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001798 ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07001799 mNetworkPolicyManagerInternal = getLocalService(NetworkPolicyManagerInternal.class);
Robin Lee876b88542018-11-13 17:22:24 +01001800 mSensorManager = mInjector.getSensorManager();
Robin Leec4d424c2018-12-07 15:09:13 +01001801
1802 if (mUseMotionSensor) {
1803 int sigMotionSensorId = getContext().getResources().getInteger(
1804 com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor);
1805 if (sigMotionSensorId > 0) {
1806 mMotionSensor = mSensorManager.getDefaultSensor(sigMotionSensorId, true);
1807 }
1808 if (mMotionSensor == null && getContext().getResources().getBoolean(
1809 com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) {
1810 mMotionSensor = mSensorManager.getDefaultSensor(
1811 Sensor.TYPE_WRIST_TILT_GESTURE, true);
1812 }
1813 if (mMotionSensor == null) {
1814 // As a last ditch, fall back to SMD.
1815 mMotionSensor = mSensorManager.getDefaultSensor(
1816 Sensor.TYPE_SIGNIFICANT_MOTION, true);
1817 }
Joe LaPenna23d681b2015-08-27 15:12:11 -07001818 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001819
Joe LaPenna23d681b2015-08-27 15:12:11 -07001820 if (getContext().getResources().getBoolean(
1821 com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) {
Joe LaPenna23d681b2015-08-27 15:12:11 -07001822 mLocationRequest = new LocationRequest()
1823 .setQuality(LocationRequest.ACCURACY_FINE)
1824 .setInterval(0)
1825 .setFastestInterval(0)
1826 .setNumUpdates(1);
1827 }
1828
Robin Lee876b88542018-11-13 17:22:24 +01001829 mConstraintController = mInjector.getConstraintController(
1830 mHandler, getLocalService(LocalService.class));
1831 if (mConstraintController != null) {
1832 mConstraintController.start();
1833 }
1834
Joe LaPenna23d681b2015-08-27 15:12:11 -07001835 float angleThreshold = getContext().getResources().getInteger(
1836 com.android.internal.R.integer.config_autoPowerModeThresholdAngle) / 100f;
Kweku Adams00e3a372018-09-28 16:57:09 -07001837 mAnyMotionDetector = mInjector.getAnyMotionDetector(mHandler, mSensorManager, this,
1838 angleThreshold);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001839
Makoto Onukie4918212018-02-06 11:30:15 -08001840 mAppStateTracker.onSystemServicesReady();
1841
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001842 mIdleIntent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001843 mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1844 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001845 mLightIdleIntent = new Intent(PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
1846 mLightIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1847 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001848
1849 IntentFilter filter = new IntentFilter();
1850 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001851 getContext().registerReceiver(mReceiver, filter);
Amith Yamasaniac59f75e2016-05-05 12:38:17 -07001852
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07001853 filter = new IntentFilter();
1854 filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
1855 filter.addDataScheme("package");
Amith Yamasaniac59f75e2016-05-05 12:38:17 -07001856 getContext().registerReceiver(mReceiver, filter);
1857
Dianne Hackborn88c41352016-04-07 15:18:58 -07001858 filter = new IntentFilter();
1859 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07001860 getContext().registerReceiver(mReceiver, filter);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001861
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -07001862 filter = new IntentFilter();
1863 filter.addAction(Intent.ACTION_SCREEN_OFF);
1864 filter.addAction(Intent.ACTION_SCREEN_ON);
1865 getContext().registerReceiver(mInteractivityReceiver, filter);
1866
Makoto Onukiaf8ff4f2018-06-04 14:44:19 -07001867 mLocalActivityManager.setDeviceIdleWhitelist(
1868 mPowerSaveWhitelistAllAppIdArray, mPowerSaveWhitelistExceptIdleAppIdArray);
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001869 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -07001870
Kweku Adamsb396ccf2018-09-17 16:37:15 -07001871 mLocalPowerManager.registerLowPowerModeObserver(ServiceType.QUICK_DOZE,
1872 state -> {
1873 synchronized (DeviceIdleController.this) {
1874 updateQuickDozeFlagLocked(state.batterySaverEnabled);
1875 }
1876 });
1877 updateQuickDozeFlagLocked(
1878 mLocalPowerManager.getLowPowerState(
1879 ServiceType.QUICK_DOZE).batterySaverEnabled);
1880
Wale Ogunwale6767eae2018-05-03 15:52:51 -07001881 mLocalActivityTaskManager.registerScreenObserver(mScreenObserver);
Amith Yamasani396a10c2018-01-19 10:58:07 -08001882
Suprabh Shukla5bf49812018-05-24 18:38:50 -07001883 passWhiteListsToForceAppStandbyTrackerLocked();
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -07001884 updateInteractivityLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001885 }
Dianne Hackborn4cb96ca2016-05-17 13:55:29 -07001886 updateConnectivityState(null);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001887 }
1888 }
1889
Robin Lee876b88542018-11-13 17:22:24 +01001890 @VisibleForTesting
1891 boolean hasMotionSensor() {
1892 return mUseMotionSensor && mMotionSensor != null;
1893 }
1894
1895 private void registerDeviceIdleConstraintInternal(IDeviceIdleConstraint constraint,
1896 final String name, final int type) {
1897 final int minState;
1898 switch (type) {
1899 case IDeviceIdleConstraint.ACTIVE:
1900 minState = STATE_ACTIVE;
1901 break;
1902 case IDeviceIdleConstraint.SENSING_OR_ABOVE:
1903 minState = STATE_SENSING;
1904 break;
1905 default:
1906 Slog.wtf(TAG, "Registering device-idle constraint with invalid type: " + type);
1907 return;
1908 }
1909 synchronized (this) {
1910 if (mConstraints.containsKey(constraint)) {
1911 Slog.e(TAG, "Re-registering device-idle constraint: " + constraint + ".");
1912 return;
1913 }
1914 DeviceIdleConstraintTracker tracker = new DeviceIdleConstraintTracker(name, minState);
1915 mConstraints.put(constraint, tracker);
1916 updateActiveConstraintsLocked();
1917 }
1918 }
1919
1920 private void unregisterDeviceIdleConstraintInternal(IDeviceIdleConstraint constraint) {
1921 synchronized (this) {
1922 // Artifically force the constraint to inactive to unblock anything waiting for it.
1923 onConstraintStateChangedLocked(constraint, /* active= */ false);
1924
1925 // Let the constraint know that we are not listening to it any more.
1926 setConstraintMonitoringLocked(constraint, /* monitoring= */ false);
1927 mConstraints.remove(constraint);
1928 }
1929 }
1930
1931 @GuardedBy("this")
1932 private void onConstraintStateChangedLocked(IDeviceIdleConstraint constraint, boolean active) {
1933 DeviceIdleConstraintTracker tracker = mConstraints.get(constraint);
1934 if (tracker == null) {
1935 Slog.e(TAG, "device-idle constraint " + constraint + " has not been registered.");
1936 return;
1937 }
1938 if (active != tracker.active && tracker.monitoring) {
1939 tracker.active = active;
1940 mNumBlockingConstraints += (tracker.active ? +1 : -1);
1941 if (mNumBlockingConstraints == 0) {
1942 if (mState == STATE_ACTIVE) {
1943 becomeInactiveIfAppropriateLocked();
1944 } else if (mNextAlarmTime == 0 || mNextAlarmTime < SystemClock.elapsedRealtime()) {
1945 stepIdleStateLocked("s:" + tracker.name);
1946 }
1947 }
1948 }
1949 }
1950
1951 @GuardedBy("this")
1952 private void setConstraintMonitoringLocked(IDeviceIdleConstraint constraint, boolean monitor) {
1953 DeviceIdleConstraintTracker tracker = mConstraints.get(constraint);
1954 if (tracker.monitoring != monitor) {
1955 tracker.monitoring = monitor;
1956 updateActiveConstraintsLocked();
1957 // We send the callback on a separate thread instead of just relying on oneway as
1958 // the client could be in the system server with us and cause re-entry problems.
1959 mHandler.obtainMessage(MSG_SEND_CONSTRAINT_MONITORING,
1960 /* monitoring= */ monitor ? 1 : 0,
1961 /* <not used>= */ -1,
1962 /* constraint= */ constraint).sendToTarget();
1963 }
1964 }
1965
1966 @GuardedBy("this")
1967 private void updateActiveConstraintsLocked() {
1968 mNumBlockingConstraints = 0;
1969 for (int i = 0; i < mConstraints.size(); i++) {
1970 final IDeviceIdleConstraint constraint = mConstraints.keyAt(i);
1971 final DeviceIdleConstraintTracker tracker = mConstraints.valueAt(i);
1972 final boolean monitoring = (tracker.minState == mState);
1973 if (monitoring != tracker.monitoring) {
1974 setConstraintMonitoringLocked(constraint, monitoring);
1975 tracker.active = monitoring;
1976 }
1977 if (tracker.monitoring && tracker.active) {
1978 mNumBlockingConstraints++;
1979 }
1980 }
1981 }
1982
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001983 public boolean addPowerSaveWhitelistAppInternal(String name) {
1984 synchronized (this) {
1985 try {
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07001986 ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name,
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -07001987 PackageManager.MATCH_ANY_USER);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001988 if (mPowerSaveWhitelistUserApps.put(name, UserHandle.getAppId(ai.uid)) == null) {
1989 reportPowerSaveWhitelistChangedLocked();
1990 updateWhitelistAppIdsLocked();
1991 writeConfigFileLocked();
1992 }
1993 return true;
1994 } catch (PackageManager.NameNotFoundException e) {
1995 return false;
1996 }
1997 }
1998 }
1999
2000 public boolean removePowerSaveWhitelistAppInternal(String name) {
2001 synchronized (this) {
2002 if (mPowerSaveWhitelistUserApps.remove(name) != null) {
2003 reportPowerSaveWhitelistChangedLocked();
2004 updateWhitelistAppIdsLocked();
2005 writeConfigFileLocked();
2006 return true;
2007 }
2008 }
2009 return false;
2010 }
2011
Felipe Lemef8a46232016-02-10 13:51:54 -08002012 public boolean getPowerSaveWhitelistAppInternal(String name) {
2013 synchronized (this) {
2014 return mPowerSaveWhitelistUserApps.containsKey(name);
2015 }
2016 }
2017
Suprabh Shukla08105642017-09-26 14:45:30 -07002018 void resetSystemPowerWhitelistInternal() {
2019 synchronized (this) {
2020 mPowerSaveWhitelistApps.putAll(mRemovedFromSystemWhitelistApps);
2021 mRemovedFromSystemWhitelistApps.clear();
2022 reportPowerSaveWhitelistChangedLocked();
2023 updateWhitelistAppIdsLocked();
2024 writeConfigFileLocked();
2025 }
2026 }
2027
2028 public boolean restoreSystemPowerWhitelistAppInternal(String name) {
2029 synchronized (this) {
2030 if (!mRemovedFromSystemWhitelistApps.containsKey(name)) {
2031 return false;
2032 }
2033 mPowerSaveWhitelistApps.put(name, mRemovedFromSystemWhitelistApps.remove(name));
2034 reportPowerSaveWhitelistChangedLocked();
2035 updateWhitelistAppIdsLocked();
2036 writeConfigFileLocked();
2037 return true;
2038 }
2039 }
2040
2041 public boolean removeSystemPowerWhitelistAppInternal(String name) {
2042 synchronized (this) {
2043 if (!mPowerSaveWhitelistApps.containsKey(name)) {
2044 return false;
2045 }
2046 mRemovedFromSystemWhitelistApps.put(name, mPowerSaveWhitelistApps.remove(name));
2047 reportPowerSaveWhitelistChangedLocked();
2048 updateWhitelistAppIdsLocked();
2049 writeConfigFileLocked();
2050 return true;
2051 }
2052 }
2053
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07002054 public boolean addPowerSaveWhitelistExceptIdleInternal(String name) {
2055 synchronized (this) {
2056 try {
2057 final ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name,
2058 PackageManager.MATCH_ANY_USER);
2059 if (mPowerSaveWhitelistAppsExceptIdle.put(name, UserHandle.getAppId(ai.uid))
2060 == null) {
2061 mPowerSaveWhitelistUserAppsExceptIdle.add(name);
2062 reportPowerSaveWhitelistChangedLocked();
2063 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(
2064 mPowerSaveWhitelistAppsExceptIdle, mPowerSaveWhitelistUserApps,
2065 mPowerSaveWhitelistExceptIdleAppIds);
Makoto Onuki71755c92018-01-16 14:15:44 -08002066
Suprabh Shukla5bf49812018-05-24 18:38:50 -07002067 passWhiteListsToForceAppStandbyTrackerLocked();
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07002068 }
2069 return true;
2070 } catch (PackageManager.NameNotFoundException e) {
2071 return false;
2072 }
2073 }
2074 }
2075
2076 public void resetPowerSaveWhitelistExceptIdleInternal() {
2077 synchronized (this) {
2078 if (mPowerSaveWhitelistAppsExceptIdle.removeAll(
2079 mPowerSaveWhitelistUserAppsExceptIdle)) {
2080 reportPowerSaveWhitelistChangedLocked();
2081 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(
2082 mPowerSaveWhitelistAppsExceptIdle, mPowerSaveWhitelistUserApps,
2083 mPowerSaveWhitelistExceptIdleAppIds);
2084 mPowerSaveWhitelistUserAppsExceptIdle.clear();
Makoto Onuki71755c92018-01-16 14:15:44 -08002085
Suprabh Shukla5bf49812018-05-24 18:38:50 -07002086 passWhiteListsToForceAppStandbyTrackerLocked();
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07002087 }
2088 }
2089 }
2090
2091 public boolean getPowerSaveWhitelistExceptIdleInternal(String name) {
2092 synchronized (this) {
2093 return mPowerSaveWhitelistAppsExceptIdle.containsKey(name);
2094 }
2095 }
2096
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002097 public String[] getSystemPowerWhitelistExceptIdleInternal() {
2098 synchronized (this) {
2099 int size = mPowerSaveWhitelistAppsExceptIdle.size();
2100 String[] apps = new String[size];
2101 for (int i = 0; i < size; i++) {
2102 apps[i] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i);
2103 }
2104 return apps;
2105 }
2106 }
2107
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002108 public String[] getSystemPowerWhitelistInternal() {
2109 synchronized (this) {
2110 int size = mPowerSaveWhitelistApps.size();
2111 String[] apps = new String[size];
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002112 for (int i = 0; i < size; i++) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002113 apps[i] = mPowerSaveWhitelistApps.keyAt(i);
2114 }
2115 return apps;
2116 }
2117 }
2118
Suprabh Shukla08105642017-09-26 14:45:30 -07002119 public String[] getRemovedSystemPowerWhitelistAppsInternal() {
2120 synchronized (this) {
2121 int size = mRemovedFromSystemWhitelistApps.size();
2122 final String[] apps = new String[size];
2123 for (int i = 0; i < size; i++) {
2124 apps[i] = mRemovedFromSystemWhitelistApps.keyAt(i);
2125 }
2126 return apps;
2127 }
2128 }
2129
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002130 public String[] getUserPowerWhitelistInternal() {
2131 synchronized (this) {
2132 int size = mPowerSaveWhitelistUserApps.size();
2133 String[] apps = new String[size];
2134 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
2135 apps[i] = mPowerSaveWhitelistUserApps.keyAt(i);
2136 }
2137 return apps;
2138 }
2139 }
2140
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002141 public String[] getFullPowerWhitelistExceptIdleInternal() {
2142 synchronized (this) {
2143 int size = mPowerSaveWhitelistAppsExceptIdle.size() + mPowerSaveWhitelistUserApps.size();
2144 String[] apps = new String[size];
2145 int cur = 0;
2146 for (int i = 0; i < mPowerSaveWhitelistAppsExceptIdle.size(); i++) {
2147 apps[cur] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i);
2148 cur++;
2149 }
2150 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
2151 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i);
2152 cur++;
2153 }
2154 return apps;
2155 }
2156 }
2157
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002158 public String[] getFullPowerWhitelistInternal() {
2159 synchronized (this) {
2160 int size = mPowerSaveWhitelistApps.size() + mPowerSaveWhitelistUserApps.size();
2161 String[] apps = new String[size];
2162 int cur = 0;
2163 for (int i = 0; i < mPowerSaveWhitelistApps.size(); i++) {
2164 apps[cur] = mPowerSaveWhitelistApps.keyAt(i);
2165 cur++;
2166 }
2167 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
2168 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i);
2169 cur++;
2170 }
2171 return apps;
2172 }
2173 }
2174
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002175 public boolean isPowerSaveWhitelistExceptIdleAppInternal(String packageName) {
2176 synchronized (this) {
2177 return mPowerSaveWhitelistAppsExceptIdle.containsKey(packageName)
2178 || mPowerSaveWhitelistUserApps.containsKey(packageName);
2179 }
2180 }
2181
Amith Yamasani06bf8242015-05-08 16:36:21 -07002182 public boolean isPowerSaveWhitelistAppInternal(String packageName) {
2183 synchronized (this) {
2184 return mPowerSaveWhitelistApps.containsKey(packageName)
2185 || mPowerSaveWhitelistUserApps.containsKey(packageName);
2186 }
2187 }
2188
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002189 public int[] getAppIdWhitelistExceptIdleInternal() {
2190 synchronized (this) {
2191 return mPowerSaveWhitelistExceptIdleAppIdArray;
2192 }
2193 }
2194
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002195 public int[] getAppIdWhitelistInternal() {
2196 synchronized (this) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002197 return mPowerSaveWhitelistAllAppIdArray;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002198 }
2199 }
2200
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002201 public int[] getAppIdUserWhitelistInternal() {
2202 synchronized (this) {
2203 return mPowerSaveWhitelistUserAppIdArray;
2204 }
2205 }
2206
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002207 public int[] getAppIdTempWhitelistInternal() {
2208 synchronized (this) {
2209 return mTempWhitelistAppIdArray;
2210 }
2211 }
2212
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002213 void addPowerSaveTempWhitelistAppChecked(String packageName, long duration,
2214 int userId, String reason) throws RemoteException {
2215 getContext().enforceCallingPermission(
2216 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
2217 "No permission to change device idle whitelist");
2218 final int callingUid = Binder.getCallingUid();
Sudheer Shankadc589ac2016-11-10 15:30:17 -08002219 userId = ActivityManager.getService().handleIncomingUser(
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002220 Binder.getCallingPid(),
2221 callingUid,
2222 userId,
2223 /*allowAll=*/ false,
2224 /*requireFull=*/ false,
2225 "addPowerSaveTempWhitelistApp", null);
2226 final long token = Binder.clearCallingIdentity();
2227 try {
2228 addPowerSaveTempWhitelistAppInternal(callingUid,
2229 packageName, duration, userId, true, reason);
2230 } finally {
2231 Binder.restoreCallingIdentity(token);
2232 }
2233 }
2234
Sudheer Shanka326b3112017-11-27 14:40:57 -08002235 void removePowerSaveTempWhitelistAppChecked(String packageName, int userId)
2236 throws RemoteException {
2237 getContext().enforceCallingPermission(
2238 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
2239 "No permission to change device idle whitelist");
2240 final int callingUid = Binder.getCallingUid();
2241 userId = ActivityManager.getService().handleIncomingUser(
2242 Binder.getCallingPid(),
2243 callingUid,
2244 userId,
2245 /*allowAll=*/ false,
2246 /*requireFull=*/ false,
2247 "removePowerSaveTempWhitelistApp", null);
2248 final long token = Binder.clearCallingIdentity();
2249 try {
2250 removePowerSaveTempWhitelistAppInternal(packageName, userId);
2251 } finally {
2252 Binder.restoreCallingIdentity(token);
2253 }
2254 }
2255
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002256 /**
2257 * Adds an app to the temporary whitelist and resets the endTime for granting the
2258 * app an exemption to access network and acquire wakelocks.
2259 */
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002260 void addPowerSaveTempWhitelistAppInternal(int callingUid, String packageName,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002261 long duration, int userId, boolean sync, String reason) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002262 try {
Jeff Sharkeye06b4d12016-01-06 14:51:50 -07002263 int uid = getContext().getPackageManager().getPackageUidAsUser(packageName, userId);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002264 int appId = UserHandle.getAppId(uid);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002265 addPowerSaveTempWhitelistAppDirectInternal(callingUid, appId, duration, sync, reason);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002266 } catch (NameNotFoundException e) {
2267 }
2268 }
2269
Dianne Hackborna750a632015-06-16 17:18:23 -07002270 /**
2271 * Adds an app to the temporary whitelist and resets the endTime for granting the
2272 * app an exemption to access network and acquire wakelocks.
2273 */
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002274 void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int appId,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002275 long duration, boolean sync, String reason) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002276 final long timeNow = SystemClock.elapsedRealtime();
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07002277 boolean informWhitelistChanged = false;
Dianne Hackborna750a632015-06-16 17:18:23 -07002278 synchronized (this) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002279 int callingAppId = UserHandle.getAppId(callingUid);
2280 if (callingAppId >= Process.FIRST_APPLICATION_UID) {
2281 if (!mPowerSaveWhitelistSystemAppIds.get(callingAppId)) {
2282 throw new SecurityException("Calling app " + UserHandle.formatUid(callingUid)
2283 + " is not on whitelist");
2284 }
2285 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002286 duration = Math.min(duration, mConstants.MAX_TEMP_APP_WHITELIST_DURATION);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002287 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId);
2288 final boolean newEntry = entry == null;
Dianne Hackborna750a632015-06-16 17:18:23 -07002289 // Set the new end time
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002290 if (newEntry) {
2291 entry = new Pair<>(new MutableLong(0), reason);
2292 mTempWhitelistAppIdEndTimes.put(appId, entry);
2293 }
2294 entry.first.value = timeNow + duration;
Dianne Hackborna750a632015-06-16 17:18:23 -07002295 if (DEBUG) {
Felipe Lemea1b79bf2016-05-24 13:06:54 -07002296 Slog.d(TAG, "Adding AppId " + appId + " to temp whitelist. New entry: " + newEntry);
Dianne Hackborna750a632015-06-16 17:18:23 -07002297 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002298 if (newEntry) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002299 // No pending timeout for the app id, post a delayed message
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002300 try {
2301 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_START,
2302 reason, appId);
2303 } catch (RemoteException e) {
2304 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002305 postTempActiveTimeoutMessage(appId, duration);
Dianne Hackborn85e35642017-01-12 15:10:57 -08002306 updateTempWhitelistAppIdsLocked(appId, true);
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07002307 if (sync) {
2308 informWhitelistChanged = true;
2309 } else {
2310 mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED, appId, 1)
2311 .sendToTarget();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002312 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002313 reportTempWhitelistChangedLocked();
2314 }
2315 }
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07002316 if (informWhitelistChanged) {
2317 mNetworkPolicyManagerInternal.onTempPowerSaveWhitelistChange(appId, true);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002318 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002319 }
2320
Sudheer Shanka326b3112017-11-27 14:40:57 -08002321 /**
2322 * Removes an app from the temporary whitelist and notifies the observers.
2323 */
2324 private void removePowerSaveTempWhitelistAppInternal(String packageName, int userId) {
2325 try {
2326 final int uid = getContext().getPackageManager().getPackageUidAsUser(
2327 packageName, userId);
2328 final int appId = UserHandle.getAppId(uid);
2329 removePowerSaveTempWhitelistAppDirectInternal(appId);
2330 } catch (NameNotFoundException e) {
2331 }
2332 }
2333
2334 private void removePowerSaveTempWhitelistAppDirectInternal(int appId) {
2335 synchronized (this) {
2336 final int idx = mTempWhitelistAppIdEndTimes.indexOfKey(appId);
2337 if (idx < 0) {
2338 // Nothing else to do
2339 return;
2340 }
2341 final String reason = mTempWhitelistAppIdEndTimes.valueAt(idx).second;
2342 mTempWhitelistAppIdEndTimes.removeAt(idx);
2343 onAppRemovedFromTempWhitelistLocked(appId, reason);
2344 }
2345 }
2346
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002347 private void postTempActiveTimeoutMessage(int uid, long delay) {
Felipe Lemea1b79bf2016-05-24 13:06:54 -07002348 if (DEBUG) {
2349 Slog.d(TAG, "postTempActiveTimeoutMessage: uid=" + uid + ", delay=" + delay);
2350 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002351 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, uid, 0),
2352 delay);
2353 }
2354
2355 void checkTempAppWhitelistTimeout(int uid) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002356 final long timeNow = SystemClock.elapsedRealtime();
Felipe Lemea1b79bf2016-05-24 13:06:54 -07002357 if (DEBUG) {
2358 Slog.d(TAG, "checkTempAppWhitelistTimeout: uid=" + uid + ", timeNow=" + timeNow);
2359 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002360 synchronized (this) {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002361 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(uid);
2362 if (entry == null) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002363 // Nothing to do
2364 return;
2365 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002366 if (timeNow >= entry.first.value) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002367 mTempWhitelistAppIdEndTimes.delete(uid);
Sudheer Shanka326b3112017-11-27 14:40:57 -08002368 onAppRemovedFromTempWhitelistLocked(uid, entry.second);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002369 } else {
2370 // Need more time
Felipe Lemea1b79bf2016-05-24 13:06:54 -07002371 if (DEBUG) {
2372 Slog.d(TAG, "Time to remove UID " + uid + ": " + entry.first.value);
2373 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002374 postTempActiveTimeoutMessage(uid, entry.first.value - timeNow);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002375 }
2376 }
2377 }
2378
Sudheer Shanka326b3112017-11-27 14:40:57 -08002379 @GuardedBy("this")
2380 private void onAppRemovedFromTempWhitelistLocked(int appId, String reason) {
2381 if (DEBUG) {
2382 Slog.d(TAG, "Removing appId " + appId + " from temp whitelist");
2383 }
2384 updateTempWhitelistAppIdsLocked(appId, false);
2385 mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED, appId, 0)
2386 .sendToTarget();
2387 reportTempWhitelistChangedLocked();
2388 try {
2389 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH,
2390 reason, appId);
2391 } catch (RemoteException e) {
2392 }
2393 }
2394
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002395 public void exitIdleInternal(String reason) {
2396 synchronized (this) {
2397 becomeActiveLocked(reason, Binder.getCallingUid());
2398 }
2399 }
2400
Kweku Adams799858b2018-10-08 17:19:08 -07002401 @VisibleForTesting
2402 boolean isNetworkConnected() {
2403 synchronized (this) {
2404 return mNetworkConnected;
2405 }
2406 }
2407
Dianne Hackborn4cb96ca2016-05-17 13:55:29 -07002408 void updateConnectivityState(Intent connIntent) {
2409 ConnectivityService cm;
2410 synchronized (this) {
Kweku Adams799858b2018-10-08 17:19:08 -07002411 cm = mInjector.getConnectivityService();
Dianne Hackborn4cb96ca2016-05-17 13:55:29 -07002412 }
2413 if (cm == null) {
2414 return;
2415 }
2416 // Note: can't call out to ConnectivityService with our lock held.
2417 NetworkInfo ni = cm.getActiveNetworkInfo();
2418 synchronized (this) {
Dianne Hackborn88c41352016-04-07 15:18:58 -07002419 boolean conn;
2420 if (ni == null) {
2421 conn = false;
2422 } else {
2423 if (connIntent == null) {
2424 conn = ni.isConnected();
2425 } else {
2426 final int networkType =
2427 connIntent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE,
2428 ConnectivityManager.TYPE_NONE);
2429 if (ni.getType() != networkType) {
2430 return;
2431 }
2432 conn = !connIntent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,
2433 false);
2434 }
2435 }
2436 if (conn != mNetworkConnected) {
2437 mNetworkConnected = conn;
2438 if (conn && mLightState == LIGHT_STATE_WAITING_FOR_NETWORK) {
2439 stepLightIdleStateLocked("network");
2440 }
2441 }
2442 }
2443 }
2444
Kweku Adams00e3a372018-09-28 16:57:09 -07002445 @VisibleForTesting
2446 boolean isScreenOn() {
Kweku Adamsb396ccf2018-09-17 16:37:15 -07002447 synchronized (this) {
2448 return mScreenOn;
2449 }
Kweku Adams00e3a372018-09-28 16:57:09 -07002450 }
2451
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -07002452 void updateInteractivityLocked() {
2453 // The interactivity state from the power manager tells us whether the display is
2454 // in a state that we need to keep things running so they will update at a normal
2455 // frequency.
2456 boolean screenOn = mPowerManager.isInteractive();
2457 if (DEBUG) Slog.d(TAG, "updateInteractivityLocked: screenOn=" + screenOn);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002458 if (!screenOn && mScreenOn) {
2459 mScreenOn = false;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002460 if (!mForceIdle) {
2461 becomeInactiveIfAppropriateLocked();
2462 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002463 } else if (screenOn) {
2464 mScreenOn = true;
Amith Yamasani396a10c2018-01-19 10:58:07 -08002465 if (!mForceIdle && (!mScreenLocked || !mConstants.WAIT_FOR_UNLOCK)) {
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002466 becomeActiveLocked("screen", Process.myUid());
2467 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002468 }
2469 }
2470
Kweku Adams00e3a372018-09-28 16:57:09 -07002471 @VisibleForTesting
2472 boolean isCharging() {
Kweku Adamsb396ccf2018-09-17 16:37:15 -07002473 synchronized (this) {
2474 return mCharging;
2475 }
Kweku Adams00e3a372018-09-28 16:57:09 -07002476 }
2477
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002478 void updateChargingLocked(boolean charging) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002479 if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002480 if (!charging && mCharging) {
2481 mCharging = false;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002482 if (!mForceIdle) {
2483 becomeInactiveIfAppropriateLocked();
2484 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002485 } else if (charging) {
2486 mCharging = charging;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002487 if (!mForceIdle) {
2488 becomeActiveLocked("charging", Process.myUid());
2489 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002490 }
2491 }
2492
Kweku Adamsb396ccf2018-09-17 16:37:15 -07002493 @VisibleForTesting
2494 boolean isQuickDozeEnabled() {
2495 synchronized (this) {
2496 return mQuickDozeActivated;
2497 }
2498 }
2499
2500 /** Updates the quick doze flag and enters deep doze if appropriate. */
2501 @VisibleForTesting
2502 void updateQuickDozeFlagLocked(boolean enabled) {
2503 if (DEBUG) Slog.i(TAG, "updateQuickDozeFlagLocked: enabled=" + enabled);
2504 mQuickDozeActivated = enabled;
2505 if (enabled) {
2506 // If Quick Doze is enabled, see if we should go straight into it.
2507 becomeInactiveIfAppropriateLocked();
2508 }
2509 // Going from Deep Doze to Light Idle (if quick doze becomes disabled) is tricky and
2510 // probably not worth the overhead, so leave in deep doze if that's the case until the
2511 // next natural time to come out of it.
2512 }
2513
Amith Yamasani396a10c2018-01-19 10:58:07 -08002514 void keyguardShowingLocked(boolean showing) {
2515 if (DEBUG) Slog.i(TAG, "keyguardShowing=" + showing);
2516 if (mScreenLocked != showing) {
2517 mScreenLocked = showing;
2518 if (mScreenOn && !mForceIdle && !mScreenLocked) {
2519 becomeActiveLocked("unlocked", Process.myUid());
2520 }
2521 }
2522 }
2523
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002524 void scheduleReportActiveLocked(String activeReason, int activeUid) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002525 Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid, 0, activeReason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002526 mHandler.sendMessage(msg);
2527 }
2528
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002529 void becomeActiveLocked(String activeReason, int activeUid) {
2530 if (DEBUG) Slog.i(TAG, "becomeActiveLocked, reason = " + activeReason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002531 if (mState != STATE_ACTIVE || mLightState != STATE_ACTIVE) {
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002532 EventLogTags.writeDeviceIdle(STATE_ACTIVE, activeReason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002533 EventLogTags.writeDeviceIdleLight(LIGHT_STATE_ACTIVE, activeReason);
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002534 scheduleReportActiveLocked(activeReason, activeUid);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002535 mState = STATE_ACTIVE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002536 mLightState = LIGHT_STATE_ACTIVE;
Adam Lesinski31c05d12015-06-09 17:34:04 -07002537 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002538 mCurIdleBudget = 0;
2539 mMaintenanceStartTime = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002540 resetIdleManagementLocked();
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002541 resetLightIdleManagementLocked();
Amith Yamasaniac6517a2018-04-23 12:19:34 -07002542 addEvent(EVENT_NORMAL, activeReason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002543 }
2544 }
2545
Kweku Adams00e3a372018-09-28 16:57:09 -07002546 /** Must only be used in tests. */
2547 @VisibleForTesting
2548 void setDeepEnabledForTest(boolean enabled) {
Kweku Adams799858b2018-10-08 17:19:08 -07002549 synchronized (this) {
2550 mDeepEnabled = enabled;
2551 }
Kweku Adams00e3a372018-09-28 16:57:09 -07002552 }
2553
2554 /** Must only be used in tests. */
2555 @VisibleForTesting
2556 void setLightEnabledForTest(boolean enabled) {
Kweku Adams799858b2018-10-08 17:19:08 -07002557 synchronized (this) {
2558 mLightEnabled = enabled;
2559 }
Kweku Adams00e3a372018-09-28 16:57:09 -07002560 }
2561
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002562 void becomeInactiveIfAppropriateLocked() {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002563 if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()");
Dianne Hackbornb6843652016-02-22 12:20:13 -08002564 if ((!mScreenOn && !mCharging) || mForceIdle) {
Kweku Adamsb396ccf2018-09-17 16:37:15 -07002565 // Become inactive and determine if we will ultimately go idle.
2566 if (mDeepEnabled) {
2567 if (mQuickDozeActivated) {
2568 if (mState == STATE_QUICK_DOZE_DELAY || mState == STATE_IDLE
2569 || mState == STATE_IDLE_MAINTENANCE) {
2570 // Already "idling". Don't want to restart the process.
2571 // mLightState can't be LIGHT_STATE_ACTIVE if mState is any of these 3
2572 // values, so returning here is safe.
2573 return;
2574 }
2575 if (DEBUG) {
2576 Slog.d(TAG, "Moved from "
2577 + stateToString(mState) + " to STATE_QUICK_DOZE_DELAY");
2578 }
2579 mState = STATE_QUICK_DOZE_DELAY;
2580 // Make sure any motion sensing or locating is stopped.
2581 resetIdleManagementLocked();
2582 // Wait a small amount of time in case something (eg: background service from
2583 // recently closed app) needs to finish running.
2584 scheduleAlarmLocked(mConstants.QUICK_DOZE_DELAY_TIMEOUT, false);
2585 EventLogTags.writeDeviceIdle(mState, "no activity");
2586 } else if (mState == STATE_ACTIVE) {
2587 mState = STATE_INACTIVE;
2588 if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE");
2589 resetIdleManagementLocked();
2590 scheduleAlarmLocked(mInactiveTimeout, false);
2591 EventLogTags.writeDeviceIdle(mState, "no activity");
2592 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002593 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08002594 if (mLightState == LIGHT_STATE_ACTIVE && mLightEnabled) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002595 mLightState = LIGHT_STATE_INACTIVE;
2596 if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE");
2597 resetLightIdleManagementLocked();
Dianne Hackborn953fc942016-03-29 15:36:24 -07002598 scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002599 EventLogTags.writeDeviceIdleLight(mLightState, "no activity");
2600 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002601 }
2602 }
2603
Kweku Adams00e3a372018-09-28 16:57:09 -07002604 private void resetIdleManagementLocked() {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002605 mNextIdlePendingDelay = 0;
2606 mNextIdleDelay = 0;
Dianne Hackborn953fc942016-03-29 15:36:24 -07002607 mNextLightIdleDelay = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002608 cancelAlarmLocked();
Kevin Gabayan92f15e62016-04-04 17:52:22 -07002609 cancelSensingTimeoutAlarmLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002610 cancelLocatingLocked();
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002611 stopMonitoringMotionLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002612 mAnyMotionDetector.stop();
Robin Lee876b88542018-11-13 17:22:24 +01002613 updateActiveConstraintsLocked();
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002614 }
2615
Kweku Adams00e3a372018-09-28 16:57:09 -07002616 private void resetLightIdleManagementLocked() {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002617 cancelLightAlarmLocked();
2618 }
2619
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002620 void exitForceIdleLocked() {
2621 if (mForceIdle) {
2622 mForceIdle = false;
2623 if (mScreenOn || mCharging) {
Dianne Hackborn88c41352016-04-07 15:18:58 -07002624 becomeActiveLocked("exit-force", Process.myUid());
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002625 }
2626 }
2627 }
2628
Kweku Adamsa457f4e2018-10-03 15:56:06 -07002629 /**
2630 * Must only be used in tests.
2631 *
2632 * This sets the state value directly and thus doesn't trigger any behavioral changes.
2633 */
2634 @VisibleForTesting
2635 void setLightStateForTest(int lightState) {
Kweku Adams799858b2018-10-08 17:19:08 -07002636 synchronized (this) {
2637 mLightState = lightState;
2638 }
Kweku Adamsa457f4e2018-10-03 15:56:06 -07002639 }
2640
Kweku Adams00e3a372018-09-28 16:57:09 -07002641 @VisibleForTesting
2642 int getLightState() {
2643 return mLightState;
2644 }
2645
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002646 void stepLightIdleStateLocked(String reason) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002647 if (mLightState == LIGHT_STATE_OVERRIDE) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08002648 // If we are already in deep device idle mode, then
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002649 // there is nothing left to do for light mode.
2650 return;
2651 }
2652
2653 if (DEBUG) Slog.d(TAG, "stepLightIdleStateLocked: mLightState=" + mLightState);
2654 EventLogTags.writeDeviceIdleLightStep();
2655
2656 switch (mLightState) {
2657 case LIGHT_STATE_INACTIVE:
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002658 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
Dianne Hackborn953fc942016-03-29 15:36:24 -07002659 // Reset the upcoming idle delays.
2660 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002661 mMaintenanceStartTime = 0;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002662 if (!isOpsInactiveLocked()) {
2663 // We have some active ops going on... give them a chance to finish
2664 // before going in to our first idle.
2665 mLightState = LIGHT_STATE_PRE_IDLE;
2666 EventLogTags.writeDeviceIdleLight(mLightState, reason);
2667 scheduleLightAlarmLocked(mConstants.LIGHT_PRE_IDLE_TIMEOUT);
2668 break;
2669 }
2670 // Nothing active, fall through to immediately idle.
2671 case LIGHT_STATE_PRE_IDLE:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002672 case LIGHT_STATE_IDLE_MAINTENANCE:
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002673 if (mMaintenanceStartTime != 0) {
2674 long duration = SystemClock.elapsedRealtime() - mMaintenanceStartTime;
2675 if (duration < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
2676 // We didn't use up all of our minimum budget; add this to the reserve.
2677 mCurIdleBudget += (mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET-duration);
2678 } else {
2679 // We used more than our minimum budget; this comes out of the reserve.
2680 mCurIdleBudget -= (duration-mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET);
2681 }
2682 }
2683 mMaintenanceStartTime = 0;
Dianne Hackborn953fc942016-03-29 15:36:24 -07002684 scheduleLightAlarmLocked(mNextLightIdleDelay);
2685 mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT,
2686 (long)(mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR));
2687 if (mNextLightIdleDelay < mConstants.LIGHT_IDLE_TIMEOUT) {
2688 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT;
2689 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002690 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_STATE_IDLE.");
2691 mLightState = LIGHT_STATE_IDLE;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002692 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Amith Yamasaniac6517a2018-04-23 12:19:34 -07002693 addEvent(EVENT_LIGHT_IDLE, null);
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08002694 mGoingIdleWakeLock.acquire();
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002695 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON_LIGHT);
2696 break;
2697 case LIGHT_STATE_IDLE:
Dianne Hackborn88c41352016-04-07 15:18:58 -07002698 case LIGHT_STATE_WAITING_FOR_NETWORK:
2699 if (mNetworkConnected || mLightState == LIGHT_STATE_WAITING_FOR_NETWORK) {
2700 // We have been idling long enough, now it is time to do some work.
2701 mActiveIdleOpCount = 1;
2702 mActiveIdleWakeLock.acquire();
2703 mMaintenanceStartTime = SystemClock.elapsedRealtime();
2704 if (mCurIdleBudget < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
2705 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
2706 } else if (mCurIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) {
2707 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
2708 }
2709 scheduleLightAlarmLocked(mCurIdleBudget);
2710 if (DEBUG) Slog.d(TAG,
2711 "Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE.");
2712 mLightState = LIGHT_STATE_IDLE_MAINTENANCE;
2713 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Amith Yamasaniac6517a2018-04-23 12:19:34 -07002714 addEvent(EVENT_LIGHT_MAINTENANCE, null);
Dianne Hackborn88c41352016-04-07 15:18:58 -07002715 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
2716 } else {
2717 // We'd like to do maintenance, but currently don't have network
2718 // connectivity... let's try to wait until the network comes back.
2719 // We'll only wait for another full idle period, however, and then give up.
2720 scheduleLightAlarmLocked(mNextLightIdleDelay);
2721 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_WAITING_FOR_NETWORK.");
2722 mLightState = LIGHT_STATE_WAITING_FOR_NETWORK;
2723 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002724 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002725 break;
2726 }
2727 }
2728
Kweku Adams00e3a372018-09-28 16:57:09 -07002729 @VisibleForTesting
2730 int getState() {
2731 return mState;
2732 }
2733
2734 @VisibleForTesting
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002735 void stepIdleStateLocked(String reason) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002736 if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002737 EventLogTags.writeDeviceIdleStep();
2738
2739 final long now = SystemClock.elapsedRealtime();
Adam Lesinski31c05d12015-06-09 17:34:04 -07002740 if ((now+mConstants.MIN_TIME_TO_ALARM) > mAlarmManager.getNextWakeFromIdleTime()) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002741 // Whoops, there is an upcoming alarm. We don't actually want to go idle.
2742 if (mState != STATE_ACTIVE) {
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002743 becomeActiveLocked("alarm", Process.myUid());
Koji Fukui27b33302015-12-16 19:43:01 +09002744 becomeInactiveIfAppropriateLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002745 }
2746 return;
2747 }
2748
Robin Lee876b88542018-11-13 17:22:24 +01002749 if (mNumBlockingConstraints != 0 && !mForceIdle) {
2750 // We have some constraints from other parts of the system server preventing
2751 // us from moving to the next state.
2752 if (DEBUG) {
2753 Slog.i(TAG, "Cannot step idle state. Blocked by: " + mConstraints.values().stream()
2754 .filter(x -> x.active)
2755 .map(x -> x.name)
2756 .collect(Collectors.joining(",")));
2757 }
2758 return;
2759 }
2760
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002761 switch (mState) {
2762 case STATE_INACTIVE:
2763 // We have now been inactive long enough, it is time to start looking
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002764 // for motion and sleep some more while doing so.
2765 startMonitoringMotionLocked();
Adam Lesinski31c05d12015-06-09 17:34:04 -07002766 scheduleAlarmLocked(mConstants.IDLE_AFTER_INACTIVE_TIMEOUT, false);
Robin Lee876b88542018-11-13 17:22:24 +01002767 moveToStateLocked(STATE_IDLE_PENDING, reason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002768 break;
2769 case STATE_IDLE_PENDING:
Robin Lee876b88542018-11-13 17:22:24 +01002770 moveToStateLocked(STATE_SENSING, reason);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002771 cancelLocatingLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002772 mLocated = false;
2773 mLastGenericLocation = null;
2774 mLastGpsLocation = null;
Robin Lee876b88542018-11-13 17:22:24 +01002775 updateActiveConstraintsLocked();
Robin Leec4d424c2018-12-07 15:09:13 +01002776
Robin Lee876b88542018-11-13 17:22:24 +01002777 // Wait for open constraints and an accelerometer reading before moving on.
Robin Leec4d424c2018-12-07 15:09:13 +01002778 if (mUseMotionSensor && mAnyMotionDetector.hasSensor()) {
2779 scheduleSensingTimeoutAlarmLocked(mConstants.SENSING_TIMEOUT);
2780 mNotMoving = false;
2781 mAnyMotionDetector.checkForAnyMotion();
2782 break;
Robin Lee876b88542018-11-13 17:22:24 +01002783 } else if (mNumBlockingConstraints != 0) {
2784 cancelAlarmLocked();
2785 break;
Robin Leec4d424c2018-12-07 15:09:13 +01002786 }
2787
2788 mNotMoving = true;
2789 // Otherwise, fall through and check this off the list of requirements.
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002790 case STATE_SENSING:
Kevin Gabayan92f15e62016-04-04 17:52:22 -07002791 cancelSensingTimeoutAlarmLocked();
Robin Lee876b88542018-11-13 17:22:24 +01002792 moveToStateLocked(STATE_LOCATING, reason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002793 scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT, false);
Kweku Adams799858b2018-10-08 17:19:08 -07002794 LocationManager locationManager = mInjector.getLocationManager();
2795 if (locationManager != null
2796 && locationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
2797 locationManager.requestLocationUpdates(mLocationRequest,
Joe LaPenna23d681b2015-08-27 15:12:11 -07002798 mGenericLocationListener, mHandler.getLooper());
2799 mLocating = true;
2800 } else {
2801 mHasNetworkLocation = false;
2802 }
Kweku Adams799858b2018-10-08 17:19:08 -07002803 if (locationManager != null
2804 && locationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
Joe LaPenna23d681b2015-08-27 15:12:11 -07002805 mHasGps = true;
Kweku Adams799858b2018-10-08 17:19:08 -07002806 locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5,
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002807 mGpsLocationListener, mHandler.getLooper());
Joe LaPenna23d681b2015-08-27 15:12:11 -07002808 mLocating = true;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002809 } else {
Joe LaPenna23d681b2015-08-27 15:12:11 -07002810 mHasGps = false;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002811 }
Joe LaPenna23d681b2015-08-27 15:12:11 -07002812 // If we have a location provider, we're all set, the listeners will move state
2813 // forward.
2814 if (mLocating) {
2815 break;
2816 }
2817
2818 // Otherwise, we have to move from locating into idle maintenance.
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002819 case STATE_LOCATING:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002820 cancelAlarmLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002821 cancelLocatingLocked();
2822 mAnyMotionDetector.stop();
Dianne Hackborn953fc942016-03-29 15:36:24 -07002823
Kweku Adamsb396ccf2018-09-17 16:37:15 -07002824 // Intentional fallthrough -- time to go into IDLE state.
2825 case STATE_QUICK_DOZE_DELAY:
2826 // Reset the upcoming idle delays.
2827 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
2828 mNextIdleDelay = mConstants.IDLE_TIMEOUT;
2829
2830 // Everything is in place to go into IDLE state.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002831 case STATE_IDLE_MAINTENANCE:
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002832 scheduleAlarmLocked(mNextIdleDelay, true);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002833 if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay +
2834 " ms.");
Adam Lesinski31c05d12015-06-09 17:34:04 -07002835 mNextIdleDelay = (long)(mNextIdleDelay * mConstants.IDLE_FACTOR);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002836 if (DEBUG) Slog.d(TAG, "Setting mNextIdleDelay = " + mNextIdleDelay);
Adam Lesinski31c05d12015-06-09 17:34:04 -07002837 mNextIdleDelay = Math.min(mNextIdleDelay, mConstants.MAX_IDLE_TIMEOUT);
Dianne Hackborn953fc942016-03-29 15:36:24 -07002838 if (mNextIdleDelay < mConstants.IDLE_TIMEOUT) {
2839 mNextIdleDelay = mConstants.IDLE_TIMEOUT;
2840 }
Robin Lee876b88542018-11-13 17:22:24 +01002841 moveToStateLocked(STATE_IDLE, reason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002842 if (mLightState != LIGHT_STATE_OVERRIDE) {
2843 mLightState = LIGHT_STATE_OVERRIDE;
2844 cancelLightAlarmLocked();
2845 }
Amith Yamasaniac6517a2018-04-23 12:19:34 -07002846 addEvent(EVENT_DEEP_IDLE, null);
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08002847 mGoingIdleWakeLock.acquire();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002848 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON);
2849 break;
2850 case STATE_IDLE:
2851 // We have been idling long enough, now it is time to do some work.
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002852 mActiveIdleOpCount = 1;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002853 mActiveIdleWakeLock.acquire();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002854 scheduleAlarmLocked(mNextIdlePendingDelay, false);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002855 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE to STATE_IDLE_MAINTENANCE. " +
2856 "Next alarm in " + mNextIdlePendingDelay + " ms.");
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002857 mMaintenanceStartTime = SystemClock.elapsedRealtime();
Adam Lesinski31c05d12015-06-09 17:34:04 -07002858 mNextIdlePendingDelay = Math.min(mConstants.MAX_IDLE_PENDING_TIMEOUT,
2859 (long)(mNextIdlePendingDelay * mConstants.IDLE_PENDING_FACTOR));
Dianne Hackborn953fc942016-03-29 15:36:24 -07002860 if (mNextIdlePendingDelay < mConstants.IDLE_PENDING_TIMEOUT) {
2861 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
2862 }
Robin Lee876b88542018-11-13 17:22:24 +01002863 moveToStateLocked(STATE_IDLE_MAINTENANCE, reason);
Amith Yamasaniac6517a2018-04-23 12:19:34 -07002864 addEvent(EVENT_DEEP_MAINTENANCE, null);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002865 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
2866 break;
2867 }
2868 }
2869
Robin Lee876b88542018-11-13 17:22:24 +01002870 private void moveToStateLocked(int state, String reason) {
2871 final int oldState = mState;
2872 mState = state;
2873 if (DEBUG) {
2874 Slog.d(TAG, String.format("Moved from STATE_%s to STATE_%s.",
2875 stateToString(oldState), stateToString(mState)));
2876 }
2877 EventLogTags.writeDeviceIdle(mState, reason);
2878 updateActiveConstraintsLocked();
2879 }
2880
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002881 void incActiveIdleOps() {
2882 synchronized (this) {
2883 mActiveIdleOpCount++;
2884 }
2885 }
2886
2887 void decActiveIdleOps() {
2888 synchronized (this) {
2889 mActiveIdleOpCount--;
2890 if (mActiveIdleOpCount <= 0) {
2891 exitMaintenanceEarlyIfNeededLocked();
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002892 mActiveIdleWakeLock.release();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002893 }
2894 }
2895 }
2896
Kweku Adamsa457f4e2018-10-03 15:56:06 -07002897 /** Must only be used in tests. */
2898 @VisibleForTesting
2899 void setActiveIdleOpsForTest(int count) {
Kweku Adams799858b2018-10-08 17:19:08 -07002900 synchronized (this) {
2901 mActiveIdleOpCount = count;
2902 }
Kweku Adamsa457f4e2018-10-03 15:56:06 -07002903 }
2904
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002905 void setJobsActive(boolean active) {
2906 synchronized (this) {
2907 mJobsActive = active;
Yao Chenca5edbb2016-01-13 14:44:36 -08002908 reportMaintenanceActivityIfNeededLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002909 if (!active) {
2910 exitMaintenanceEarlyIfNeededLocked();
2911 }
2912 }
2913 }
2914
2915 void setAlarmsActive(boolean active) {
2916 synchronized (this) {
2917 mAlarmsActive = active;
2918 if (!active) {
2919 exitMaintenanceEarlyIfNeededLocked();
2920 }
2921 }
2922 }
2923
Yao Chenca5edbb2016-01-13 14:44:36 -08002924 boolean registerMaintenanceActivityListener(IMaintenanceActivityListener listener) {
2925 synchronized (this) {
2926 mMaintenanceActivityListeners.register(listener);
2927 return mReportedMaintenanceActivity;
2928 }
2929 }
2930
2931 void unregisterMaintenanceActivityListener(IMaintenanceActivityListener listener) {
2932 synchronized (this) {
2933 mMaintenanceActivityListeners.unregister(listener);
2934 }
2935 }
2936
2937 void reportMaintenanceActivityIfNeededLocked() {
Dianne Hackborn7ab40252016-06-15 17:30:24 -07002938 boolean active = mJobsActive;
Yao Chenca5edbb2016-01-13 14:44:36 -08002939 if (active == mReportedMaintenanceActivity) {
2940 return;
2941 }
2942 mReportedMaintenanceActivity = active;
2943 Message msg = mHandler.obtainMessage(MSG_REPORT_MAINTENANCE_ACTIVITY,
2944 mReportedMaintenanceActivity ? 1 : 0, 0);
2945 mHandler.sendMessage(msg);
2946 }
2947
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002948 boolean isOpsInactiveLocked() {
Dianne Hackborn7ab40252016-06-15 17:30:24 -07002949 return mActiveIdleOpCount <= 0 && !mJobsActive && !mAlarmsActive;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002950 }
2951
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002952 void exitMaintenanceEarlyIfNeededLocked() {
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002953 if (mState == STATE_IDLE_MAINTENANCE || mLightState == LIGHT_STATE_IDLE_MAINTENANCE
2954 || mLightState == LIGHT_STATE_PRE_IDLE) {
2955 if (isOpsInactiveLocked()) {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002956 final long now = SystemClock.elapsedRealtime();
2957 if (DEBUG) {
2958 StringBuilder sb = new StringBuilder();
2959 sb.append("Exit: start=");
2960 TimeUtils.formatDuration(mMaintenanceStartTime, sb);
2961 sb.append(" now=");
2962 TimeUtils.formatDuration(now, sb);
2963 Slog.d(TAG, sb.toString());
2964 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002965 if (mState == STATE_IDLE_MAINTENANCE) {
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002966 stepIdleStateLocked("s:early");
2967 } else if (mLightState == LIGHT_STATE_PRE_IDLE) {
2968 stepLightIdleStateLocked("s:predone");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002969 } else {
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002970 stepLightIdleStateLocked("s:early");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002971 }
2972 }
2973 }
2974 }
2975
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002976 void motionLocked() {
2977 if (DEBUG) Slog.d(TAG, "motionLocked()");
2978 // The motion sensor will have been disabled at this point
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002979 handleMotionDetectedLocked(mConstants.MOTION_INACTIVE_TIMEOUT, "motion");
2980 }
2981
2982 void handleMotionDetectedLocked(long timeout, String type) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002983 // The device is not yet active, so we want to go back to the pending idle
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002984 // state to wait again for no motion. Note that we only monitor for motion
2985 // after moving out of the inactive state, so no need to worry about that.
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002986 boolean becomeInactive = false;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002987 if (mState != STATE_ACTIVE) {
Amith Yamasani4cb42572018-04-27 10:02:57 -07002988 // Motion shouldn't affect light state, if it's already in doze-light or maintenance
2989 boolean lightIdle = mLightState == LIGHT_STATE_IDLE
2990 || mLightState == LIGHT_STATE_WAITING_FOR_NETWORK
2991 || mLightState == LIGHT_STATE_IDLE_MAINTENANCE;
2992 if (!lightIdle) {
2993 // Only switch to active state if we're not in either idle state
2994 scheduleReportActiveLocked(type, Process.myUid());
2995 addEvent(EVENT_NORMAL, type);
2996 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002997 mState = STATE_ACTIVE;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002998 mInactiveTimeout = timeout;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002999 mCurIdleBudget = 0;
3000 mMaintenanceStartTime = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003001 EventLogTags.writeDeviceIdle(mState, type);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003002 becomeInactive = true;
Robin Lee876b88542018-11-13 17:22:24 +01003003 updateActiveConstraintsLocked();
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003004 }
3005 if (mLightState == LIGHT_STATE_OVERRIDE) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08003006 // We went out of light idle mode because we had started deep idle mode... let's
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003007 // now go back and reset things so we resume light idling if appropriate.
Amith Yamasani4cb42572018-04-27 10:02:57 -07003008 mLightState = LIGHT_STATE_ACTIVE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003009 EventLogTags.writeDeviceIdleLight(mLightState, type);
3010 becomeInactive = true;
3011 }
3012 if (becomeInactive) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003013 becomeInactiveIfAppropriateLocked();
3014 }
3015 }
3016
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003017 void receivedGenericLocationLocked(Location location) {
3018 if (mState != STATE_LOCATING) {
3019 cancelLocatingLocked();
3020 return;
3021 }
3022 if (DEBUG) Slog.d(TAG, "Generic location: " + location);
3023 mLastGenericLocation = new Location(location);
Joe LaPenna23d681b2015-08-27 15:12:11 -07003024 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHasGps) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003025 return;
3026 }
3027 mLocated = true;
3028 if (mNotMoving) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003029 stepIdleStateLocked("s:location");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003030 }
3031 }
3032
3033 void receivedGpsLocationLocked(Location location) {
3034 if (mState != STATE_LOCATING) {
3035 cancelLocatingLocked();
3036 return;
3037 }
3038 if (DEBUG) Slog.d(TAG, "GPS location: " + location);
3039 mLastGpsLocation = new Location(location);
3040 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY) {
3041 return;
3042 }
3043 mLocated = true;
3044 if (mNotMoving) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003045 stepIdleStateLocked("s:gps");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003046 }
3047 }
3048
Nick Vaccaro20feaea2015-09-17 17:22:44 -07003049 void startMonitoringMotionLocked() {
3050 if (DEBUG) Slog.d(TAG, "startMonitoringMotionLocked()");
3051 if (mMotionSensor != null && !mMotionListener.active) {
3052 mMotionListener.registerLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003053 }
3054 }
3055
Nick Vaccaro20feaea2015-09-17 17:22:44 -07003056 void stopMonitoringMotionLocked() {
3057 if (DEBUG) Slog.d(TAG, "stopMonitoringMotionLocked()");
3058 if (mMotionSensor != null && mMotionListener.active) {
3059 mMotionListener.unregisterLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003060 }
3061 }
3062
3063 void cancelAlarmLocked() {
3064 if (mNextAlarmTime != 0) {
3065 mNextAlarmTime = 0;
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003066 mAlarmManager.cancel(mDeepAlarmListener);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003067 }
3068 }
3069
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003070 void cancelLightAlarmLocked() {
3071 if (mNextLightAlarmTime != 0) {
3072 mNextLightAlarmTime = 0;
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003073 mAlarmManager.cancel(mLightAlarmListener);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003074 }
3075 }
3076
3077 void cancelLocatingLocked() {
3078 if (mLocating) {
Kweku Adams799858b2018-10-08 17:19:08 -07003079 LocationManager locationManager = mInjector.getLocationManager();
3080 locationManager.removeUpdates(mGenericLocationListener);
3081 locationManager.removeUpdates(mGpsLocationListener);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003082 mLocating = false;
3083 }
Kevin Gabayan89ecf822015-05-18 12:10:07 -07003084 }
3085
Kevin Gabayan92f15e62016-04-04 17:52:22 -07003086 void cancelSensingTimeoutAlarmLocked() {
3087 if (mNextSensingTimeoutAlarmTime != 0) {
3088 mNextSensingTimeoutAlarmTime = 0;
3089 mAlarmManager.cancel(mSensingTimeoutAlarmListener);
3090 }
3091 }
3092
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003093 void scheduleAlarmLocked(long delay, boolean idleUntil) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07003094 if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")");
Robin Leec4d424c2018-12-07 15:09:13 +01003095
3096 if (mUseMotionSensor && mMotionSensor == null
3097 && mState != STATE_QUICK_DOZE_DELAY
3098 && mState != STATE_IDLE
3099 && mState != STATE_IDLE_MAINTENANCE) {
3100 // 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 -07003101 // alarms, because we can't determine if the device is not moving. This effectively
Joe LaPenna23d681b2015-08-27 15:12:11 -07003102 // turns off normal execution of device idling, although it is still possible to
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003103 // manually poke it by pretending like the alarm is going off.
Kweku Adamsb396ccf2018-09-17 16:37:15 -07003104 // STATE_QUICK_DOZE_DELAY skips the motion sensing so if the state is past the motion
3105 // sensing stage (ie, is QUICK_DOZE_DELAY, IDLE, or IDLE_MAINTENANCE), then idling
3106 // can continue until the user interacts with the device.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003107 return;
3108 }
3109 mNextAlarmTime = SystemClock.elapsedRealtime() + delay;
3110 if (idleUntil) {
3111 mAlarmManager.setIdleUntil(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003112 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003113 } else {
3114 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003115 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003116 }
3117 }
3118
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003119 void scheduleLightAlarmLocked(long delay) {
3120 if (DEBUG) Slog.d(TAG, "scheduleLightAlarmLocked(" + delay + ")");
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003121 mNextLightAlarmTime = SystemClock.elapsedRealtime() + delay;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003122 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003123 mNextLightAlarmTime, "DeviceIdleController.light", mLightAlarmListener, mHandler);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07003124 }
3125
Kevin Gabayan92f15e62016-04-04 17:52:22 -07003126 void scheduleSensingTimeoutAlarmLocked(long delay) {
3127 if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")");
3128 mNextSensingTimeoutAlarmTime = SystemClock.elapsedRealtime() + delay;
3129 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextSensingTimeoutAlarmTime,
3130 "DeviceIdleController.sensing", mSensingTimeoutAlarmListener, mHandler);
3131 }
3132
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003133 private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps,
3134 ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds) {
3135 outAppIds.clear();
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08003136 if (systemApps != null) {
3137 for (int i = 0; i < systemApps.size(); i++) {
3138 outAppIds.put(systemApps.valueAt(i), true);
3139 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003140 }
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08003141 if (userApps != null) {
3142 for (int i = 0; i < userApps.size(); i++) {
3143 outAppIds.put(userApps.valueAt(i), true);
3144 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003145 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003146 int size = outAppIds.size();
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003147 int[] appids = new int[size];
3148 for (int i = 0; i < size; i++) {
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003149 appids[i] = outAppIds.keyAt(i);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003150 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003151 return appids;
3152 }
3153
3154 private void updateWhitelistAppIdsLocked() {
3155 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(mPowerSaveWhitelistAppsExceptIdle,
3156 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistExceptIdleAppIds);
3157 mPowerSaveWhitelistAllAppIdArray = buildAppIdArray(mPowerSaveWhitelistApps,
3158 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistAllAppIds);
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08003159 mPowerSaveWhitelistUserAppIdArray = buildAppIdArray(null,
3160 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistUserAppIds);
Dianne Hackborn85e35642017-01-12 15:10:57 -08003161 if (mLocalActivityManager != null) {
Makoto Onukiaf8ff4f2018-06-04 14:44:19 -07003162 mLocalActivityManager.setDeviceIdleWhitelist(
3163 mPowerSaveWhitelistAllAppIdArray, mPowerSaveWhitelistExceptIdleAppIdArray);
Dianne Hackborn85e35642017-01-12 15:10:57 -08003164 }
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003165 if (mLocalPowerManager != null) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003166 if (DEBUG) {
3167 Slog.d(TAG, "Setting wakelock whitelist to "
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07003168 + Arrays.toString(mPowerSaveWhitelistAllAppIdArray));
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003169 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07003170 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003171 }
Suprabh Shukla5bf49812018-05-24 18:38:50 -07003172 passWhiteListsToForceAppStandbyTrackerLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003173 }
3174
Dianne Hackborn85e35642017-01-12 15:10:57 -08003175 private void updateTempWhitelistAppIdsLocked(int appId, boolean adding) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003176 final int size = mTempWhitelistAppIdEndTimes.size();
3177 if (mTempWhitelistAppIdArray.length != size) {
3178 mTempWhitelistAppIdArray = new int[size];
3179 }
3180 for (int i = 0; i < size; i++) {
3181 mTempWhitelistAppIdArray[i] = mTempWhitelistAppIdEndTimes.keyAt(i);
3182 }
Dianne Hackborn85e35642017-01-12 15:10:57 -08003183 if (mLocalActivityManager != null) {
3184 if (DEBUG) {
3185 Slog.d(TAG, "Setting activity manager temp whitelist to "
3186 + Arrays.toString(mTempWhitelistAppIdArray));
3187 }
3188 mLocalActivityManager.updateDeviceIdleTempWhitelist(mTempWhitelistAppIdArray, appId,
3189 adding);
3190 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003191 if (mLocalPowerManager != null) {
3192 if (DEBUG) {
3193 Slog.d(TAG, "Setting wakelock temp whitelist to "
3194 + Arrays.toString(mTempWhitelistAppIdArray));
3195 }
3196 mLocalPowerManager.setDeviceIdleTempWhitelist(mTempWhitelistAppIdArray);
3197 }
Suprabh Shukla5bf49812018-05-24 18:38:50 -07003198 passWhiteListsToForceAppStandbyTrackerLocked();
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003199 }
3200
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003201 private void reportPowerSaveWhitelistChangedLocked() {
3202 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
3203 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Xiaohui Chene4de5a02015-09-22 15:33:31 -07003204 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003205 }
3206
3207 private void reportTempWhitelistChangedLocked() {
3208 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED);
3209 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Xiaohui Chene4de5a02015-09-22 15:33:31 -07003210 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003211 }
3212
Suprabh Shukla5bf49812018-05-24 18:38:50 -07003213 private void passWhiteListsToForceAppStandbyTrackerLocked() {
Makoto Onukie4918212018-02-06 11:30:15 -08003214 mAppStateTracker.setPowerSaveWhitelistAppIds(
Makoto Onuki71755c92018-01-16 14:15:44 -08003215 mPowerSaveWhitelistExceptIdleAppIdArray,
Suprabh Shukla5bf49812018-05-24 18:38:50 -07003216 mPowerSaveWhitelistUserAppIdArray,
Makoto Onuki2206af32017-11-21 16:25:35 -08003217 mTempWhitelistAppIdArray);
3218 }
3219
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003220 void readConfigFileLocked() {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003221 if (DEBUG) Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003222 mPowerSaveWhitelistUserApps.clear();
3223 FileInputStream stream;
3224 try {
3225 stream = mConfigFile.openRead();
3226 } catch (FileNotFoundException e) {
3227 return;
3228 }
3229 try {
3230 XmlPullParser parser = Xml.newPullParser();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01003231 parser.setInput(stream, StandardCharsets.UTF_8.name());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003232 readConfigFileLocked(parser);
3233 } catch (XmlPullParserException e) {
3234 } finally {
3235 try {
3236 stream.close();
3237 } catch (IOException e) {
3238 }
3239 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003240 }
3241
3242 private void readConfigFileLocked(XmlPullParser parser) {
3243 final PackageManager pm = getContext().getPackageManager();
3244
3245 try {
3246 int type;
3247 while ((type = parser.next()) != XmlPullParser.START_TAG
3248 && type != XmlPullParser.END_DOCUMENT) {
3249 ;
3250 }
3251
3252 if (type != XmlPullParser.START_TAG) {
3253 throw new IllegalStateException("no start tag found");
3254 }
3255
3256 int outerDepth = parser.getDepth();
3257 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3258 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3259 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3260 continue;
3261 }
3262
3263 String tagName = parser.getName();
Suprabh Shukla08105642017-09-26 14:45:30 -07003264 switch (tagName) {
3265 case "wl":
3266 String name = parser.getAttributeValue(null, "n");
3267 if (name != null) {
3268 try {
3269 ApplicationInfo ai = pm.getApplicationInfo(name,
3270 PackageManager.MATCH_ANY_USER);
3271 mPowerSaveWhitelistUserApps.put(ai.packageName,
3272 UserHandle.getAppId(ai.uid));
3273 } catch (PackageManager.NameNotFoundException e) {
3274 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003275 }
Suprabh Shukla08105642017-09-26 14:45:30 -07003276 break;
3277 case "un-wl":
3278 final String packageName = parser.getAttributeValue(null, "n");
3279 if (mPowerSaveWhitelistApps.containsKey(packageName)) {
3280 mRemovedFromSystemWhitelistApps.put(packageName,
3281 mPowerSaveWhitelistApps.remove(packageName));
3282 }
3283 break;
3284 default:
3285 Slog.w(TAG, "Unknown element under <config>: "
3286 + parser.getName());
3287 XmlUtils.skipCurrentTag(parser);
3288 break;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003289 }
3290 }
3291
3292 } catch (IllegalStateException e) {
3293 Slog.w(TAG, "Failed parsing config " + e);
3294 } catch (NullPointerException e) {
3295 Slog.w(TAG, "Failed parsing config " + e);
3296 } catch (NumberFormatException e) {
3297 Slog.w(TAG, "Failed parsing config " + e);
3298 } catch (XmlPullParserException e) {
3299 Slog.w(TAG, "Failed parsing config " + e);
3300 } catch (IOException e) {
3301 Slog.w(TAG, "Failed parsing config " + e);
3302 } catch (IndexOutOfBoundsException e) {
3303 Slog.w(TAG, "Failed parsing config " + e);
3304 }
3305 }
3306
3307 void writeConfigFileLocked() {
3308 mHandler.removeMessages(MSG_WRITE_CONFIG);
3309 mHandler.sendEmptyMessageDelayed(MSG_WRITE_CONFIG, 5000);
3310 }
3311
3312 void handleWriteConfigFile() {
3313 final ByteArrayOutputStream memStream = new ByteArrayOutputStream();
3314
3315 try {
3316 synchronized (this) {
3317 XmlSerializer out = new FastXmlSerializer();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01003318 out.setOutput(memStream, StandardCharsets.UTF_8.name());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003319 writeConfigFileLocked(out);
3320 }
3321 } catch (IOException e) {
3322 }
3323
3324 synchronized (mConfigFile) {
3325 FileOutputStream stream = null;
3326 try {
3327 stream = mConfigFile.startWrite();
3328 memStream.writeTo(stream);
3329 stream.flush();
3330 FileUtils.sync(stream);
3331 stream.close();
3332 mConfigFile.finishWrite(stream);
3333 } catch (IOException e) {
3334 Slog.w(TAG, "Error writing config file", e);
3335 mConfigFile.failWrite(stream);
3336 }
3337 }
3338 }
3339
3340 void writeConfigFileLocked(XmlSerializer out) throws IOException {
3341 out.startDocument(null, true);
3342 out.startTag(null, "config");
3343 for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) {
3344 String name = mPowerSaveWhitelistUserApps.keyAt(i);
3345 out.startTag(null, "wl");
3346 out.attribute(null, "n", name);
3347 out.endTag(null, "wl");
3348 }
Suprabh Shukla08105642017-09-26 14:45:30 -07003349 for (int i = 0; i < mRemovedFromSystemWhitelistApps.size(); i++) {
3350 out.startTag(null, "un-wl");
3351 out.attribute(null, "n", mRemovedFromSystemWhitelistApps.keyAt(i));
3352 out.endTag(null, "un-wl");
3353 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003354 out.endTag(null, "config");
3355 out.endDocument();
3356 }
3357
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003358 static void dumpHelp(PrintWriter pw) {
3359 pw.println("Device idle controller (deviceidle) commands:");
3360 pw.println(" help");
3361 pw.println(" Print this help text.");
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003362 pw.println(" step [light|deep]");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003363 pw.println(" Immediately step to next state, without waiting for alarm.");
Dianne Hackborn88c41352016-04-07 15:18:58 -07003364 pw.println(" force-idle [light|deep]");
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003365 pw.println(" Force directly into idle mode, regardless of other device state.");
Dianne Hackborn88c41352016-04-07 15:18:58 -07003366 pw.println(" force-inactive");
3367 pw.println(" Force to be inactive, ready to freely step idle states.");
3368 pw.println(" unforce");
3369 pw.println(" Resume normal functioning after force-idle or force-inactive.");
3370 pw.println(" get [light|deep|force|screen|charging|network]");
3371 pw.println(" Retrieve the current given state.");
Dianne Hackbornb6843652016-02-22 12:20:13 -08003372 pw.println(" disable [light|deep|all]");
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003373 pw.println(" Completely disable device idle mode.");
Dianne Hackbornb6843652016-02-22 12:20:13 -08003374 pw.println(" enable [light|deep|all]");
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003375 pw.println(" Re-enable device idle mode after it had previously been disabled.");
Dianne Hackbornb6843652016-02-22 12:20:13 -08003376 pw.println(" enabled [light|deep|all]");
Dianne Hackborn92617032015-06-19 15:32:19 -07003377 pw.println(" Print 1 if device idle mode is currently enabled, else 0.");
Dianne Hackborn1b139682015-07-06 15:13:37 -07003378 pw.println(" whitelist");
3379 pw.println(" Print currently whitelisted apps.");
Dianne Hackborn92617032015-06-19 15:32:19 -07003380 pw.println(" whitelist [package ...]");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003381 pw.println(" Add (prefix with +) or remove (prefix with -) packages.");
Suprabh Shukla08105642017-09-26 14:45:30 -07003382 pw.println(" sys-whitelist [package ...|reset]");
3383 pw.println(" Prefix the package with '-' to remove it from the system whitelist or '+'"
3384 + " to put it back in the system whitelist.");
3385 pw.println(" Note that only packages that were"
3386 + " earlier removed from the system whitelist can be added back.");
3387 pw.println(" reset will reset the whitelist to the original state");
3388 pw.println(" Prints the system whitelist if no arguments are specified");
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07003389 pw.println(" except-idle-whitelist [package ...|reset]");
3390 pw.println(" Prefix the package with '+' to add it to whitelist or "
3391 + "'=' to check if it is already whitelisted");
3392 pw.println(" [reset] will reset the whitelist to it's original state");
3393 pw.println(" Note that unlike <whitelist> cmd, "
3394 + "changes made using this won't be persisted across boots");
Felipe Lemea1b79bf2016-05-24 13:06:54 -07003395 pw.println(" tempwhitelist");
3396 pw.println(" Print packages that are temporarily whitelisted.");
Sudheer Shanka326b3112017-11-27 14:40:57 -08003397 pw.println(" tempwhitelist [-u USER] [-d DURATION] [-r] [package]");
3398 pw.println(" Temporarily place package in whitelist for DURATION milliseconds.");
Dianne Hackborn85e35642017-01-12 15:10:57 -08003399 pw.println(" If no DURATION is specified, 10 seconds is used");
Sudheer Shanka326b3112017-11-27 14:40:57 -08003400 pw.println(" If [-r] option is used, then the package is removed from temp whitelist "
3401 + "and any [-d] is ignored");
Amith Yamasani4cb42572018-04-27 10:02:57 -07003402 pw.println(" motion");
3403 pw.println(" Simulate a motion event to bring the device out of deep doze");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003404 }
3405
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003406 class Shell extends ShellCommand {
3407 int userId = UserHandle.USER_SYSTEM;
3408
3409 @Override
3410 public int onCommand(String cmd) {
3411 return onShellCommand(this, cmd);
3412 }
3413
3414 @Override
3415 public void onHelp() {
3416 PrintWriter pw = getOutPrintWriter();
3417 dumpHelp(pw);
3418 }
3419 }
3420
3421 int onShellCommand(Shell shell, String cmd) {
3422 PrintWriter pw = shell.getOutPrintWriter();
3423 if ("step".equals(cmd)) {
3424 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3425 null);
3426 synchronized (this) {
3427 long token = Binder.clearCallingIdentity();
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003428 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003429 try {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003430 if (arg == null || "deep".equals(arg)) {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003431 stepIdleStateLocked("s:shell");
3432 pw.print("Stepped to deep: ");
3433 pw.println(stateToString(mState));
3434 } else if ("light".equals(arg)) {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003435 stepLightIdleStateLocked("s:shell");
3436 pw.print("Stepped to light: "); pw.println(lightStateToString(mLightState));
3437 } else {
3438 pw.println("Unknown idle mode: " + arg);
3439 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003440 } finally {
3441 Binder.restoreCallingIdentity(token);
3442 }
3443 }
3444 } else if ("force-idle".equals(cmd)) {
3445 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3446 null);
3447 synchronized (this) {
3448 long token = Binder.clearCallingIdentity();
Dianne Hackborn88c41352016-04-07 15:18:58 -07003449 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003450 try {
Dianne Hackborn88c41352016-04-07 15:18:58 -07003451 if (arg == null || "deep".equals(arg)) {
3452 if (!mDeepEnabled) {
3453 pw.println("Unable to go deep idle; not enabled");
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003454 return -1;
3455 }
Dianne Hackborn88c41352016-04-07 15:18:58 -07003456 mForceIdle = true;
3457 becomeInactiveIfAppropriateLocked();
3458 int curState = mState;
3459 while (curState != STATE_IDLE) {
3460 stepIdleStateLocked("s:shell");
3461 if (curState == mState) {
3462 pw.print("Unable to go deep idle; stopped at ");
3463 pw.println(stateToString(mState));
3464 exitForceIdleLocked();
3465 return -1;
3466 }
3467 curState = mState;
3468 }
3469 pw.println("Now forced in to deep idle mode");
3470 } else if ("light".equals(arg)) {
3471 mForceIdle = true;
3472 becomeInactiveIfAppropriateLocked();
3473 int curLightState = mLightState;
3474 while (curLightState != LIGHT_STATE_IDLE) {
Tej Singh93cf3e32017-12-07 13:05:38 -08003475 stepLightIdleStateLocked("s:shell");
Dianne Hackborn88c41352016-04-07 15:18:58 -07003476 if (curLightState == mLightState) {
3477 pw.print("Unable to go light idle; stopped at ");
3478 pw.println(lightStateToString(mLightState));
3479 exitForceIdleLocked();
3480 return -1;
3481 }
3482 curLightState = mLightState;
3483 }
3484 pw.println("Now forced in to light idle mode");
3485 } else {
3486 pw.println("Unknown idle mode: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003487 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003488 } finally {
3489 Binder.restoreCallingIdentity(token);
3490 }
3491 }
Dianne Hackborn88c41352016-04-07 15:18:58 -07003492 } else if ("force-inactive".equals(cmd)) {
3493 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3494 null);
3495 synchronized (this) {
3496 long token = Binder.clearCallingIdentity();
3497 try {
3498 mForceIdle = true;
3499 becomeInactiveIfAppropriateLocked();
3500 pw.print("Light state: ");
3501 pw.print(lightStateToString(mLightState));
3502 pw.print(", deep state: ");
3503 pw.println(stateToString(mState));
3504 } finally {
3505 Binder.restoreCallingIdentity(token);
3506 }
3507 }
3508 } else if ("unforce".equals(cmd)) {
3509 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3510 null);
3511 synchronized (this) {
3512 long token = Binder.clearCallingIdentity();
3513 try {
3514 exitForceIdleLocked();
3515 pw.print("Light state: ");
3516 pw.print(lightStateToString(mLightState));
3517 pw.print(", deep state: ");
3518 pw.println(stateToString(mState));
3519 } finally {
3520 Binder.restoreCallingIdentity(token);
3521 }
3522 }
3523 } else if ("get".equals(cmd)) {
3524 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3525 null);
3526 synchronized (this) {
3527 String arg = shell.getNextArg();
3528 if (arg != null) {
3529 long token = Binder.clearCallingIdentity();
3530 try {
3531 switch (arg) {
3532 case "light": pw.println(lightStateToString(mLightState)); break;
3533 case "deep": pw.println(stateToString(mState)); break;
3534 case "force": pw.println(mForceIdle); break;
Kweku Adamsb396ccf2018-09-17 16:37:15 -07003535 case "quick": pw.println(mQuickDozeActivated); break;
Dianne Hackborn88c41352016-04-07 15:18:58 -07003536 case "screen": pw.println(mScreenOn); break;
3537 case "charging": pw.println(mCharging); break;
3538 case "network": pw.println(mNetworkConnected); break;
3539 default: pw.println("Unknown get option: " + arg); break;
3540 }
3541 } finally {
3542 Binder.restoreCallingIdentity(token);
3543 }
3544 } else {
3545 pw.println("Argument required");
3546 }
3547 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003548 } else if ("disable".equals(cmd)) {
3549 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3550 null);
3551 synchronized (this) {
3552 long token = Binder.clearCallingIdentity();
Dianne Hackbornb6843652016-02-22 12:20:13 -08003553 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003554 try {
Dianne Hackbornb6843652016-02-22 12:20:13 -08003555 boolean becomeActive = false;
3556 boolean valid = false;
3557 if (arg == null || "deep".equals(arg) || "all".equals(arg)) {
3558 valid = true;
3559 if (mDeepEnabled) {
3560 mDeepEnabled = false;
3561 becomeActive = true;
3562 pw.println("Deep idle mode disabled");
3563 }
3564 }
3565 if (arg == null || "light".equals(arg) || "all".equals(arg)) {
3566 valid = true;
3567 if (mLightEnabled) {
3568 mLightEnabled = false;
3569 becomeActive = true;
3570 pw.println("Light idle mode disabled");
3571 }
3572 }
3573 if (becomeActive) {
3574 becomeActiveLocked((arg == null ? "all" : arg) + "-disabled",
3575 Process.myUid());
3576 }
3577 if (!valid) {
3578 pw.println("Unknown idle mode: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003579 }
3580 } finally {
3581 Binder.restoreCallingIdentity(token);
3582 }
3583 }
3584 } else if ("enable".equals(cmd)) {
3585 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3586 null);
3587 synchronized (this) {
3588 long token = Binder.clearCallingIdentity();
Dianne Hackbornb6843652016-02-22 12:20:13 -08003589 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003590 try {
Dianne Hackbornb6843652016-02-22 12:20:13 -08003591 boolean becomeInactive = false;
3592 boolean valid = false;
3593 if (arg == null || "deep".equals(arg) || "all".equals(arg)) {
3594 valid = true;
3595 if (!mDeepEnabled) {
3596 mDeepEnabled = true;
3597 becomeInactive = true;
3598 pw.println("Deep idle mode enabled");
3599 }
3600 }
3601 if (arg == null || "light".equals(arg) || "all".equals(arg)) {
3602 valid = true;
3603 if (!mLightEnabled) {
3604 mLightEnabled = true;
3605 becomeInactive = true;
3606 pw.println("Light idle mode enable");
3607 }
3608 }
3609 if (becomeInactive) {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003610 becomeInactiveIfAppropriateLocked();
Dianne Hackbornb6843652016-02-22 12:20:13 -08003611 }
3612 if (!valid) {
3613 pw.println("Unknown idle mode: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003614 }
3615 } finally {
3616 Binder.restoreCallingIdentity(token);
3617 }
3618 }
3619 } else if ("enabled".equals(cmd)) {
3620 synchronized (this) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08003621 String arg = shell.getNextArg();
3622 if (arg == null || "all".equals(arg)) {
3623 pw.println(mDeepEnabled && mLightEnabled ? "1" : 0);
3624 } else if ("deep".equals(arg)) {
3625 pw.println(mDeepEnabled ? "1" : 0);
3626 } else if ("light".equals(arg)) {
3627 pw.println(mLightEnabled ? "1" : 0);
3628 } else {
3629 pw.println("Unknown idle mode: " + arg);
3630 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003631 }
3632 } else if ("whitelist".equals(cmd)) {
Dianne Hackborneb909e32016-09-29 14:35:15 -07003633 String arg = shell.getNextArg();
3634 if (arg != null) {
3635 getContext().enforceCallingOrSelfPermission(
3636 android.Manifest.permission.DEVICE_POWER, null);
3637 long token = Binder.clearCallingIdentity();
3638 try {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003639 do {
3640 if (arg.length() < 1 || (arg.charAt(0) != '-'
Felipe Lemef8a46232016-02-10 13:51:54 -08003641 && arg.charAt(0) != '+' && arg.charAt(0) != '=')) {
3642 pw.println("Package must be prefixed with +, -, or =: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003643 return -1;
3644 }
3645 char op = arg.charAt(0);
3646 String pkg = arg.substring(1);
3647 if (op == '+') {
3648 if (addPowerSaveWhitelistAppInternal(pkg)) {
3649 pw.println("Added: " + pkg);
3650 } else {
3651 pw.println("Unknown package: " + pkg);
3652 }
Felipe Lemef8a46232016-02-10 13:51:54 -08003653 } else if (op == '-') {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003654 if (removePowerSaveWhitelistAppInternal(pkg)) {
3655 pw.println("Removed: " + pkg);
3656 }
Felipe Lemef8a46232016-02-10 13:51:54 -08003657 } else {
3658 pw.println(getPowerSaveWhitelistAppInternal(pkg));
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003659 }
3660 } while ((arg=shell.getNextArg()) != null);
Dianne Hackborneb909e32016-09-29 14:35:15 -07003661 } finally {
3662 Binder.restoreCallingIdentity(token);
3663 }
3664 } else {
3665 synchronized (this) {
3666 for (int j=0; j<mPowerSaveWhitelistAppsExceptIdle.size(); j++) {
3667 pw.print("system-excidle,");
3668 pw.print(mPowerSaveWhitelistAppsExceptIdle.keyAt(j));
3669 pw.print(",");
3670 pw.println(mPowerSaveWhitelistAppsExceptIdle.valueAt(j));
3671 }
3672 for (int j=0; j<mPowerSaveWhitelistApps.size(); j++) {
3673 pw.print("system,");
3674 pw.print(mPowerSaveWhitelistApps.keyAt(j));
3675 pw.print(",");
3676 pw.println(mPowerSaveWhitelistApps.valueAt(j));
3677 }
3678 for (int j=0; j<mPowerSaveWhitelistUserApps.size(); j++) {
3679 pw.print("user,");
3680 pw.print(mPowerSaveWhitelistUserApps.keyAt(j));
3681 pw.print(",");
3682 pw.println(mPowerSaveWhitelistUserApps.valueAt(j));
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003683 }
3684 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003685 }
3686 } else if ("tempwhitelist".equals(cmd)) {
Dianne Hackborn85e35642017-01-12 15:10:57 -08003687 long duration = 10000;
Sudheer Shanka326b3112017-11-27 14:40:57 -08003688 boolean removePkg = false;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003689 String opt;
3690 while ((opt=shell.getNextOption()) != null) {
3691 if ("-u".equals(opt)) {
3692 opt = shell.getNextArg();
3693 if (opt == null) {
3694 pw.println("-u requires a user number");
3695 return -1;
3696 }
3697 shell.userId = Integer.parseInt(opt);
Dianne Hackborn85e35642017-01-12 15:10:57 -08003698 } else if ("-d".equals(opt)) {
3699 opt = shell.getNextArg();
3700 if (opt == null) {
3701 pw.println("-d requires a duration");
3702 return -1;
3703 }
3704 duration = Long.parseLong(opt);
Sudheer Shanka326b3112017-11-27 14:40:57 -08003705 } else if ("-r".equals(opt)) {
3706 removePkg = true;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003707 }
3708 }
3709 String arg = shell.getNextArg();
3710 if (arg != null) {
3711 try {
Sudheer Shanka326b3112017-11-27 14:40:57 -08003712 if (removePkg) {
3713 removePowerSaveTempWhitelistAppChecked(arg, shell.userId);
3714 } else {
3715 addPowerSaveTempWhitelistAppChecked(arg, duration, shell.userId, "shell");
3716 }
Christopher Tateec3a9f32017-03-21 17:43:47 -07003717 } catch (Exception e) {
3718 pw.println("Failed: " + e);
3719 return -1;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003720 }
Sudheer Shanka326b3112017-11-27 14:40:57 -08003721 } else if (removePkg) {
3722 pw.println("[-r] requires a package name");
3723 return -1;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003724 } else {
Felipe Lemea1b79bf2016-05-24 13:06:54 -07003725 dumpTempWhitelistSchedule(pw, false);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003726 }
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07003727 } else if ("except-idle-whitelist".equals(cmd)) {
3728 getContext().enforceCallingOrSelfPermission(
3729 android.Manifest.permission.DEVICE_POWER, null);
3730 final long token = Binder.clearCallingIdentity();
3731 try {
3732 String arg = shell.getNextArg();
3733 if (arg == null) {
3734 pw.println("No arguments given");
3735 return -1;
3736 } else if ("reset".equals(arg)) {
3737 resetPowerSaveWhitelistExceptIdleInternal();
3738 } else {
3739 do {
3740 if (arg.length() < 1 || (arg.charAt(0) != '-'
3741 && arg.charAt(0) != '+' && arg.charAt(0) != '=')) {
3742 pw.println("Package must be prefixed with +, -, or =: " + arg);
3743 return -1;
3744 }
3745 char op = arg.charAt(0);
3746 String pkg = arg.substring(1);
3747 if (op == '+') {
3748 if (addPowerSaveWhitelistExceptIdleInternal(pkg)) {
3749 pw.println("Added: " + pkg);
3750 } else {
3751 pw.println("Unknown package: " + pkg);
3752 }
3753 } else if (op == '=') {
3754 pw.println(getPowerSaveWhitelistExceptIdleInternal(pkg));
3755 } else {
3756 pw.println("Unknown argument: " + arg);
3757 return -1;
3758 }
3759 } while ((arg = shell.getNextArg()) != null);
3760 }
3761 } finally {
3762 Binder.restoreCallingIdentity(token);
3763 }
Suprabh Shukla08105642017-09-26 14:45:30 -07003764 } else if ("sys-whitelist".equals(cmd)) {
3765 String arg = shell.getNextArg();
3766 if (arg != null) {
3767 getContext().enforceCallingOrSelfPermission(
3768 android.Manifest.permission.DEVICE_POWER, null);
3769 final long token = Binder.clearCallingIdentity();
3770 try {
3771 if ("reset".equals(arg)) {
3772 resetSystemPowerWhitelistInternal();
3773 } else {
3774 do {
3775 if (arg.length() < 1
3776 || (arg.charAt(0) != '-' && arg.charAt(0) != '+')) {
3777 pw.println("Package must be prefixed with + or - " + arg);
3778 return -1;
3779 }
3780 final char op = arg.charAt(0);
3781 final String pkg = arg.substring(1);
3782 switch (op) {
3783 case '+':
3784 if (restoreSystemPowerWhitelistAppInternal(pkg)) {
3785 pw.println("Restored " + pkg);
3786 }
3787 break;
3788 case '-':
3789 if (removeSystemPowerWhitelistAppInternal(pkg)) {
3790 pw.println("Removed " + pkg);
3791 }
3792 break;
3793 }
3794 } while ((arg = shell.getNextArg()) != null);
3795 }
3796 } finally {
3797 Binder.restoreCallingIdentity(token);
3798 }
3799 } else {
3800 synchronized (this) {
Amith Yamasani4cb42572018-04-27 10:02:57 -07003801 for (int j = 0; j < mPowerSaveWhitelistApps.size(); j++) {
Suprabh Shukla08105642017-09-26 14:45:30 -07003802 pw.print(mPowerSaveWhitelistApps.keyAt(j));
3803 pw.print(",");
3804 pw.println(mPowerSaveWhitelistApps.valueAt(j));
3805 }
3806 }
3807 }
Amith Yamasani4cb42572018-04-27 10:02:57 -07003808 } else if ("motion".equals(cmd)) {
3809 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3810 null);
3811 synchronized (this) {
3812 long token = Binder.clearCallingIdentity();
3813 try {
3814 motionLocked();
3815 pw.print("Light state: ");
3816 pw.print(lightStateToString(mLightState));
3817 pw.print(", deep state: ");
3818 pw.println(stateToString(mState));
3819 } finally {
3820 Binder.restoreCallingIdentity(token);
3821 }
3822 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003823 } else {
3824 return shell.handleDefaultCommands(cmd);
3825 }
3826 return 0;
3827 }
3828
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003829 void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06003830 if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003831
3832 if (args != null) {
Xiaohui Chen7c696362015-09-16 09:56:14 -07003833 int userId = UserHandle.USER_SYSTEM;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003834 for (int i=0; i<args.length; i++) {
3835 String arg = args[i];
3836 if ("-h".equals(arg)) {
3837 dumpHelp(pw);
3838 return;
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003839 } else if ("-u".equals(arg)) {
3840 i++;
3841 if (i < args.length) {
3842 arg = args[i];
3843 userId = Integer.parseInt(arg);
3844 }
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003845 } else if ("-a".equals(arg)) {
3846 // Ignore, we always dump all.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003847 } else if (arg.length() > 0 && arg.charAt(0) == '-'){
3848 pw.println("Unknown option: " + arg);
3849 return;
3850 } else {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003851 Shell shell = new Shell();
3852 shell.userId = userId;
3853 String[] newArgs = new String[args.length-i];
3854 System.arraycopy(args, i, newArgs, 0, args.length-i);
Dianne Hackborn354736e2016-08-22 17:00:05 -07003855 shell.exec(mBinderService, null, fd, null, newArgs, null,
3856 new ResultReceiver(null));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003857 return;
3858 }
3859 }
3860 }
3861
3862 synchronized (this) {
Dianne Hackborna750a632015-06-16 17:18:23 -07003863 mConstants.dump(pw);
3864
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08003865 if (mEventCmds[0] != EVENT_NULL) {
3866 pw.println(" Idling history:");
3867 long now = SystemClock.elapsedRealtime();
3868 for (int i=EVENT_BUFFER_SIZE-1; i>=0; i--) {
3869 int cmd = mEventCmds[i];
3870 if (cmd == EVENT_NULL) {
3871 continue;
3872 }
3873 String label;
3874 switch (mEventCmds[i]) {
3875 case EVENT_NORMAL: label = " normal"; break;
3876 case EVENT_LIGHT_IDLE: label = " light-idle"; break;
3877 case EVENT_LIGHT_MAINTENANCE: label = "light-maint"; break;
Dianne Hackbornb6843652016-02-22 12:20:13 -08003878 case EVENT_DEEP_IDLE: label = " deep-idle"; break;
3879 case EVENT_DEEP_MAINTENANCE: label = " deep-maint"; break;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08003880 default: label = " ??"; break;
3881 }
3882 pw.print(" ");
3883 pw.print(label);
3884 pw.print(": ");
Amith Yamasaniac6517a2018-04-23 12:19:34 -07003885 TimeUtils.formatDuration(mEventTimes[i], now, pw);
3886 if (mEventReasons[i] != null) {
3887 pw.print(" (");
3888 pw.print(mEventReasons[i]);
3889 pw.print(")");
3890 }
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08003891 pw.println();
Amith Yamasaniac6517a2018-04-23 12:19:34 -07003892
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08003893 }
3894 }
3895
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003896 int size = mPowerSaveWhitelistAppsExceptIdle.size();
3897 if (size > 0) {
3898 pw.println(" Whitelist (except idle) system apps:");
3899 for (int i = 0; i < size; i++) {
3900 pw.print(" ");
3901 pw.println(mPowerSaveWhitelistAppsExceptIdle.keyAt(i));
3902 }
3903 }
3904 size = mPowerSaveWhitelistApps.size();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003905 if (size > 0) {
3906 pw.println(" Whitelist system apps:");
3907 for (int i = 0; i < size; i++) {
3908 pw.print(" ");
3909 pw.println(mPowerSaveWhitelistApps.keyAt(i));
3910 }
3911 }
Suprabh Shukla08105642017-09-26 14:45:30 -07003912 size = mRemovedFromSystemWhitelistApps.size();
3913 if (size > 0) {
3914 pw.println(" Removed from whitelist system apps:");
3915 for (int i = 0; i < size; i++) {
3916 pw.print(" ");
3917 pw.println(mRemovedFromSystemWhitelistApps.keyAt(i));
3918 }
3919 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003920 size = mPowerSaveWhitelistUserApps.size();
3921 if (size > 0) {
3922 pw.println(" Whitelist user apps:");
3923 for (int i = 0; i < size; i++) {
3924 pw.print(" ");
3925 pw.println(mPowerSaveWhitelistUserApps.keyAt(i));
3926 }
3927 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003928 size = mPowerSaveWhitelistExceptIdleAppIds.size();
3929 if (size > 0) {
3930 pw.println(" Whitelist (except idle) all app ids:");
3931 for (int i = 0; i < size; i++) {
3932 pw.print(" ");
3933 pw.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
3934 pw.println();
3935 }
3936 }
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08003937 size = mPowerSaveWhitelistUserAppIds.size();
3938 if (size > 0) {
3939 pw.println(" Whitelist user app ids:");
3940 for (int i = 0; i < size; i++) {
3941 pw.print(" ");
3942 pw.print(mPowerSaveWhitelistUserAppIds.keyAt(i));
3943 pw.println();
3944 }
3945 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07003946 size = mPowerSaveWhitelistAllAppIds.size();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003947 if (size > 0) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07003948 pw.println(" Whitelist all app ids:");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003949 for (int i = 0; i < size; i++) {
Dianne Hackborna750a632015-06-16 17:18:23 -07003950 pw.print(" ");
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07003951 pw.print(mPowerSaveWhitelistAllAppIds.keyAt(i));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003952 pw.println();
3953 }
3954 }
Felipe Lemea1b79bf2016-05-24 13:06:54 -07003955 dumpTempWhitelistSchedule(pw, true);
3956
Dianne Hackborna750a632015-06-16 17:18:23 -07003957 size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0;
3958 if (size > 0) {
3959 pw.println(" Temp whitelist app ids:");
3960 for (int i = 0; i < size; i++) {
3961 pw.print(" ");
3962 pw.print(mTempWhitelistAppIdArray[i]);
3963 pw.println();
3964 }
3965 }
Adam Lesinski31c05d12015-06-09 17:34:04 -07003966
Dianne Hackbornb6843652016-02-22 12:20:13 -08003967 pw.print(" mLightEnabled="); pw.print(mLightEnabled);
Felipe Lemea1b79bf2016-05-24 13:06:54 -07003968 pw.print(" mDeepEnabled="); pw.println(mDeepEnabled);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003969 pw.print(" mForceIdle="); pw.println(mForceIdle);
Robin Leec4d424c2018-12-07 15:09:13 +01003970 pw.print(" mUseMotionSensor="); pw.print(mUseMotionSensor);
3971 if (mUseMotionSensor) {
3972 pw.print(" mMotionSensor="); pw.println(mMotionSensor);
3973 } else {
3974 pw.println();
3975 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003976 pw.print(" mScreenOn="); pw.println(mScreenOn);
Amith Yamasani396a10c2018-01-19 10:58:07 -08003977 pw.print(" mScreenLocked="); pw.println(mScreenLocked);
Dianne Hackborn88c41352016-04-07 15:18:58 -07003978 pw.print(" mNetworkConnected="); pw.println(mNetworkConnected);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003979 pw.print(" mCharging="); pw.println(mCharging);
Robin Lee876b88542018-11-13 17:22:24 +01003980 if (mConstraints.size() != 0) {
3981 pw.println(" mConstraints={");
3982 for (int i = 0; i < mConstraints.size(); i++) {
3983 final DeviceIdleConstraintTracker tracker = mConstraints.valueAt(i);
3984 pw.print(" \""); pw.print(tracker.name); pw.print("\"=");
3985 if (tracker.minState == mState) {
3986 pw.println(tracker.active);
3987 } else {
3988 pw.print("ignored <mMinState="); pw.print(stateToString(tracker.minState));
3989 pw.println(">");
3990 }
3991 }
3992 pw.println(" }");
3993 }
Robin Leec4d424c2018-12-07 15:09:13 +01003994 if (mUseMotionSensor) {
Robin Lee876b88542018-11-13 17:22:24 +01003995 pw.print(" mMotionActive="); pw.println(mMotionListener.active);
Robin Leec4d424c2018-12-07 15:09:13 +01003996 pw.print(" mNotMoving="); pw.println(mNotMoving);
3997 }
Joe LaPenna23d681b2015-08-27 15:12:11 -07003998 pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHasGps=");
3999 pw.print(mHasGps); pw.print(" mHasNetwork=");
4000 pw.print(mHasNetworkLocation); pw.print(" mLocated="); pw.println(mLocated);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07004001 if (mLastGenericLocation != null) {
4002 pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation);
4003 }
4004 if (mLastGpsLocation != null) {
4005 pw.print(" mLastGpsLocation="); pw.println(mLastGpsLocation);
4006 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004007 pw.print(" mState="); pw.print(stateToString(mState));
4008 pw.print(" mLightState=");
4009 pw.println(lightStateToString(mLightState));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004010 pw.print(" mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw);
4011 pw.println();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08004012 if (mActiveIdleOpCount != 0) {
4013 pw.print(" mActiveIdleOpCount="); pw.println(mActiveIdleOpCount);
4014 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004015 if (mNextAlarmTime != 0) {
4016 pw.print(" mNextAlarmTime=");
4017 TimeUtils.formatDuration(mNextAlarmTime, SystemClock.elapsedRealtime(), pw);
4018 pw.println();
4019 }
4020 if (mNextIdlePendingDelay != 0) {
4021 pw.print(" mNextIdlePendingDelay=");
4022 TimeUtils.formatDuration(mNextIdlePendingDelay, pw);
4023 pw.println();
4024 }
4025 if (mNextIdleDelay != 0) {
4026 pw.print(" mNextIdleDelay=");
4027 TimeUtils.formatDuration(mNextIdleDelay, pw);
4028 pw.println();
4029 }
Dianne Hackborn953fc942016-03-29 15:36:24 -07004030 if (mNextLightIdleDelay != 0) {
4031 pw.print(" mNextIdleDelay=");
4032 TimeUtils.formatDuration(mNextLightIdleDelay, pw);
4033 pw.println();
4034 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004035 if (mNextLightAlarmTime != 0) {
4036 pw.print(" mNextLightAlarmTime=");
4037 TimeUtils.formatDuration(mNextLightAlarmTime, SystemClock.elapsedRealtime(), pw);
4038 pw.println();
4039 }
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08004040 if (mCurIdleBudget != 0) {
4041 pw.print(" mCurIdleBudget=");
4042 TimeUtils.formatDuration(mCurIdleBudget, pw);
4043 pw.println();
4044 }
4045 if (mMaintenanceStartTime != 0) {
4046 pw.print(" mMaintenanceStartTime=");
4047 TimeUtils.formatDuration(mMaintenanceStartTime, SystemClock.elapsedRealtime(), pw);
4048 pw.println();
4049 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08004050 if (mJobsActive) {
4051 pw.print(" mJobsActive="); pw.println(mJobsActive);
4052 }
4053 if (mAlarmsActive) {
4054 pw.print(" mAlarmsActive="); pw.println(mAlarmsActive);
4055 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07004056 }
4057 }
Felipe Lemea1b79bf2016-05-24 13:06:54 -07004058
4059 void dumpTempWhitelistSchedule(PrintWriter pw, boolean printTitle) {
4060 final int size = mTempWhitelistAppIdEndTimes.size();
4061 if (size > 0) {
4062 String prefix = "";
4063 if (printTitle) {
4064 pw.println(" Temp whitelist schedule:");
4065 prefix = " ";
4066 }
4067 final long timeNow = SystemClock.elapsedRealtime();
4068 for (int i = 0; i < size; i++) {
4069 pw.print(prefix);
4070 pw.print("UID=");
4071 pw.print(mTempWhitelistAppIdEndTimes.keyAt(i));
4072 pw.print(": ");
4073 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.valueAt(i);
4074 TimeUtils.formatDuration(entry.first.value, timeNow, pw);
4075 pw.print(" - ");
4076 pw.println(entry.second);
4077 }
4078 }
4079 }
4080 }