blob: 376bc0df1d876abc588b1ee5b50f11609e4e287a [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;
Dianne Hackbornfd854ee2015-07-13 18:00:37 -070046import android.os.BatteryStats;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070047import android.os.Binder;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -070048import android.os.Bundle;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070049import android.os.Environment;
50import android.os.FileUtils;
51import android.os.Handler;
52import android.os.IDeviceIdleController;
Yao Chenca5edbb2016-01-13 14:44:36 -080053import android.os.IMaintenanceActivityListener;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070054import android.os.Looper;
55import android.os.Message;
56import android.os.PowerManager;
57import android.os.PowerManagerInternal;
Dianne Hackbornb6683c42015-06-18 17:40:33 -070058import android.os.Process;
Yao Chenca5edbb2016-01-13 14:44:36 -080059import android.os.RemoteCallbackList;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070060import android.os.RemoteException;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070061import android.os.ResultReceiver;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070062import android.os.ServiceManager;
Dianne Hackborn354736e2016-08-22 17:00:05 -070063import android.os.ShellCallback;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070064import android.os.ShellCommand;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070065import android.os.SystemClock;
66import android.os.UserHandle;
Adam Lesinski31c05d12015-06-09 17:34:04 -070067import android.provider.Settings;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070068import android.util.ArrayMap;
69import android.util.ArraySet;
Adam Lesinski31c05d12015-06-09 17:34:04 -070070import android.util.KeyValueListParser;
Dianne Hackbornfd854ee2015-07-13 18:00:37 -070071import android.util.MutableLong;
72import android.util.Pair;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070073import android.util.Slog;
Dianne Hackbornfd854ee2015-07-13 18:00:37 -070074import android.util.SparseArray;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070075import android.util.SparseBooleanArray;
76import android.util.TimeUtils;
77import android.util.Xml;
Amith Yamasani520d8f22015-05-08 16:36:21 -070078
Sudheer Shanka326b3112017-11-27 14:40:57 -080079import com.android.internal.annotations.GuardedBy;
Kweku Adams00e3a372018-09-28 16:57:09 -070080import com.android.internal.annotations.VisibleForTesting;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070081import com.android.internal.app.IBatteryStats;
82import com.android.internal.os.AtomicFile;
83import com.android.internal.os.BackgroundThread;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060084import com.android.internal.util.DumpUtils;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070085import com.android.internal.util.FastXmlSerializer;
86import com.android.internal.util.XmlUtils;
87import com.android.server.am.BatteryStatsService;
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -070088import com.android.server.net.NetworkPolicyManagerInternal;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070089import com.android.server.wm.ActivityTaskManagerInternal;
Amith Yamasani520d8f22015-05-08 16:36:21 -070090
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070091import org.xmlpull.v1.XmlPullParser;
92import org.xmlpull.v1.XmlPullParserException;
93import org.xmlpull.v1.XmlSerializer;
94
95import java.io.ByteArrayOutputStream;
96import java.io.File;
97import java.io.FileDescriptor;
98import java.io.FileInputStream;
99import java.io.FileNotFoundException;
100import java.io.FileOutputStream;
101import java.io.IOException;
102import java.io.PrintWriter;
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +0100103import java.nio.charset.StandardCharsets;
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700104import java.util.Arrays;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700105
106/**
107 * Keeps track of device idleness and drives low power mode based on that.
Kweku Adams00e3a372018-09-28 16:57:09 -0700108 *
109 * Test: atest com.android.server.DeviceIdleControllerTest
Kweku Adamsf596cfc2018-10-04 15:15:22 -0700110 *
111 * Current idling state machine (as of Android 9 Pie). This can be visualized using Graphviz:
112
113 digraph {
114 subgraph deep {
115 label="deep";
116
117 STATE_ACTIVE [label="STATE_ACTIVE\nScreen on OR Charging OR Alarm going off soon"]
118 STATE_INACTIVE [label="STATE_INACTIVE\nScreen off AND Not charging"]
119 STATE_IDLE_PENDING [
120 label="STATE_IDLE_PENDING\nSignificant motion monitoring turned on"
121 ]
122 STATE_SENSING [label="STATE_SENSING\nMonitoring for ANY motion"]
123 STATE_LOCATING [
124 label="STATE_LOCATING\nRequesting location, motion monitoring still on"
125 ]
126 STATE_IDLE [
127 label="STATE_IDLE\nLocation and motion detection turned off\n"
128 + "Significant motion monitoring still on"
129 ]
130 STATE_IDLE_MAINTENANCE [label="STATE_IDLE_MAINTENANCE\n"]
131
132 STATE_ACTIVE -> STATE_INACTIVE [label="becomeInactiveIfAppropriateLocked()"]
133
134 STATE_INACTIVE -> STATE_ACTIVE [
135 label="handleMotionDetectedLocked(), becomeActiveLocked()"
136 ]
137 STATE_INACTIVE -> STATE_IDLE_PENDING [label="stepIdleStateLocked()"]
138
139 STATE_IDLE_PENDING -> STATE_ACTIVE [
140 label="handleMotionDetectedLocked(), becomeActiveLocked()"
141 ]
142 STATE_IDLE_PENDING -> STATE_SENSING [label="stepIdleStateLocked()"]
143
144 STATE_SENSING -> STATE_ACTIVE [
145 label="handleMotionDetectedLocked(), becomeActiveLocked()"
146 ]
147 STATE_SENSING -> STATE_LOCATING [label="stepIdleStateLocked()"]
148 STATE_SENSING -> STATE_IDLE [
149 label="stepIdleStateLocked()\n"
150 + "No Location Manager OR (no Network provider AND no GPS provider)"
151 ]
152
153 STATE_LOCATING -> STATE_ACTIVE [
154 label="handleMotionDetectedLocked(), becomeActiveLocked()"
155 ]
156 STATE_LOCATING -> STATE_IDLE [label="stepIdleStateLocked()"]
157
158 STATE_IDLE -> STATE_ACTIVE [label="handleMotionDetectedLocked(), becomeActiveLocked()"]
159 STATE_IDLE -> STATE_IDLE_MAINTENANCE [label="stepIdleStateLocked()"]
160
161 STATE_IDLE_MAINTENANCE -> STATE_ACTIVE [
162 label="handleMotionDetectedLocked(), becomeActiveLocked()"
163 ]
164 STATE_IDLE_MAINTENANCE -> STATE_IDLE [
165 label="stepIdleStateLocked(), exitMaintenanceEarlyIfNeededLocked()"
166 ]
167 }
168
169 subgraph light {
170 label="light"
171
172 LIGHT_STATE_ACTIVE [
173 label="LIGHT_STATE_ACTIVE\nScreen on OR Charging OR Alarm going off soon"
174 ]
175 LIGHT_STATE_INACTIVE [label="LIGHT_STATE_INACTIVE\nScreen off AND Not charging"]
176 LIGHT_STATE_PRE_IDLE [
177 label="LIGHT_STATE_PRE_IDLE\n"
178 + "Delay going into LIGHT_STATE_IDLE due to some running jobs or alarms"
179 ]
180 LIGHT_STATE_IDLE [label="LIGHT_STATE_IDLE\n"]
181 LIGHT_STATE_WAITING_FOR_NETWORK [
182 label="LIGHT_STATE_WAITING_FOR_NETWORK\n"
183 + "Coming out of LIGHT_STATE_IDLE, waiting for network"
184 ]
185 LIGHT_STATE_IDLE_MAINTENANCE [label="LIGHT_STATE_IDLE_MAINTENANCE\n"]
186 LIGHT_STATE_OVERRIDE [
187 label="LIGHT_STATE_OVERRIDE\nDevice in deep doze, light no longer changing states"
188 ]
189
190 LIGHT_STATE_ACTIVE -> LIGHT_STATE_INACTIVE [
191 label="becomeInactiveIfAppropriateLocked()"
192 ]
193 LIGHT_STATE_ACTIVE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"]
194
195 LIGHT_STATE_INACTIVE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"]
196 LIGHT_STATE_INACTIVE -> LIGHT_STATE_PRE_IDLE [label="active jobs"]
197 LIGHT_STATE_INACTIVE -> LIGHT_STATE_IDLE [label="no active jobs"]
198 LIGHT_STATE_INACTIVE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"]
199
200 LIGHT_STATE_PRE_IDLE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"]
201 LIGHT_STATE_PRE_IDLE -> LIGHT_STATE_IDLE [
202 label="stepLightIdleStateLocked(), exitMaintenanceEarlyIfNeededLocked()"
203 ]
204 LIGHT_STATE_PRE_IDLE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"]
205
206 LIGHT_STATE_IDLE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"]
207 LIGHT_STATE_IDLE -> LIGHT_STATE_WAITING_FOR_NETWORK [label="no network"]
208 LIGHT_STATE_IDLE -> LIGHT_STATE_IDLE_MAINTENANCE
209 LIGHT_STATE_IDLE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"]
210
211 LIGHT_STATE_WAITING_FOR_NETWORK -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"]
212 LIGHT_STATE_WAITING_FOR_NETWORK -> LIGHT_STATE_IDLE_MAINTENANCE
213 LIGHT_STATE_WAITING_FOR_NETWORK -> LIGHT_STATE_OVERRIDE [
214 label="deep goes to STATE_IDLE"
215 ]
216
217 LIGHT_STATE_IDLE_MAINTENANCE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"]
218 LIGHT_STATE_IDLE_MAINTENANCE -> LIGHT_STATE_IDLE [
219 label="stepLightIdleStateLocked(), exitMaintenanceEarlyIfNeededLocked()"
220 ]
221 LIGHT_STATE_IDLE_MAINTENANCE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"]
222
223 LIGHT_STATE_OVERRIDE -> LIGHT_STATE_ACTIVE [
224 label="handleMotionDetectedLocked(), becomeActiveLocked()"
225 ]
226 }
227 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700228 */
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700229public class DeviceIdleController extends SystemService
230 implements AnyMotionDetector.DeviceIdleCallback {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700231 private static final String TAG = "DeviceIdleController";
232
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700233 private static final boolean DEBUG = false;
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700234
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700235 private static final boolean COMPRESS_TIME = false;
Amith Yamasani520d8f22015-05-08 16:36:21 -0700236
Dianne Hackborn953fc942016-03-29 15:36:24 -0700237 private static final int EVENT_BUFFER_SIZE = 100;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800238
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700239 private AlarmManager mAlarmManager;
240 private IBatteryStats mBatteryStats;
Dianne Hackborn85e35642017-01-12 15:10:57 -0800241 private ActivityManagerInternal mLocalActivityManager;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700242 private ActivityTaskManagerInternal mLocalActivityTaskManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700243 private PowerManagerInternal mLocalPowerManager;
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700244 private PowerManager mPowerManager;
Dianne Hackborn88c41352016-04-07 15:18:58 -0700245 private ConnectivityService mConnectivityService;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700246 private INetworkPolicyManager mNetworkPolicyManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700247 private SensorManager mSensorManager;
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700248 private Sensor mMotionSensor;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700249 private LocationManager mLocationManager;
250 private LocationRequest mLocationRequest;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700251 private Intent mIdleIntent;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700252 private Intent mLightIdleIntent;
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700253 private AnyMotionDetector mAnyMotionDetector;
Makoto Onukie4918212018-02-06 11:30:15 -0800254 private final AppStateTracker mAppStateTracker;
Dianne Hackbornb6843652016-02-22 12:20:13 -0800255 private boolean mLightEnabled;
256 private boolean mDeepEnabled;
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700257 private boolean mForceIdle;
Dianne Hackborn88c41352016-04-07 15:18:58 -0700258 private boolean mNetworkConnected;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700259 private boolean mScreenOn;
260 private boolean mCharging;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700261 private boolean mNotMoving;
262 private boolean mLocating;
263 private boolean mLocated;
Joe LaPenna23d681b2015-08-27 15:12:11 -0700264 private boolean mHasGps;
265 private boolean mHasNetworkLocation;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700266 private Location mLastGenericLocation;
267 private Location mLastGpsLocation;
Amith Yamasani396a10c2018-01-19 10:58:07 -0800268 // Current locked state of the screen
269 private boolean mScreenLocked;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700270
271 /** Device is currently active. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700272 @VisibleForTesting
273 static final int STATE_ACTIVE = 0;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700274 /** Device is inactive (screen off, no motion) and we are waiting to for idle. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700275 @VisibleForTesting
276 static final int STATE_INACTIVE = 1;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700277 /** Device is past the initial inactive period, and waiting for the next idle period. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700278 @VisibleForTesting
279 static final int STATE_IDLE_PENDING = 2;
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700280 /** Device is currently sensing motion. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700281 @VisibleForTesting
282 static final int STATE_SENSING = 3;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700283 /** Device is currently finding location (and may still be sensing). */
Kweku Adams00e3a372018-09-28 16:57:09 -0700284 @VisibleForTesting
285 static final int STATE_LOCATING = 4;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700286 /** Device is in the idle state, trying to stay asleep as much as possible. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700287 @VisibleForTesting
288 static final int STATE_IDLE = 5;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700289 /** Device is in the idle state, but temporarily out of idle to do regular maintenance. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700290 @VisibleForTesting
291 static final int STATE_IDLE_MAINTENANCE = 6;
Amith Yamasani396a10c2018-01-19 10:58:07 -0800292
Kweku Adams00e3a372018-09-28 16:57:09 -0700293 @VisibleForTesting
294 static String stateToString(int state) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700295 switch (state) {
296 case STATE_ACTIVE: return "ACTIVE";
297 case STATE_INACTIVE: return "INACTIVE";
298 case STATE_IDLE_PENDING: return "IDLE_PENDING";
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700299 case STATE_SENSING: return "SENSING";
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700300 case STATE_LOCATING: return "LOCATING";
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700301 case STATE_IDLE: return "IDLE";
302 case STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE";
303 default: return Integer.toString(state);
304 }
305 }
306
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700307 /** Device is currently active. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700308 @VisibleForTesting
309 static final int LIGHT_STATE_ACTIVE = 0;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700310 /** Device is inactive (screen off) and we are waiting to for the first light idle. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700311 @VisibleForTesting
312 static final int LIGHT_STATE_INACTIVE = 1;
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700313 /** Device is about to go idle for the first time, wait for current work to complete. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700314 @VisibleForTesting
315 static final int LIGHT_STATE_PRE_IDLE = 3;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700316 /** Device is in the light idle state, trying to stay asleep as much as possible. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700317 @VisibleForTesting
318 static final int LIGHT_STATE_IDLE = 4;
Dianne Hackborn88c41352016-04-07 15:18:58 -0700319 /** Device is in the light idle state, we want to go in to idle maintenance but are
320 * waiting for network connectivity before doing so. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700321 @VisibleForTesting
322 static final int LIGHT_STATE_WAITING_FOR_NETWORK = 5;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700323 /** Device is in the light idle state, but temporarily out of idle to do regular maintenance. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700324 @VisibleForTesting
325 static final int LIGHT_STATE_IDLE_MAINTENANCE = 6;
Dianne Hackbornb6843652016-02-22 12:20:13 -0800326 /** Device light idle state is overriden, now applying deep doze state. */
Kweku Adams00e3a372018-09-28 16:57:09 -0700327 @VisibleForTesting
328 static final int LIGHT_STATE_OVERRIDE = 7;
329
330 @VisibleForTesting
331 static String lightStateToString(int state) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700332 switch (state) {
333 case LIGHT_STATE_ACTIVE: return "ACTIVE";
334 case LIGHT_STATE_INACTIVE: return "INACTIVE";
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700335 case LIGHT_STATE_PRE_IDLE: return "PRE_IDLE";
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700336 case LIGHT_STATE_IDLE: return "IDLE";
Dianne Hackborn88c41352016-04-07 15:18:58 -0700337 case LIGHT_STATE_WAITING_FOR_NETWORK: return "WAITING_FOR_NETWORK";
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700338 case LIGHT_STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE";
339 case LIGHT_STATE_OVERRIDE: return "OVERRIDE";
340 default: return Integer.toString(state);
341 }
342 }
343
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700344 private int mState;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700345 private int mLightState;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700346
347 private long mInactiveTimeout;
348 private long mNextAlarmTime;
349 private long mNextIdlePendingDelay;
350 private long mNextIdleDelay;
Dianne Hackborn953fc942016-03-29 15:36:24 -0700351 private long mNextLightIdleDelay;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700352 private long mNextLightAlarmTime;
Kevin Gabayan92f15e62016-04-04 17:52:22 -0700353 private long mNextSensingTimeoutAlarmTime;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800354 private long mCurIdleBudget;
355 private long mMaintenanceStartTime;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700356
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800357 private int mActiveIdleOpCount;
Joe Onorato8f0e9ced2016-12-08 17:48:49 -0800358 private PowerManager.WakeLock mActiveIdleWakeLock; // held when there are operations in progress
359 private PowerManager.WakeLock mGoingIdleWakeLock; // held when we are going idle so hardware
360 // (especially NetworkPolicyManager) can shut
361 // down.
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800362 private boolean mJobsActive;
363 private boolean mAlarmsActive;
Yao Chenca5edbb2016-01-13 14:44:36 -0800364 private boolean mReportedMaintenanceActivity;
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800365
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700366 public final AtomicFile mConfigFile;
367
Yao Chenca5edbb2016-01-13 14:44:36 -0800368 private final RemoteCallbackList<IMaintenanceActivityListener> mMaintenanceActivityListeners =
369 new RemoteCallbackList<IMaintenanceActivityListener>();
370
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700371 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700372 * Package names the system has white-listed to opt out of power save restrictions,
373 * except for device idle mode.
374 */
375 private final ArrayMap<String, Integer> mPowerSaveWhitelistAppsExceptIdle = new ArrayMap<>();
376
377 /**
Sudheer Shanka3f4d7702017-04-28 17:38:03 -0700378 * Package names the user has white-listed using commandline option to opt out of
379 * power save restrictions, except for device idle mode.
380 */
381 private final ArraySet<String> mPowerSaveWhitelistUserAppsExceptIdle = new ArraySet<>();
382
383 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700384 * Package names the system has white-listed to opt out of power save restrictions for
385 * all modes.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700386 */
387 private final ArrayMap<String, Integer> mPowerSaveWhitelistApps = new ArrayMap<>();
388
389 /**
390 * Package names the user has white-listed to opt out of power save restrictions.
391 */
392 private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>();
393
394 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700395 * App IDs of built-in system apps that have been white-listed except for idle modes.
396 */
397 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIdsExceptIdle
398 = new SparseBooleanArray();
399
400 /**
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700401 * App IDs of built-in system apps that have been white-listed.
402 */
403 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray();
404
405 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700406 * App IDs that have been white-listed to opt out of power save restrictions, except
407 * for device idle modes.
408 */
409 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
410
411 /**
412 * Current app IDs that are in the complete power save white list, but shouldn't be
413 * excluded from idle modes. This array can be shared with others because it will not be
414 * modified once set.
415 */
416 private int[] mPowerSaveWhitelistExceptIdleAppIdArray = new int[0];
417
418 /**
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700419 * App IDs that have been white-listed to opt out of power save restrictions.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700420 */
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700421 private final SparseBooleanArray mPowerSaveWhitelistAllAppIds = new SparseBooleanArray();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700422
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700423 /**
424 * Current app IDs that are in the complete power save white list. This array can
425 * be shared with others because it will not be modified once set.
426 */
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700427 private int[] mPowerSaveWhitelistAllAppIdArray = new int[0];
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700428
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700429 /**
Dianne Hackborn262ae5c2016-02-10 16:28:29 -0800430 * App IDs that have been white-listed by the user to opt out of power save restrictions.
431 */
432 private final SparseBooleanArray mPowerSaveWhitelistUserAppIds = new SparseBooleanArray();
433
434 /**
435 * Current app IDs that are in the user power save white list. This array can
436 * be shared with others because it will not be modified once set.
437 */
438 private int[] mPowerSaveWhitelistUserAppIdArray = new int[0];
439
440 /**
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700441 * List of end times for UIDs that are temporarily marked as being allowed to access
442 * the network and acquire wakelocks. Times are in milliseconds.
443 */
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700444 private final SparseArray<Pair<MutableLong, String>> mTempWhitelistAppIdEndTimes
445 = new SparseArray<>();
446
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -0700447 private NetworkPolicyManagerInternal mNetworkPolicyManagerInternal;
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700448
449 /**
450 * Current app IDs of temporarily whitelist apps for high-priority messages.
451 */
452 private int[] mTempWhitelistAppIdArray = new int[0];
453
Suprabh Shukla08105642017-09-26 14:45:30 -0700454 /**
455 * Apps in the system whitelist that have been taken out (probably because the user wanted to).
456 * They can be restored back by calling restoreAppToSystemWhitelist(String).
457 */
458 private ArrayMap<String, Integer> mRemovedFromSystemWhitelistApps = new ArrayMap<>();
459
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800460 private static final int EVENT_NULL = 0;
461 private static final int EVENT_NORMAL = 1;
462 private static final int EVENT_LIGHT_IDLE = 2;
463 private static final int EVENT_LIGHT_MAINTENANCE = 3;
Dianne Hackbornb6843652016-02-22 12:20:13 -0800464 private static final int EVENT_DEEP_IDLE = 4;
465 private static final int EVENT_DEEP_MAINTENANCE = 5;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800466
Dianne Hackbornef3aa6e2016-04-29 18:18:08 -0700467 private final int[] mEventCmds = new int[EVENT_BUFFER_SIZE];
468 private final long[] mEventTimes = new long[EVENT_BUFFER_SIZE];
Amith Yamasaniac6517a2018-04-23 12:19:34 -0700469 private final String[] mEventReasons = new String[EVENT_BUFFER_SIZE];
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800470
Amith Yamasaniac6517a2018-04-23 12:19:34 -0700471 private void addEvent(int cmd, String reason) {
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800472 if (mEventCmds[0] != cmd) {
473 System.arraycopy(mEventCmds, 0, mEventCmds, 1, EVENT_BUFFER_SIZE - 1);
474 System.arraycopy(mEventTimes, 0, mEventTimes, 1, EVENT_BUFFER_SIZE - 1);
Amith Yamasaniac6517a2018-04-23 12:19:34 -0700475 System.arraycopy(mEventReasons, 0, mEventReasons, 1, EVENT_BUFFER_SIZE - 1);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800476 mEventCmds[0] = cmd;
477 mEventTimes[0] = SystemClock.elapsedRealtime();
Amith Yamasaniac6517a2018-04-23 12:19:34 -0700478 mEventReasons[0] = reason;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800479 }
480 }
481
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700482 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
483 @Override public void onReceive(Context context, Intent intent) {
Dianne Hackborn88c41352016-04-07 15:18:58 -0700484 switch (intent.getAction()) {
485 case ConnectivityManager.CONNECTIVITY_ACTION: {
Dianne Hackborn4cb96ca2016-05-17 13:55:29 -0700486 updateConnectivityState(intent);
Dianne Hackborn88c41352016-04-07 15:18:58 -0700487 } break;
488 case Intent.ACTION_BATTERY_CHANGED: {
489 synchronized (DeviceIdleController.this) {
490 int plugged = intent.getIntExtra("plugged", 0);
491 updateChargingLocked(plugged != 0);
492 }
493 } break;
494 case Intent.ACTION_PACKAGE_REMOVED: {
495 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
496 Uri data = intent.getData();
497 String ssp;
498 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
499 removePowerSaveWhitelistAppInternal(ssp);
500 }
501 }
502 } break;
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700503 }
504 }
505 };
506
507 private final AlarmManager.OnAlarmListener mLightAlarmListener
508 = new AlarmManager.OnAlarmListener() {
509 @Override
510 public void onAlarm() {
511 synchronized (DeviceIdleController.this) {
512 stepLightIdleStateLocked("s:alarm");
513 }
514 }
515 };
516
Kevin Gabayan92f15e62016-04-04 17:52:22 -0700517 private final AlarmManager.OnAlarmListener mSensingTimeoutAlarmListener
518 = new AlarmManager.OnAlarmListener() {
519 @Override
520 public void onAlarm() {
521 if (mState == STATE_SENSING) {
522 synchronized (DeviceIdleController.this) {
Kweku Adams00e3a372018-09-28 16:57:09 -0700523 // Restart the device idle progression in case the device moved but the screen
524 // didn't turn on.
Kevin Gabayan92f15e62016-04-04 17:52:22 -0700525 becomeInactiveIfAppropriateLocked();
526 }
527 }
528 }
529 };
530
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700531 private final AlarmManager.OnAlarmListener mDeepAlarmListener
532 = new AlarmManager.OnAlarmListener() {
533 @Override
534 public void onAlarm() {
535 synchronized (DeviceIdleController.this) {
536 stepIdleStateLocked("s:alarm");
537 }
538 }
539 };
540
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800541 private final BroadcastReceiver mIdleStartedDoneReceiver = new BroadcastReceiver() {
542 @Override public void onReceive(Context context, Intent intent) {
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700543 // When coming out of a deep idle, we will add in some delay before we allow
544 // the system to settle down and finish the maintenance window. This is
545 // to give a chance for any pending work to be scheduled.
546 if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(intent.getAction())) {
547 mHandler.sendEmptyMessageDelayed(MSG_FINISH_IDLE_OP,
548 mConstants.MIN_DEEP_MAINTENANCE_TIME);
549 } else {
550 mHandler.sendEmptyMessageDelayed(MSG_FINISH_IDLE_OP,
551 mConstants.MIN_LIGHT_MAINTENANCE_TIME);
552 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800553 }
554 };
555
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -0700556 private final BroadcastReceiver mInteractivityReceiver = new BroadcastReceiver() {
557 @Override
558 public void onReceive(Context context, Intent intent) {
Dianne Hackborn9b5ebc92017-09-08 13:45:35 -0700559 synchronized (DeviceIdleController.this) {
560 updateInteractivityLocked();
561 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700562 }
563 };
564
Kweku Adams00e3a372018-09-28 16:57:09 -0700565 @VisibleForTesting
566 final class MotionListener extends TriggerEventListener
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700567 implements SensorEventListener {
568
569 boolean active = false;
570
Kweku Adams00e3a372018-09-28 16:57:09 -0700571 public boolean isActive() {
572 return active;
573 }
574
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700575 @Override
576 public void onTrigger(TriggerEvent event) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700577 synchronized (DeviceIdleController.this) {
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700578 active = false;
579 motionLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700580 }
581 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700582
583 @Override
584 public void onSensorChanged(SensorEvent event) {
585 synchronized (DeviceIdleController.this) {
586 mSensorManager.unregisterListener(this, mMotionSensor);
587 active = false;
588 motionLocked();
589 }
590 }
591
592 @Override
593 public void onAccuracyChanged(Sensor sensor, int accuracy) {}
594
595 public boolean registerLocked() {
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700596 boolean success;
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700597 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
598 success = mSensorManager.requestTriggerSensor(mMotionListener, mMotionSensor);
599 } else {
600 success = mSensorManager.registerListener(
601 mMotionListener, mMotionSensor, SensorManager.SENSOR_DELAY_NORMAL);
602 }
603 if (success) {
604 active = true;
605 } else {
606 Slog.e(TAG, "Unable to register for " + mMotionSensor);
607 }
608 return success;
609 }
610
611 public void unregisterLocked() {
612 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
613 mSensorManager.cancelTriggerSensor(mMotionListener, mMotionSensor);
614 } else {
615 mSensorManager.unregisterListener(mMotionListener);
616 }
617 active = false;
618 }
619 }
Kweku Adams00e3a372018-09-28 16:57:09 -0700620 @VisibleForTesting final MotionListener mMotionListener = new MotionListener();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700621
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700622 private final LocationListener mGenericLocationListener = new LocationListener() {
623 @Override
624 public void onLocationChanged(Location location) {
625 synchronized (DeviceIdleController.this) {
626 receivedGenericLocationLocked(location);
627 }
628 }
629
630 @Override
631 public void onStatusChanged(String provider, int status, Bundle extras) {
632 }
633
634 @Override
635 public void onProviderEnabled(String provider) {
636 }
637
638 @Override
639 public void onProviderDisabled(String provider) {
640 }
641 };
642
643 private final LocationListener mGpsLocationListener = new LocationListener() {
644 @Override
645 public void onLocationChanged(Location location) {
646 synchronized (DeviceIdleController.this) {
647 receivedGpsLocationLocked(location);
648 }
649 }
650
651 @Override
652 public void onStatusChanged(String provider, int status, Bundle extras) {
653 }
654
655 @Override
656 public void onProviderEnabled(String provider) {
657 }
658
659 @Override
660 public void onProviderDisabled(String provider) {
661 }
662 };
663
Adam Lesinski31c05d12015-06-09 17:34:04 -0700664 /**
665 * All times are in milliseconds. These constants are kept synchronized with the system
666 * global Settings. Any access to this class or its fields should be done while
667 * holding the DeviceIdleController lock.
668 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700669 private final class Constants extends ContentObserver {
Adam Lesinski31c05d12015-06-09 17:34:04 -0700670 // Key names stored in the settings value.
Dianne Hackborn953fc942016-03-29 15:36:24 -0700671 private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT
672 = "light_after_inactive_to";
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700673 private static final String KEY_LIGHT_PRE_IDLE_TIMEOUT = "light_pre_idle_to";
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700674 private static final String KEY_LIGHT_IDLE_TIMEOUT = "light_idle_to";
Dianne Hackborn953fc942016-03-29 15:36:24 -0700675 private static final String KEY_LIGHT_IDLE_FACTOR = "light_idle_factor";
676 private static final String KEY_LIGHT_MAX_IDLE_TIMEOUT = "light_max_idle_to";
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800677 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET
678 = "light_idle_maintenance_min_budget";
679 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET
680 = "light_idle_maintenance_max_budget";
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700681 private static final String KEY_MIN_LIGHT_MAINTENANCE_TIME = "min_light_maintenance_time";
682 private static final String KEY_MIN_DEEP_MAINTENANCE_TIME = "min_deep_maintenance_time";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700683 private static final String KEY_INACTIVE_TIMEOUT = "inactive_to";
684 private static final String KEY_SENSING_TIMEOUT = "sensing_to";
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700685 private static final String KEY_LOCATING_TIMEOUT = "locating_to";
686 private static final String KEY_LOCATION_ACCURACY = "location_accuracy";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700687 private static final String KEY_MOTION_INACTIVE_TIMEOUT = "motion_inactive_to";
688 private static final String KEY_IDLE_AFTER_INACTIVE_TIMEOUT = "idle_after_inactive_to";
689 private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to";
690 private static final String KEY_MAX_IDLE_PENDING_TIMEOUT = "max_idle_pending_to";
691 private static final String KEY_IDLE_PENDING_FACTOR = "idle_pending_factor";
692 private static final String KEY_IDLE_TIMEOUT = "idle_to";
693 private static final String KEY_MAX_IDLE_TIMEOUT = "max_idle_to";
694 private static final String KEY_IDLE_FACTOR = "idle_factor";
695 private static final String KEY_MIN_TIME_TO_ALARM = "min_time_to_alarm";
696 private static final String KEY_MAX_TEMP_APP_WHITELIST_DURATION =
697 "max_temp_app_whitelist_duration";
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700698 private static final String KEY_MMS_TEMP_APP_WHITELIST_DURATION =
699 "mms_temp_app_whitelist_duration";
Dianne Hackborn451c3462015-07-21 17:39:46 -0700700 private static final String KEY_SMS_TEMP_APP_WHITELIST_DURATION =
701 "sms_temp_app_whitelist_duration";
Felipe Lemea1b79bf2016-05-24 13:06:54 -0700702 private static final String KEY_NOTIFICATION_WHITELIST_DURATION =
703 "notification_whitelist_duration";
Amith Yamasani396a10c2018-01-19 10:58:07 -0800704 /**
705 * Whether to wait for the user to unlock the device before causing screen-on to
706 * exit doze. Default = true
707 */
708 private static final String KEY_WAIT_FOR_UNLOCK = "wait_for_unlock";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700709
710 /**
Dianne Hackborn953fc942016-03-29 15:36:24 -0700711 * This is the time, after becoming inactive, that we go in to the first
712 * light-weight idle mode.
713 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
714 * @see #KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT
715 */
716 public long LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT;
717
718 /**
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700719 * This is amount of time we will wait from the point where we decide we would
720 * like to go idle until we actually do, while waiting for jobs and other current
721 * activity to finish.
722 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
723 * @see #KEY_LIGHT_PRE_IDLE_TIMEOUT
724 */
725 public long LIGHT_PRE_IDLE_TIMEOUT;
726
727 /**
Dianne Hackborn953fc942016-03-29 15:36:24 -0700728 * This is the initial time that we will run in idle maintenance mode.
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700729 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
730 * @see #KEY_LIGHT_IDLE_TIMEOUT
731 */
732 public long LIGHT_IDLE_TIMEOUT;
733
734 /**
Dianne Hackborn953fc942016-03-29 15:36:24 -0700735 * Scaling factor to apply to the light idle mode time each time we complete a cycle.
736 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
737 * @see #KEY_LIGHT_IDLE_FACTOR
738 */
739 public float LIGHT_IDLE_FACTOR;
740
741 /**
Kweku Adams00e3a372018-09-28 16:57:09 -0700742 * This is the maximum time we will run in idle maintenance mode.
Dianne Hackborn953fc942016-03-29 15:36:24 -0700743 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
744 * @see #KEY_LIGHT_MAX_IDLE_TIMEOUT
745 */
746 public long LIGHT_MAX_IDLE_TIMEOUT;
747
748 /**
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800749 * This is the minimum amount of time we want to make available for maintenance mode
750 * when lightly idling. That is, we will always have at least this amount of time
751 * available maintenance before timing out and cutting off maintenance mode.
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700752 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800753 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700754 */
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800755 public long LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
756
757 /**
758 * This is the maximum amount of time we want to make available for maintenance mode
759 * when lightly idling. That is, if the system isn't using up its minimum maintenance
760 * budget and this time is being added to the budget reserve, this is the maximum
761 * reserve size we will allow to grow and thus the maximum amount of time we will
762 * allow for the maintenance window.
763 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
764 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET
765 */
766 public long LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700767
768 /**
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700769 * This is the minimum amount of time that we will stay in maintenance mode after
770 * a light doze. We have this minimum to allow various things to respond to switching
771 * in to maintenance mode and scheduling their work -- otherwise we may
Dianne Hackborn7ab40252016-06-15 17:30:24 -0700772 * see there is nothing to do (no jobs pending) and go out of maintenance
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700773 * mode immediately.
774 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
775 * @see #KEY_MIN_LIGHT_MAINTENANCE_TIME
776 */
777 public long MIN_LIGHT_MAINTENANCE_TIME;
778
779 /**
780 * This is the minimum amount of time that we will stay in maintenance mode after
781 * a full doze. We have this minimum to allow various things to respond to switching
782 * in to maintenance mode and scheduling their work -- otherwise we may
Dianne Hackborn7ab40252016-06-15 17:30:24 -0700783 * see there is nothing to do (no jobs pending) and go out of maintenance
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700784 * mode immediately.
785 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
786 * @see #KEY_MIN_DEEP_MAINTENANCE_TIME
787 */
788 public long MIN_DEEP_MAINTENANCE_TIME;
789
790 /**
Adam Lesinski31c05d12015-06-09 17:34:04 -0700791 * This is the time, after becoming inactive, at which we start looking at the
792 * motion sensor to determine if the device is being left alone. We don't do this
793 * immediately after going inactive just because we don't want to be continually running
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700794 * the motion sensor whenever the screen is off.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700795 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
796 * @see #KEY_INACTIVE_TIMEOUT
797 */
798 public long INACTIVE_TIMEOUT;
799
800 /**
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700801 * If we don't receive a callback from AnyMotion in this amount of time +
802 * {@link #LOCATING_TIMEOUT}, we will change from
Adam Lesinski31c05d12015-06-09 17:34:04 -0700803 * STATE_SENSING to STATE_INACTIVE, and any AnyMotion callbacks while not in STATE_SENSING
804 * will be ignored.
805 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
806 * @see #KEY_SENSING_TIMEOUT
807 */
808 public long SENSING_TIMEOUT;
809
810 /**
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700811 * This is how long we will wait to try to get a good location fix before going in to
812 * idle mode.
813 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
814 * @see #KEY_LOCATING_TIMEOUT
815 */
816 public long LOCATING_TIMEOUT;
817
818 /**
819 * The desired maximum accuracy (in meters) we consider the location to be good enough to go
820 * on to idle. We will be trying to get an accuracy fix at least this good or until
821 * {@link #LOCATING_TIMEOUT} expires.
822 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
823 * @see #KEY_LOCATION_ACCURACY
824 */
825 public float LOCATION_ACCURACY;
826
827 /**
Adam Lesinski31c05d12015-06-09 17:34:04 -0700828 * This is the time, after seeing motion, that we wait after becoming inactive from
829 * that until we start looking for motion again.
830 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
831 * @see #KEY_MOTION_INACTIVE_TIMEOUT
832 */
833 public long MOTION_INACTIVE_TIMEOUT;
834
835 /**
836 * This is the time, after the inactive timeout elapses, that we will wait looking
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700837 * for motion until we truly consider the device to be idle.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700838 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
839 * @see #KEY_IDLE_AFTER_INACTIVE_TIMEOUT
840 */
841 public long IDLE_AFTER_INACTIVE_TIMEOUT;
842
843 /**
844 * This is the initial time, after being idle, that we will allow ourself to be back
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700845 * in the IDLE_MAINTENANCE state allowing the system to run normally until we return to
846 * idle.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700847 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
848 * @see #KEY_IDLE_PENDING_TIMEOUT
849 */
850 public long IDLE_PENDING_TIMEOUT;
851
852 /**
853 * Maximum pending idle timeout (time spent running) we will be allowed to use.
854 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
855 * @see #KEY_MAX_IDLE_PENDING_TIMEOUT
856 */
857 public long MAX_IDLE_PENDING_TIMEOUT;
858
859 /**
860 * Scaling factor to apply to current pending idle timeout each time we cycle through
861 * that state.
862 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
863 * @see #KEY_IDLE_PENDING_FACTOR
864 */
865 public float IDLE_PENDING_FACTOR;
866
867 /**
868 * This is the initial time that we want to sit in the idle state before waking up
869 * again to return to pending idle and allowing normal work to run.
870 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
871 * @see #KEY_IDLE_TIMEOUT
872 */
873 public long IDLE_TIMEOUT;
874
875 /**
876 * Maximum idle duration we will be allowed to use.
877 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
878 * @see #KEY_MAX_IDLE_TIMEOUT
879 */
880 public long MAX_IDLE_TIMEOUT;
881
882 /**
883 * Scaling factor to apply to current idle timeout each time we cycle through that state.
884 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
885 * @see #KEY_IDLE_FACTOR
886 */
887 public float IDLE_FACTOR;
888
889 /**
890 * This is the minimum time we will allow until the next upcoming alarm for us to
891 * actually go in to idle mode.
892 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
893 * @see #KEY_MIN_TIME_TO_ALARM
894 */
895 public long MIN_TIME_TO_ALARM;
896
897 /**
898 * Max amount of time to temporarily whitelist an app when it receives a high priority
899 * tickle.
900 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
901 * @see #KEY_MAX_TEMP_APP_WHITELIST_DURATION
902 */
903 public long MAX_TEMP_APP_WHITELIST_DURATION;
904
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700905 /**
906 * Amount of time we would like to whitelist an app that is receiving an MMS.
907 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
908 * @see #KEY_MMS_TEMP_APP_WHITELIST_DURATION
909 */
910 public long MMS_TEMP_APP_WHITELIST_DURATION;
911
Dianne Hackborn451c3462015-07-21 17:39:46 -0700912 /**
913 * Amount of time we would like to whitelist an app that is receiving an SMS.
914 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
915 * @see #KEY_SMS_TEMP_APP_WHITELIST_DURATION
916 */
917 public long SMS_TEMP_APP_WHITELIST_DURATION;
918
Felipe Lemea1b79bf2016-05-24 13:06:54 -0700919 /**
920 * Amount of time we would like to whitelist an app that is handling a
921 * {@link android.app.PendingIntent} triggered by a {@link android.app.Notification}.
922 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
923 * @see #KEY_NOTIFICATION_WHITELIST_DURATION
924 */
925 public long NOTIFICATION_WHITELIST_DURATION;
926
Amith Yamasani396a10c2018-01-19 10:58:07 -0800927 public boolean WAIT_FOR_UNLOCK;
928
Adam Lesinski31c05d12015-06-09 17:34:04 -0700929 private final ContentResolver mResolver;
shreerag597da8a2017-07-21 14:24:14 -0700930 private final boolean mSmallBatteryDevice;
Adam Lesinski31c05d12015-06-09 17:34:04 -0700931 private final KeyValueListParser mParser = new KeyValueListParser(',');
932
933 public Constants(Handler handler, ContentResolver resolver) {
934 super(handler);
935 mResolver = resolver;
shreerag597da8a2017-07-21 14:24:14 -0700936 mSmallBatteryDevice = ActivityManager.isSmallBatteryDevice();
937 mResolver.registerContentObserver(
938 Settings.Global.getUriFor(Settings.Global.DEVICE_IDLE_CONSTANTS),
Joe LaPennaf33b5bf2016-03-23 15:19:47 -0700939 false, this);
Adam Lesinski31c05d12015-06-09 17:34:04 -0700940 updateConstants();
941 }
942
943 @Override
944 public void onChange(boolean selfChange, Uri uri) {
945 updateConstants();
946 }
947
948 private void updateConstants() {
949 synchronized (DeviceIdleController.this) {
950 try {
951 mParser.setString(Settings.Global.getString(mResolver,
shreerag597da8a2017-07-21 14:24:14 -0700952 Settings.Global.DEVICE_IDLE_CONSTANTS));
Adam Lesinski31c05d12015-06-09 17:34:04 -0700953 } catch (IllegalArgumentException e) {
954 // Failed to parse the settings string, log this and move on
955 // with defaults.
956 Slog.e(TAG, "Bad device idle settings", e);
957 }
958
Amith Yamasani761d3ff2017-12-14 17:50:03 -0800959 LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getDurationMillis(
Dianne Hackborn953fc942016-03-29 15:36:24 -0700960 KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
Suprabh Shukla85fff7d2018-05-08 17:39:24 -0700961 !COMPRESS_TIME ? 3 * 60 * 1000L : 15 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -0800962 LIGHT_PRE_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_LIGHT_PRE_IDLE_TIMEOUT,
Suprabh Shukla85fff7d2018-05-08 17:39:24 -0700963 !COMPRESS_TIME ? 3 * 60 * 1000L : 30 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -0800964 LIGHT_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_LIGHT_IDLE_TIMEOUT,
Dianne Hackborn953fc942016-03-29 15:36:24 -0700965 !COMPRESS_TIME ? 5 * 60 * 1000L : 15 * 1000L);
966 LIGHT_IDLE_FACTOR = mParser.getFloat(KEY_LIGHT_IDLE_FACTOR,
967 2f);
Amith Yamasani761d3ff2017-12-14 17:50:03 -0800968 LIGHT_MAX_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_LIGHT_MAX_IDLE_TIMEOUT,
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700969 !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -0800970 LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = mParser.getDurationMillis(
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800971 KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET,
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700972 !COMPRESS_TIME ? 1 * 60 * 1000L : 15 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -0800973 LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = mParser.getDurationMillis(
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800974 KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET,
975 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -0800976 MIN_LIGHT_MAINTENANCE_TIME = mParser.getDurationMillis(
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700977 KEY_MIN_LIGHT_MAINTENANCE_TIME,
978 !COMPRESS_TIME ? 5 * 1000L : 1 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -0800979 MIN_DEEP_MAINTENANCE_TIME = mParser.getDurationMillis(
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700980 KEY_MIN_DEEP_MAINTENANCE_TIME,
981 !COMPRESS_TIME ? 30 * 1000L : 5 * 1000L);
Michael Kwan88871462017-08-21 13:13:37 -0700982 long inactiveTimeoutDefault = (mSmallBatteryDevice ? 15 : 30) * 60 * 1000L;
Amith Yamasani761d3ff2017-12-14 17:50:03 -0800983 INACTIVE_TIMEOUT = mParser.getDurationMillis(KEY_INACTIVE_TIMEOUT,
Joe LaPenna0c5d3e92016-03-24 13:29:56 -0700984 !COMPRESS_TIME ? inactiveTimeoutDefault : (inactiveTimeoutDefault / 10));
Amith Yamasani761d3ff2017-12-14 17:50:03 -0800985 SENSING_TIMEOUT = mParser.getDurationMillis(KEY_SENSING_TIMEOUT,
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700986 !DEBUG ? 4 * 60 * 1000L : 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -0800987 LOCATING_TIMEOUT = mParser.getDurationMillis(KEY_LOCATING_TIMEOUT,
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700988 !DEBUG ? 30 * 1000L : 15 * 1000L);
989 LOCATION_ACCURACY = mParser.getFloat(KEY_LOCATION_ACCURACY, 20);
Amith Yamasani761d3ff2017-12-14 17:50:03 -0800990 MOTION_INACTIVE_TIMEOUT = mParser.getDurationMillis(KEY_MOTION_INACTIVE_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -0700991 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
Michael Kwan88871462017-08-21 13:13:37 -0700992 long idleAfterInactiveTimeout = (mSmallBatteryDevice ? 15 : 30) * 60 * 1000L;
Amith Yamasani761d3ff2017-12-14 17:50:03 -0800993 IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getDurationMillis(
994 KEY_IDLE_AFTER_INACTIVE_TIMEOUT,
Joe LaPenna0c5d3e92016-03-24 13:29:56 -0700995 !COMPRESS_TIME ? idleAfterInactiveTimeout
996 : (idleAfterInactiveTimeout / 10));
Amith Yamasani761d3ff2017-12-14 17:50:03 -0800997 IDLE_PENDING_TIMEOUT = mParser.getDurationMillis(KEY_IDLE_PENDING_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -0700998 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -0800999 MAX_IDLE_PENDING_TIMEOUT = mParser.getDurationMillis(KEY_MAX_IDLE_PENDING_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001000 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
1001 IDLE_PENDING_FACTOR = mParser.getFloat(KEY_IDLE_PENDING_FACTOR,
1002 2f);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001003 IDLE_TIMEOUT = mParser.getDurationMillis(KEY_IDLE_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001004 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001005 MAX_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_MAX_IDLE_TIMEOUT,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001006 !COMPRESS_TIME ? 6 * 60 * 60 * 1000L : 30 * 60 * 1000L);
1007 IDLE_FACTOR = mParser.getFloat(KEY_IDLE_FACTOR,
1008 2f);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001009 MIN_TIME_TO_ALARM = mParser.getDurationMillis(KEY_MIN_TIME_TO_ALARM,
Adam Lesinski31c05d12015-06-09 17:34:04 -07001010 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001011 MAX_TEMP_APP_WHITELIST_DURATION = mParser.getDurationMillis(
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001012 KEY_MAX_TEMP_APP_WHITELIST_DURATION, 5 * 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001013 MMS_TEMP_APP_WHITELIST_DURATION = mParser.getDurationMillis(
Dianne Hackborn0b6134b2015-07-14 18:48:07 -07001014 KEY_MMS_TEMP_APP_WHITELIST_DURATION, 60 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001015 SMS_TEMP_APP_WHITELIST_DURATION = mParser.getDurationMillis(
Dianne Hackborn451c3462015-07-21 17:39:46 -07001016 KEY_SMS_TEMP_APP_WHITELIST_DURATION, 20 * 1000L);
Amith Yamasani761d3ff2017-12-14 17:50:03 -08001017 NOTIFICATION_WHITELIST_DURATION = mParser.getDurationMillis(
Felipe Lemea1b79bf2016-05-24 13:06:54 -07001018 KEY_NOTIFICATION_WHITELIST_DURATION, 30 * 1000L);
Amith Yamasani396a10c2018-01-19 10:58:07 -08001019 WAIT_FOR_UNLOCK = mParser.getBoolean(KEY_WAIT_FOR_UNLOCK, false);
Adam Lesinski31c05d12015-06-09 17:34:04 -07001020 }
1021 }
1022
1023 void dump(PrintWriter pw) {
1024 pw.println(" Settings:");
1025
Dianne Hackborn953fc942016-03-29 15:36:24 -07001026 pw.print(" "); pw.print(KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("=");
1027 TimeUtils.formatDuration(LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT, pw);
1028 pw.println();
1029
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001030 pw.print(" "); pw.print(KEY_LIGHT_PRE_IDLE_TIMEOUT); pw.print("=");
1031 TimeUtils.formatDuration(LIGHT_PRE_IDLE_TIMEOUT, pw);
1032 pw.println();
1033
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001034 pw.print(" "); pw.print(KEY_LIGHT_IDLE_TIMEOUT); pw.print("=");
1035 TimeUtils.formatDuration(LIGHT_IDLE_TIMEOUT, pw);
1036 pw.println();
1037
Dianne Hackborn953fc942016-03-29 15:36:24 -07001038 pw.print(" "); pw.print(KEY_LIGHT_IDLE_FACTOR); pw.print("=");
1039 pw.print(LIGHT_IDLE_FACTOR);
1040 pw.println();
1041
1042 pw.print(" "); pw.print(KEY_LIGHT_MAX_IDLE_TIMEOUT); pw.print("=");
1043 TimeUtils.formatDuration(LIGHT_MAX_IDLE_TIMEOUT, pw);
1044 pw.println();
1045
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001046 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET); pw.print("=");
1047 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MIN_BUDGET, pw);
1048 pw.println();
1049
1050 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET); pw.print("=");
1051 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MAX_BUDGET, pw);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001052 pw.println();
1053
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001054 pw.print(" "); pw.print(KEY_MIN_LIGHT_MAINTENANCE_TIME); pw.print("=");
1055 TimeUtils.formatDuration(MIN_LIGHT_MAINTENANCE_TIME, pw);
1056 pw.println();
1057
1058 pw.print(" "); pw.print(KEY_MIN_DEEP_MAINTENANCE_TIME); pw.print("=");
1059 TimeUtils.formatDuration(MIN_DEEP_MAINTENANCE_TIME, pw);
1060 pw.println();
1061
Dianne Hackborna750a632015-06-16 17:18:23 -07001062 pw.print(" "); pw.print(KEY_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001063 TimeUtils.formatDuration(INACTIVE_TIMEOUT, pw);
1064 pw.println();
1065
Dianne Hackborna750a632015-06-16 17:18:23 -07001066 pw.print(" "); pw.print(KEY_SENSING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001067 TimeUtils.formatDuration(SENSING_TIMEOUT, pw);
1068 pw.println();
1069
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001070 pw.print(" "); pw.print(KEY_LOCATING_TIMEOUT); pw.print("=");
1071 TimeUtils.formatDuration(LOCATING_TIMEOUT, pw);
1072 pw.println();
1073
1074 pw.print(" "); pw.print(KEY_LOCATION_ACCURACY); pw.print("=");
1075 pw.print(LOCATION_ACCURACY); pw.print("m");
1076 pw.println();
1077
Dianne Hackborna750a632015-06-16 17:18:23 -07001078 pw.print(" "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001079 TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT, pw);
1080 pw.println();
1081
Dianne Hackborna750a632015-06-16 17:18:23 -07001082 pw.print(" "); pw.print(KEY_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001083 TimeUtils.formatDuration(IDLE_AFTER_INACTIVE_TIMEOUT, pw);
1084 pw.println();
1085
Dianne Hackborna750a632015-06-16 17:18:23 -07001086 pw.print(" "); pw.print(KEY_IDLE_PENDING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001087 TimeUtils.formatDuration(IDLE_PENDING_TIMEOUT, pw);
1088 pw.println();
1089
Dianne Hackborna750a632015-06-16 17:18:23 -07001090 pw.print(" "); pw.print(KEY_MAX_IDLE_PENDING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001091 TimeUtils.formatDuration(MAX_IDLE_PENDING_TIMEOUT, pw);
1092 pw.println();
1093
Dianne Hackborna750a632015-06-16 17:18:23 -07001094 pw.print(" "); pw.print(KEY_IDLE_PENDING_FACTOR); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001095 pw.println(IDLE_PENDING_FACTOR);
1096
Dianne Hackborna750a632015-06-16 17:18:23 -07001097 pw.print(" "); pw.print(KEY_IDLE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001098 TimeUtils.formatDuration(IDLE_TIMEOUT, pw);
1099 pw.println();
1100
Dianne Hackborna750a632015-06-16 17:18:23 -07001101 pw.print(" "); pw.print(KEY_MAX_IDLE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001102 TimeUtils.formatDuration(MAX_IDLE_TIMEOUT, pw);
1103 pw.println();
1104
Dianne Hackborna750a632015-06-16 17:18:23 -07001105 pw.print(" "); pw.print(KEY_IDLE_FACTOR); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001106 pw.println(IDLE_FACTOR);
1107
Dianne Hackborna750a632015-06-16 17:18:23 -07001108 pw.print(" "); pw.print(KEY_MIN_TIME_TO_ALARM); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001109 TimeUtils.formatDuration(MIN_TIME_TO_ALARM, pw);
1110 pw.println();
1111
Dianne Hackborna750a632015-06-16 17:18:23 -07001112 pw.print(" "); pw.print(KEY_MAX_TEMP_APP_WHITELIST_DURATION); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001113 TimeUtils.formatDuration(MAX_TEMP_APP_WHITELIST_DURATION, pw);
1114 pw.println();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001115
1116 pw.print(" "); pw.print(KEY_MMS_TEMP_APP_WHITELIST_DURATION); pw.print("=");
1117 TimeUtils.formatDuration(MMS_TEMP_APP_WHITELIST_DURATION, pw);
1118 pw.println();
Dianne Hackborn451c3462015-07-21 17:39:46 -07001119
1120 pw.print(" "); pw.print(KEY_SMS_TEMP_APP_WHITELIST_DURATION); pw.print("=");
1121 TimeUtils.formatDuration(SMS_TEMP_APP_WHITELIST_DURATION, pw);
1122 pw.println();
Felipe Lemea1b79bf2016-05-24 13:06:54 -07001123
1124 pw.print(" "); pw.print(KEY_NOTIFICATION_WHITELIST_DURATION); pw.print("=");
1125 TimeUtils.formatDuration(NOTIFICATION_WHITELIST_DURATION, pw);
1126 pw.println();
Amith Yamasani396a10c2018-01-19 10:58:07 -08001127
1128 pw.print(" "); pw.print(KEY_WAIT_FOR_UNLOCK); pw.print("=");
1129 pw.println(WAIT_FOR_UNLOCK);
Adam Lesinski31c05d12015-06-09 17:34:04 -07001130 }
1131 }
1132
1133 private Constants mConstants;
1134
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001135 @Override
1136 public void onAnyMotionResult(int result) {
1137 if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")");
Kevin Gabayan92f15e62016-04-04 17:52:22 -07001138 if (result != AnyMotionDetector.RESULT_UNKNOWN) {
1139 synchronized (this) {
1140 cancelSensingTimeoutAlarmLocked();
1141 }
1142 }
Kevin Gabayandcf47012016-07-08 10:41:24 -07001143 if ((result == AnyMotionDetector.RESULT_MOVED) ||
1144 (result == AnyMotionDetector.RESULT_UNKNOWN)) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001145 synchronized (this) {
Kevin Gabayandcf47012016-07-08 10:41:24 -07001146 handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "non_stationary");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001147 }
1148 } else if (result == AnyMotionDetector.RESULT_STATIONARY) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001149 if (mState == STATE_SENSING) {
1150 // If we are currently sensing, it is time to move to locating.
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001151 synchronized (this) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001152 mNotMoving = true;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001153 stepIdleStateLocked("s:stationary");
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001154 }
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001155 } else if (mState == STATE_LOCATING) {
1156 // If we are currently locating, note that we are not moving and step
1157 // if we have located the position.
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001158 synchronized (this) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001159 mNotMoving = true;
1160 if (mLocated) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001161 stepIdleStateLocked("s:stationary");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001162 }
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001163 }
1164 }
1165 }
1166 }
1167
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001168 private static final int MSG_WRITE_CONFIG = 1;
1169 private static final int MSG_REPORT_IDLE_ON = 2;
1170 private static final int MSG_REPORT_IDLE_ON_LIGHT = 3;
1171 private static final int MSG_REPORT_IDLE_OFF = 4;
1172 private static final int MSG_REPORT_ACTIVE = 5;
1173 private static final int MSG_TEMP_APP_WHITELIST_TIMEOUT = 6;
1174 private static final int MSG_REPORT_MAINTENANCE_ACTIVITY = 7;
1175 private static final int MSG_FINISH_IDLE_OP = 8;
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07001176 private static final int MSG_REPORT_TEMP_APP_WHITELIST_CHANGED = 9;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001177
1178 final class MyHandler extends Handler {
1179 MyHandler(Looper looper) {
1180 super(looper);
1181 }
1182
1183 @Override public void handleMessage(Message msg) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001184 if (DEBUG) Slog.d(TAG, "handleMessage(" + msg.what + ")");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001185 switch (msg.what) {
1186 case MSG_WRITE_CONFIG: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001187 // Does not hold a wakelock. Just let this happen whenever.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001188 handleWriteConfigFile();
1189 } break;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001190 case MSG_REPORT_IDLE_ON:
1191 case MSG_REPORT_IDLE_ON_LIGHT: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001192 // mGoingIdleWakeLock is held at this point
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001193 EventLogTags.writeDeviceIdleOnStart();
Dianne Hackbornb6843652016-02-22 12:20:13 -08001194 final boolean deepChanged;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001195 final boolean lightChanged;
1196 if (msg.what == MSG_REPORT_IDLE_ON) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08001197 deepChanged = mLocalPowerManager.setDeviceIdleMode(true);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001198 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
1199 } else {
Dianne Hackbornb6843652016-02-22 12:20:13 -08001200 deepChanged = mLocalPowerManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001201 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(true);
1202 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001203 try {
1204 mNetworkPolicyManager.setDeviceIdleMode(true);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001205 mBatteryStats.noteDeviceIdleMode(msg.what == MSG_REPORT_IDLE_ON
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001206 ? BatteryStats.DEVICE_IDLE_MODE_DEEP
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001207 : BatteryStats.DEVICE_IDLE_MODE_LIGHT, null, Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001208 } catch (RemoteException e) {
1209 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08001210 if (deepChanged) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001211 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
1212 }
1213 if (lightChanged) {
1214 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL);
1215 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001216 EventLogTags.writeDeviceIdleOnComplete();
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001217 mGoingIdleWakeLock.release();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001218 } break;
1219 case MSG_REPORT_IDLE_OFF: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001220 // mActiveIdleWakeLock is held at this point
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001221 EventLogTags.writeDeviceIdleOffStart("unknown");
Dianne Hackbornb6843652016-02-22 12:20:13 -08001222 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001223 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001224 try {
1225 mNetworkPolicyManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001226 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF,
1227 null, Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001228 } catch (RemoteException e) {
1229 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08001230 if (deepChanged) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001231 incActiveIdleOps();
1232 getContext().sendOrderedBroadcastAsUser(mIdleIntent, UserHandle.ALL,
1233 null, mIdleStartedDoneReceiver, null, 0, null, null);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001234 }
1235 if (lightChanged) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001236 incActiveIdleOps();
1237 getContext().sendOrderedBroadcastAsUser(mLightIdleIntent, UserHandle.ALL,
1238 null, mIdleStartedDoneReceiver, null, 0, null, null);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001239 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001240 // Always start with one active op for the message being sent here.
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001241 // Now we are done!
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001242 decActiveIdleOps();
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001243 EventLogTags.writeDeviceIdleOffComplete();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001244 } break;
1245 case MSG_REPORT_ACTIVE: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001246 // The device is awake at this point, so no wakelock necessary.
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001247 String activeReason = (String)msg.obj;
1248 int activeUid = msg.arg1;
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001249 EventLogTags.writeDeviceIdleOffStart(
1250 activeReason != null ? activeReason : "unknown");
Dianne Hackbornb6843652016-02-22 12:20:13 -08001251 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001252 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001253 try {
1254 mNetworkPolicyManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001255 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF,
1256 activeReason, activeUid);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001257 } catch (RemoteException e) {
1258 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08001259 if (deepChanged) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001260 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
1261 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001262 if (lightChanged) {
1263 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL);
1264 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001265 EventLogTags.writeDeviceIdleOffComplete();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001266 } break;
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001267 case MSG_TEMP_APP_WHITELIST_TIMEOUT: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001268 // TODO: What is keeping the device awake at this point? Does it need to be?
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001269 int uid = msg.arg1;
1270 checkTempAppWhitelistTimeout(uid);
1271 } break;
Yao Chenca5edbb2016-01-13 14:44:36 -08001272 case MSG_REPORT_MAINTENANCE_ACTIVITY: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001273 // TODO: What is keeping the device awake at this point? Does it need to be?
Yao Chenca5edbb2016-01-13 14:44:36 -08001274 boolean active = (msg.arg1 == 1);
1275 final int size = mMaintenanceActivityListeners.beginBroadcast();
1276 try {
1277 for (int i = 0; i < size; i++) {
1278 try {
1279 mMaintenanceActivityListeners.getBroadcastItem(i)
1280 .onMaintenanceActivityChanged(active);
1281 } catch (RemoteException ignored) {
1282 }
1283 }
1284 } finally {
1285 mMaintenanceActivityListeners.finishBroadcast();
1286 }
1287 } break;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001288 case MSG_FINISH_IDLE_OP: {
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001289 // mActiveIdleWakeLock is held at this point
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001290 decActiveIdleOps();
1291 } break;
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07001292 case MSG_REPORT_TEMP_APP_WHITELIST_CHANGED: {
1293 final int appId = msg.arg1;
1294 final boolean added = (msg.arg2 == 1);
1295 mNetworkPolicyManagerInternal.onTempPowerSaveWhitelistChange(appId, added);
1296 } break;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001297 }
1298 }
1299 }
1300
1301 final MyHandler mHandler;
1302
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001303 BinderService mBinderService;
1304
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001305 private final class BinderService extends IDeviceIdleController.Stub {
1306 @Override public void addPowerSaveWhitelistApp(String name) {
Eugene Susla6a7006a2017-03-13 12:57:58 -07001307 if (DEBUG) {
1308 Slog.i(TAG, "addPowerSaveWhitelistApp(name = " + name + ")");
1309 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001310 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1311 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001312 long ident = Binder.clearCallingIdentity();
1313 try {
1314 addPowerSaveWhitelistAppInternal(name);
1315 } finally {
1316 Binder.restoreCallingIdentity(ident);
1317 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001318 }
1319
1320 @Override public void removePowerSaveWhitelistApp(String name) {
Eugene Susla6a7006a2017-03-13 12:57:58 -07001321 if (DEBUG) {
1322 Slog.i(TAG, "removePowerSaveWhitelistApp(name = " + name + ")");
1323 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001324 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1325 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001326 long ident = Binder.clearCallingIdentity();
1327 try {
1328 removePowerSaveWhitelistAppInternal(name);
1329 } finally {
1330 Binder.restoreCallingIdentity(ident);
1331 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001332 }
1333
Suprabh Shukla08105642017-09-26 14:45:30 -07001334 @Override public void removeSystemPowerWhitelistApp(String name) {
1335 if (DEBUG) {
1336 Slog.d(TAG, "removeAppFromSystemWhitelist(name = " + name + ")");
1337 }
1338 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1339 null);
1340 long ident = Binder.clearCallingIdentity();
1341 try {
1342 removeSystemPowerWhitelistAppInternal(name);
1343 } finally {
1344 Binder.restoreCallingIdentity(ident);
1345 }
1346 }
1347
1348 @Override public void restoreSystemPowerWhitelistApp(String name) {
1349 if (DEBUG) {
1350 Slog.d(TAG, "restoreAppToSystemWhitelist(name = " + name + ")");
1351 }
1352 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1353 null);
1354 long ident = Binder.clearCallingIdentity();
1355 try {
1356 restoreSystemPowerWhitelistAppInternal(name);
1357 } finally {
1358 Binder.restoreCallingIdentity(ident);
1359 }
1360 }
1361
1362 public String[] getRemovedSystemPowerWhitelistApps() {
1363 return getRemovedSystemPowerWhitelistAppsInternal();
1364 }
1365
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001366 @Override public String[] getSystemPowerWhitelistExceptIdle() {
1367 return getSystemPowerWhitelistExceptIdleInternal();
1368 }
1369
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001370 @Override public String[] getSystemPowerWhitelist() {
1371 return getSystemPowerWhitelistInternal();
1372 }
1373
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001374 @Override public String[] getUserPowerWhitelist() {
1375 return getUserPowerWhitelistInternal();
1376 }
1377
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001378 @Override public String[] getFullPowerWhitelistExceptIdle() {
1379 return getFullPowerWhitelistExceptIdleInternal();
1380 }
1381
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001382 @Override public String[] getFullPowerWhitelist() {
1383 return getFullPowerWhitelistInternal();
1384 }
1385
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001386 @Override public int[] getAppIdWhitelistExceptIdle() {
1387 return getAppIdWhitelistExceptIdleInternal();
1388 }
1389
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001390 @Override public int[] getAppIdWhitelist() {
1391 return getAppIdWhitelistInternal();
1392 }
1393
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001394 @Override public int[] getAppIdUserWhitelist() {
1395 return getAppIdUserWhitelistInternal();
1396 }
1397
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001398 @Override public int[] getAppIdTempWhitelist() {
1399 return getAppIdTempWhitelistInternal();
1400 }
1401
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001402 @Override public boolean isPowerSaveWhitelistExceptIdleApp(String name) {
1403 return isPowerSaveWhitelistExceptIdleAppInternal(name);
1404 }
1405
Amith Yamasani06bf8242015-05-08 16:36:21 -07001406 @Override public boolean isPowerSaveWhitelistApp(String name) {
1407 return isPowerSaveWhitelistAppInternal(name);
1408 }
1409
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001410 @Override public void addPowerSaveTempWhitelistApp(String packageName, long duration,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001411 int userId, String reason) throws RemoteException {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001412 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001413 }
1414
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001415 @Override public long addPowerSaveTempWhitelistAppForMms(String packageName,
1416 int userId, String reason) throws RemoteException {
1417 long duration = mConstants.MMS_TEMP_APP_WHITELIST_DURATION;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001418 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001419 return duration;
1420 }
1421
Dianne Hackborn451c3462015-07-21 17:39:46 -07001422 @Override public long addPowerSaveTempWhitelistAppForSms(String packageName,
1423 int userId, String reason) throws RemoteException {
1424 long duration = mConstants.SMS_TEMP_APP_WHITELIST_DURATION;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001425 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Dianne Hackborn451c3462015-07-21 17:39:46 -07001426 return duration;
1427 }
1428
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001429 @Override public void exitIdle(String reason) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001430 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER,
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001431 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001432 long ident = Binder.clearCallingIdentity();
1433 try {
1434 exitIdleInternal(reason);
1435 } finally {
1436 Binder.restoreCallingIdentity(ident);
1437 }
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001438 }
1439
Yao Chenca5edbb2016-01-13 14:44:36 -08001440 @Override public boolean registerMaintenanceActivityListener(
1441 IMaintenanceActivityListener listener) {
1442 return DeviceIdleController.this.registerMaintenanceActivityListener(listener);
1443 }
1444
1445 @Override public void unregisterMaintenanceActivityListener(
1446 IMaintenanceActivityListener listener) {
1447 DeviceIdleController.this.unregisterMaintenanceActivityListener(listener);
1448 }
1449
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001450 @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1451 DeviceIdleController.this.dump(fd, pw, args);
1452 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001453
1454 @Override public void onShellCommand(FileDescriptor in, FileDescriptor out,
Dianne Hackborn354736e2016-08-22 17:00:05 -07001455 FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
1456 (new Shell()).exec(this, in, out, err, args, callback, resultReceiver);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001457 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001458 }
1459
Felipe Lemeef134662016-08-10 14:46:39 -07001460 public class LocalService {
Christopher Tatee0be7e82017-02-08 17:38:20 -08001461 // duration in milliseconds
1462 public void addPowerSaveTempWhitelistApp(int callingUid, String packageName,
1463 long duration, int userId, boolean sync, String reason) {
1464 addPowerSaveTempWhitelistAppInternal(callingUid, packageName, duration,
1465 userId, sync, reason);
1466 }
1467
1468 // duration in milliseconds
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001469 public void addPowerSaveTempWhitelistAppDirect(int appId, long duration, boolean sync,
1470 String reason) {
1471 addPowerSaveTempWhitelistAppDirectInternal(0, appId, duration, sync, reason);
1472 }
1473
Christopher Tatee0be7e82017-02-08 17:38:20 -08001474 // duration in milliseconds
Felipe Lemea1b79bf2016-05-24 13:06:54 -07001475 public long getNotificationWhitelistDuration() {
1476 return mConstants.NOTIFICATION_WHITELIST_DURATION;
1477 }
1478
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001479 public void setJobsActive(boolean active) {
1480 DeviceIdleController.this.setJobsActive(active);
1481 }
1482
1483 // Up-call from alarm manager.
1484 public void setAlarmsActive(boolean active) {
1485 DeviceIdleController.this.setAlarmsActive(active);
1486 }
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001487
Christopher Tate42a386b2016-11-07 12:21:21 -08001488 /** Is the app on any of the power save whitelists, whether system or user? */
1489 public boolean isAppOnWhitelist(int appid) {
1490 return DeviceIdleController.this.isAppOnWhitelistInternal(appid);
1491 }
1492
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001493 /**
1494 * Returns the array of app ids whitelisted by user. Take care not to
1495 * modify this, as it is a reference to the original copy. But the reference
1496 * can change when the list changes, so it needs to be re-acquired when
1497 * {@link PowerManager#ACTION_POWER_SAVE_WHITELIST_CHANGED} is sent.
1498 */
1499 public int[] getPowerSaveWhitelistUserAppIds() {
1500 return DeviceIdleController.this.getPowerSaveWhitelistUserAppIds();
1501 }
Suprabh Shuklaa78acfd2017-10-13 19:29:36 -07001502
1503 public int[] getPowerSaveTempWhitelistAppIds() {
1504 return DeviceIdleController.this.getAppIdTempWhitelistInternal();
1505 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001506 }
1507
Kweku Adams00e3a372018-09-28 16:57:09 -07001508 static class Injector {
1509 private final Context mContext;
1510
1511 Injector(Context ctx) {
1512 mContext = ctx;
1513 }
1514
1515 AlarmManager getAlarmManager() {
1516 return mContext.getSystemService(AlarmManager.class);
1517 }
1518
1519 AnyMotionDetector getAnyMotionDetector(Handler handler, SensorManager sm,
1520 AnyMotionDetector.DeviceIdleCallback callback, float angleThreshold) {
1521 return new AnyMotionDetector(getPowerManager(), handler, sm, callback, angleThreshold);
1522 }
1523
1524 AppStateTracker getAppStateTracker(Context ctx, Looper looper) {
1525 return new AppStateTracker(ctx, looper);
1526 }
1527
1528 ConnectivityService getConnectivityService() {
1529 return (ConnectivityService) ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
1530 }
1531
1532 LocationManager getLocationManager() {
1533 return mContext.getSystemService(LocationManager.class);
1534 }
1535
1536 MyHandler getHandler(DeviceIdleController ctlr) {
1537 return ctlr.new MyHandler(BackgroundThread.getHandler().getLooper());
1538 }
1539
1540 PowerManager getPowerManager() {
1541 return mContext.getSystemService(PowerManager.class);
1542 }
1543 }
1544
1545 private final Injector mInjector;
1546
Wale Ogunwale6767eae2018-05-03 15:52:51 -07001547 private ActivityTaskManagerInternal.ScreenObserver mScreenObserver =
1548 new ActivityTaskManagerInternal.ScreenObserver() {
Amith Yamasani396a10c2018-01-19 10:58:07 -08001549 @Override
1550 public void onAwakeStateChanged(boolean isAwake) { }
1551
1552 @Override
1553 public void onKeyguardStateChanged(boolean isShowing) {
1554 synchronized (DeviceIdleController.this) {
1555 DeviceIdleController.this.keyguardShowingLocked(isShowing);
1556 }
1557 }
1558 };
1559
Kweku Adams00e3a372018-09-28 16:57:09 -07001560 @VisibleForTesting DeviceIdleController(Context context, Injector injector) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001561 super(context);
Kweku Adams00e3a372018-09-28 16:57:09 -07001562 mInjector = injector;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001563 mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml"));
Kweku Adams00e3a372018-09-28 16:57:09 -07001564 mHandler = mInjector.getHandler(this);
1565 mAppStateTracker = mInjector.getAppStateTracker(context, FgThread.get().getLooper());
Makoto Onukie4918212018-02-06 11:30:15 -08001566 LocalServices.addService(AppStateTracker.class, mAppStateTracker);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001567 }
1568
Kweku Adams00e3a372018-09-28 16:57:09 -07001569 public DeviceIdleController(Context context) {
1570 this(context, new Injector(context));
1571 }
1572
Christopher Tate42a386b2016-11-07 12:21:21 -08001573 boolean isAppOnWhitelistInternal(int appid) {
1574 synchronized (this) {
1575 return Arrays.binarySearch(mPowerSaveWhitelistAllAppIdArray, appid) >= 0;
1576 }
1577 }
1578
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001579 int[] getPowerSaveWhitelistUserAppIds() {
1580 synchronized (this) {
1581 return mPowerSaveWhitelistUserAppIdArray;
1582 }
1583 }
1584
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001585 private static File getSystemDir() {
1586 return new File(Environment.getDataDirectory(), "system");
1587 }
1588
1589 @Override
1590 public void onStart() {
1591 final PackageManager pm = getContext().getPackageManager();
1592
1593 synchronized (this) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08001594 mLightEnabled = mDeepEnabled = getContext().getResources().getBoolean(
Dianne Hackborn92617032015-06-19 15:32:19 -07001595 com.android.internal.R.bool.config_enableAutoPowerModes);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001596 SystemConfig sysConfig = SystemConfig.getInstance();
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001597 ArraySet<String> allowPowerExceptIdle = sysConfig.getAllowInPowerSaveExceptIdle();
1598 for (int i=0; i<allowPowerExceptIdle.size(); i++) {
1599 String pkg = allowPowerExceptIdle.valueAt(i);
1600 try {
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07001601 ApplicationInfo ai = pm.getApplicationInfo(pkg,
1602 PackageManager.MATCH_SYSTEM_ONLY);
1603 int appid = UserHandle.getAppId(ai.uid);
1604 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
1605 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001606 } catch (PackageManager.NameNotFoundException e) {
1607 }
1608 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001609 ArraySet<String> allowPower = sysConfig.getAllowInPowerSave();
1610 for (int i=0; i<allowPower.size(); i++) {
1611 String pkg = allowPower.valueAt(i);
1612 try {
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07001613 ApplicationInfo ai = pm.getApplicationInfo(pkg,
1614 PackageManager.MATCH_SYSTEM_ONLY);
1615 int appid = UserHandle.getAppId(ai.uid);
1616 // These apps are on both the whitelist-except-idle as well
1617 // as the full whitelist, so they apply in all cases.
1618 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
1619 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
1620 mPowerSaveWhitelistApps.put(ai.packageName, appid);
1621 mPowerSaveWhitelistSystemAppIds.put(appid, true);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001622 } catch (PackageManager.NameNotFoundException e) {
1623 }
1624 }
1625
Adam Lesinski31c05d12015-06-09 17:34:04 -07001626 mConstants = new Constants(mHandler, getContext().getContentResolver());
1627
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001628 readConfigFileLocked();
1629 updateWhitelistAppIdsLocked();
1630
Dianne Hackborn88c41352016-04-07 15:18:58 -07001631 mNetworkConnected = true;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001632 mScreenOn = true;
Amith Yamasani396a10c2018-01-19 10:58:07 -08001633 mScreenLocked = false;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001634 // Start out assuming we are charging. If we aren't, we will at least get
1635 // a battery update the next time the level drops.
1636 mCharging = true;
1637 mState = STATE_ACTIVE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001638 mLightState = LIGHT_STATE_ACTIVE;
Adam Lesinski31c05d12015-06-09 17:34:04 -07001639 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001640 }
1641
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001642 mBinderService = new BinderService();
1643 publishBinderService(Context.DEVICE_IDLE_CONTROLLER, mBinderService);
Dianne Hackborna750a632015-06-16 17:18:23 -07001644 publishLocalService(LocalService.class, new LocalService());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001645 }
1646
1647 @Override
1648 public void onBootPhase(int phase) {
1649 if (phase == PHASE_SYSTEM_SERVICES_READY) {
1650 synchronized (this) {
Kweku Adams00e3a372018-09-28 16:57:09 -07001651 mAlarmManager = mInjector.getAlarmManager();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001652 mBatteryStats = BatteryStatsService.getService();
Dianne Hackborn85e35642017-01-12 15:10:57 -08001653 mLocalActivityManager = getLocalService(ActivityManagerInternal.class);
Wale Ogunwale6767eae2018-05-03 15:52:51 -07001654 mLocalActivityTaskManager = getLocalService(ActivityTaskManagerInternal.class);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001655 mLocalPowerManager = getLocalService(PowerManagerInternal.class);
Kweku Adams00e3a372018-09-28 16:57:09 -07001656 mPowerManager = mInjector.getPowerManager();
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001657 mActiveIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
1658 "deviceidle_maint");
1659 mActiveIdleWakeLock.setReferenceCounted(false);
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08001660 mGoingIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
1661 "deviceidle_going_idle");
1662 mGoingIdleWakeLock.setReferenceCounted(true);
Kweku Adams00e3a372018-09-28 16:57:09 -07001663 mConnectivityService = mInjector.getConnectivityService();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001664 mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface(
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001665 ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07001666 mNetworkPolicyManagerInternal = getLocalService(NetworkPolicyManagerInternal.class);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001667 mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001668 int sigMotionSensorId = getContext().getResources().getInteger(
1669 com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor);
1670 if (sigMotionSensorId > 0) {
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001671 mMotionSensor = mSensorManager.getDefaultSensor(sigMotionSensorId, true);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001672 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001673 if (mMotionSensor == null && getContext().getResources().getBoolean(
Joe LaPenna23d681b2015-08-27 15:12:11 -07001674 com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) {
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001675 mMotionSensor = mSensorManager.getDefaultSensor(
1676 Sensor.TYPE_WRIST_TILT_GESTURE, true);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001677 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001678 if (mMotionSensor == null) {
Joe LaPenna23d681b2015-08-27 15:12:11 -07001679 // As a last ditch, fall back to SMD.
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001680 mMotionSensor = mSensorManager.getDefaultSensor(
1681 Sensor.TYPE_SIGNIFICANT_MOTION, true);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001682 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001683
Joe LaPenna23d681b2015-08-27 15:12:11 -07001684 if (getContext().getResources().getBoolean(
1685 com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) {
Kweku Adams00e3a372018-09-28 16:57:09 -07001686 mLocationManager = mInjector.getLocationManager();
Joe LaPenna23d681b2015-08-27 15:12:11 -07001687 mLocationRequest = new LocationRequest()
1688 .setQuality(LocationRequest.ACCURACY_FINE)
1689 .setInterval(0)
1690 .setFastestInterval(0)
1691 .setNumUpdates(1);
1692 }
1693
1694 float angleThreshold = getContext().getResources().getInteger(
1695 com.android.internal.R.integer.config_autoPowerModeThresholdAngle) / 100f;
Kweku Adams00e3a372018-09-28 16:57:09 -07001696 mAnyMotionDetector = mInjector.getAnyMotionDetector(mHandler, mSensorManager, this,
1697 angleThreshold);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001698
Makoto Onukie4918212018-02-06 11:30:15 -08001699 mAppStateTracker.onSystemServicesReady();
1700
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001701 mIdleIntent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001702 mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1703 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001704 mLightIdleIntent = new Intent(PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
1705 mLightIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1706 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001707
1708 IntentFilter filter = new IntentFilter();
1709 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001710 getContext().registerReceiver(mReceiver, filter);
Amith Yamasaniac59f75e2016-05-05 12:38:17 -07001711
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07001712 filter = new IntentFilter();
1713 filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
1714 filter.addDataScheme("package");
Amith Yamasaniac59f75e2016-05-05 12:38:17 -07001715 getContext().registerReceiver(mReceiver, filter);
1716
Dianne Hackborn88c41352016-04-07 15:18:58 -07001717 filter = new IntentFilter();
1718 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07001719 getContext().registerReceiver(mReceiver, filter);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001720
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -07001721 filter = new IntentFilter();
1722 filter.addAction(Intent.ACTION_SCREEN_OFF);
1723 filter.addAction(Intent.ACTION_SCREEN_ON);
1724 getContext().registerReceiver(mInteractivityReceiver, filter);
1725
Makoto Onukiaf8ff4f2018-06-04 14:44:19 -07001726 mLocalActivityManager.setDeviceIdleWhitelist(
1727 mPowerSaveWhitelistAllAppIdArray, mPowerSaveWhitelistExceptIdleAppIdArray);
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001728 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -07001729
Wale Ogunwale6767eae2018-05-03 15:52:51 -07001730 mLocalActivityTaskManager.registerScreenObserver(mScreenObserver);
Amith Yamasani396a10c2018-01-19 10:58:07 -08001731
Suprabh Shukla5bf49812018-05-24 18:38:50 -07001732 passWhiteListsToForceAppStandbyTrackerLocked();
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -07001733 updateInteractivityLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001734 }
Dianne Hackborn4cb96ca2016-05-17 13:55:29 -07001735 updateConnectivityState(null);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001736 }
1737 }
1738
1739 public boolean addPowerSaveWhitelistAppInternal(String name) {
1740 synchronized (this) {
1741 try {
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07001742 ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name,
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -07001743 PackageManager.MATCH_ANY_USER);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001744 if (mPowerSaveWhitelistUserApps.put(name, UserHandle.getAppId(ai.uid)) == null) {
1745 reportPowerSaveWhitelistChangedLocked();
1746 updateWhitelistAppIdsLocked();
1747 writeConfigFileLocked();
1748 }
1749 return true;
1750 } catch (PackageManager.NameNotFoundException e) {
1751 return false;
1752 }
1753 }
1754 }
1755
1756 public boolean removePowerSaveWhitelistAppInternal(String name) {
1757 synchronized (this) {
1758 if (mPowerSaveWhitelistUserApps.remove(name) != null) {
1759 reportPowerSaveWhitelistChangedLocked();
1760 updateWhitelistAppIdsLocked();
1761 writeConfigFileLocked();
1762 return true;
1763 }
1764 }
1765 return false;
1766 }
1767
Felipe Lemef8a46232016-02-10 13:51:54 -08001768 public boolean getPowerSaveWhitelistAppInternal(String name) {
1769 synchronized (this) {
1770 return mPowerSaveWhitelistUserApps.containsKey(name);
1771 }
1772 }
1773
Suprabh Shukla08105642017-09-26 14:45:30 -07001774 void resetSystemPowerWhitelistInternal() {
1775 synchronized (this) {
1776 mPowerSaveWhitelistApps.putAll(mRemovedFromSystemWhitelistApps);
1777 mRemovedFromSystemWhitelistApps.clear();
1778 reportPowerSaveWhitelistChangedLocked();
1779 updateWhitelistAppIdsLocked();
1780 writeConfigFileLocked();
1781 }
1782 }
1783
1784 public boolean restoreSystemPowerWhitelistAppInternal(String name) {
1785 synchronized (this) {
1786 if (!mRemovedFromSystemWhitelistApps.containsKey(name)) {
1787 return false;
1788 }
1789 mPowerSaveWhitelistApps.put(name, mRemovedFromSystemWhitelistApps.remove(name));
1790 reportPowerSaveWhitelistChangedLocked();
1791 updateWhitelistAppIdsLocked();
1792 writeConfigFileLocked();
1793 return true;
1794 }
1795 }
1796
1797 public boolean removeSystemPowerWhitelistAppInternal(String name) {
1798 synchronized (this) {
1799 if (!mPowerSaveWhitelistApps.containsKey(name)) {
1800 return false;
1801 }
1802 mRemovedFromSystemWhitelistApps.put(name, mPowerSaveWhitelistApps.remove(name));
1803 reportPowerSaveWhitelistChangedLocked();
1804 updateWhitelistAppIdsLocked();
1805 writeConfigFileLocked();
1806 return true;
1807 }
1808 }
1809
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07001810 public boolean addPowerSaveWhitelistExceptIdleInternal(String name) {
1811 synchronized (this) {
1812 try {
1813 final ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name,
1814 PackageManager.MATCH_ANY_USER);
1815 if (mPowerSaveWhitelistAppsExceptIdle.put(name, UserHandle.getAppId(ai.uid))
1816 == null) {
1817 mPowerSaveWhitelistUserAppsExceptIdle.add(name);
1818 reportPowerSaveWhitelistChangedLocked();
1819 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(
1820 mPowerSaveWhitelistAppsExceptIdle, mPowerSaveWhitelistUserApps,
1821 mPowerSaveWhitelistExceptIdleAppIds);
Makoto Onuki71755c92018-01-16 14:15:44 -08001822
Suprabh Shukla5bf49812018-05-24 18:38:50 -07001823 passWhiteListsToForceAppStandbyTrackerLocked();
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07001824 }
1825 return true;
1826 } catch (PackageManager.NameNotFoundException e) {
1827 return false;
1828 }
1829 }
1830 }
1831
1832 public void resetPowerSaveWhitelistExceptIdleInternal() {
1833 synchronized (this) {
1834 if (mPowerSaveWhitelistAppsExceptIdle.removeAll(
1835 mPowerSaveWhitelistUserAppsExceptIdle)) {
1836 reportPowerSaveWhitelistChangedLocked();
1837 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(
1838 mPowerSaveWhitelistAppsExceptIdle, mPowerSaveWhitelistUserApps,
1839 mPowerSaveWhitelistExceptIdleAppIds);
1840 mPowerSaveWhitelistUserAppsExceptIdle.clear();
Makoto Onuki71755c92018-01-16 14:15:44 -08001841
Suprabh Shukla5bf49812018-05-24 18:38:50 -07001842 passWhiteListsToForceAppStandbyTrackerLocked();
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07001843 }
1844 }
1845 }
1846
1847 public boolean getPowerSaveWhitelistExceptIdleInternal(String name) {
1848 synchronized (this) {
1849 return mPowerSaveWhitelistAppsExceptIdle.containsKey(name);
1850 }
1851 }
1852
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001853 public String[] getSystemPowerWhitelistExceptIdleInternal() {
1854 synchronized (this) {
1855 int size = mPowerSaveWhitelistAppsExceptIdle.size();
1856 String[] apps = new String[size];
1857 for (int i = 0; i < size; i++) {
1858 apps[i] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i);
1859 }
1860 return apps;
1861 }
1862 }
1863
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001864 public String[] getSystemPowerWhitelistInternal() {
1865 synchronized (this) {
1866 int size = mPowerSaveWhitelistApps.size();
1867 String[] apps = new String[size];
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001868 for (int i = 0; i < size; i++) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001869 apps[i] = mPowerSaveWhitelistApps.keyAt(i);
1870 }
1871 return apps;
1872 }
1873 }
1874
Suprabh Shukla08105642017-09-26 14:45:30 -07001875 public String[] getRemovedSystemPowerWhitelistAppsInternal() {
1876 synchronized (this) {
1877 int size = mRemovedFromSystemWhitelistApps.size();
1878 final String[] apps = new String[size];
1879 for (int i = 0; i < size; i++) {
1880 apps[i] = mRemovedFromSystemWhitelistApps.keyAt(i);
1881 }
1882 return apps;
1883 }
1884 }
1885
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001886 public String[] getUserPowerWhitelistInternal() {
1887 synchronized (this) {
1888 int size = mPowerSaveWhitelistUserApps.size();
1889 String[] apps = new String[size];
1890 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
1891 apps[i] = mPowerSaveWhitelistUserApps.keyAt(i);
1892 }
1893 return apps;
1894 }
1895 }
1896
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001897 public String[] getFullPowerWhitelistExceptIdleInternal() {
1898 synchronized (this) {
1899 int size = mPowerSaveWhitelistAppsExceptIdle.size() + mPowerSaveWhitelistUserApps.size();
1900 String[] apps = new String[size];
1901 int cur = 0;
1902 for (int i = 0; i < mPowerSaveWhitelistAppsExceptIdle.size(); i++) {
1903 apps[cur] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i);
1904 cur++;
1905 }
1906 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
1907 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i);
1908 cur++;
1909 }
1910 return apps;
1911 }
1912 }
1913
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001914 public String[] getFullPowerWhitelistInternal() {
1915 synchronized (this) {
1916 int size = mPowerSaveWhitelistApps.size() + mPowerSaveWhitelistUserApps.size();
1917 String[] apps = new String[size];
1918 int cur = 0;
1919 for (int i = 0; i < mPowerSaveWhitelistApps.size(); i++) {
1920 apps[cur] = mPowerSaveWhitelistApps.keyAt(i);
1921 cur++;
1922 }
1923 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
1924 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i);
1925 cur++;
1926 }
1927 return apps;
1928 }
1929 }
1930
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001931 public boolean isPowerSaveWhitelistExceptIdleAppInternal(String packageName) {
1932 synchronized (this) {
1933 return mPowerSaveWhitelistAppsExceptIdle.containsKey(packageName)
1934 || mPowerSaveWhitelistUserApps.containsKey(packageName);
1935 }
1936 }
1937
Amith Yamasani06bf8242015-05-08 16:36:21 -07001938 public boolean isPowerSaveWhitelistAppInternal(String packageName) {
1939 synchronized (this) {
1940 return mPowerSaveWhitelistApps.containsKey(packageName)
1941 || mPowerSaveWhitelistUserApps.containsKey(packageName);
1942 }
1943 }
1944
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001945 public int[] getAppIdWhitelistExceptIdleInternal() {
1946 synchronized (this) {
1947 return mPowerSaveWhitelistExceptIdleAppIdArray;
1948 }
1949 }
1950
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001951 public int[] getAppIdWhitelistInternal() {
1952 synchronized (this) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001953 return mPowerSaveWhitelistAllAppIdArray;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001954 }
1955 }
1956
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001957 public int[] getAppIdUserWhitelistInternal() {
1958 synchronized (this) {
1959 return mPowerSaveWhitelistUserAppIdArray;
1960 }
1961 }
1962
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001963 public int[] getAppIdTempWhitelistInternal() {
1964 synchronized (this) {
1965 return mTempWhitelistAppIdArray;
1966 }
1967 }
1968
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001969 void addPowerSaveTempWhitelistAppChecked(String packageName, long duration,
1970 int userId, String reason) throws RemoteException {
1971 getContext().enforceCallingPermission(
1972 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
1973 "No permission to change device idle whitelist");
1974 final int callingUid = Binder.getCallingUid();
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001975 userId = ActivityManager.getService().handleIncomingUser(
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001976 Binder.getCallingPid(),
1977 callingUid,
1978 userId,
1979 /*allowAll=*/ false,
1980 /*requireFull=*/ false,
1981 "addPowerSaveTempWhitelistApp", null);
1982 final long token = Binder.clearCallingIdentity();
1983 try {
1984 addPowerSaveTempWhitelistAppInternal(callingUid,
1985 packageName, duration, userId, true, reason);
1986 } finally {
1987 Binder.restoreCallingIdentity(token);
1988 }
1989 }
1990
Sudheer Shanka326b3112017-11-27 14:40:57 -08001991 void removePowerSaveTempWhitelistAppChecked(String packageName, int userId)
1992 throws RemoteException {
1993 getContext().enforceCallingPermission(
1994 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
1995 "No permission to change device idle whitelist");
1996 final int callingUid = Binder.getCallingUid();
1997 userId = ActivityManager.getService().handleIncomingUser(
1998 Binder.getCallingPid(),
1999 callingUid,
2000 userId,
2001 /*allowAll=*/ false,
2002 /*requireFull=*/ false,
2003 "removePowerSaveTempWhitelistApp", null);
2004 final long token = Binder.clearCallingIdentity();
2005 try {
2006 removePowerSaveTempWhitelistAppInternal(packageName, userId);
2007 } finally {
2008 Binder.restoreCallingIdentity(token);
2009 }
2010 }
2011
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002012 /**
2013 * Adds an app to the temporary whitelist and resets the endTime for granting the
2014 * app an exemption to access network and acquire wakelocks.
2015 */
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002016 void addPowerSaveTempWhitelistAppInternal(int callingUid, String packageName,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002017 long duration, int userId, boolean sync, String reason) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002018 try {
Jeff Sharkeye06b4d12016-01-06 14:51:50 -07002019 int uid = getContext().getPackageManager().getPackageUidAsUser(packageName, userId);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002020 int appId = UserHandle.getAppId(uid);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002021 addPowerSaveTempWhitelistAppDirectInternal(callingUid, appId, duration, sync, reason);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002022 } catch (NameNotFoundException e) {
2023 }
2024 }
2025
Dianne Hackborna750a632015-06-16 17:18:23 -07002026 /**
2027 * Adds an app to the temporary whitelist and resets the endTime for granting the
2028 * app an exemption to access network and acquire wakelocks.
2029 */
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002030 void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int appId,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002031 long duration, boolean sync, String reason) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002032 final long timeNow = SystemClock.elapsedRealtime();
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07002033 boolean informWhitelistChanged = false;
Dianne Hackborna750a632015-06-16 17:18:23 -07002034 synchronized (this) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002035 int callingAppId = UserHandle.getAppId(callingUid);
2036 if (callingAppId >= Process.FIRST_APPLICATION_UID) {
2037 if (!mPowerSaveWhitelistSystemAppIds.get(callingAppId)) {
2038 throw new SecurityException("Calling app " + UserHandle.formatUid(callingUid)
2039 + " is not on whitelist");
2040 }
2041 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002042 duration = Math.min(duration, mConstants.MAX_TEMP_APP_WHITELIST_DURATION);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002043 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId);
2044 final boolean newEntry = entry == null;
Dianne Hackborna750a632015-06-16 17:18:23 -07002045 // Set the new end time
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002046 if (newEntry) {
2047 entry = new Pair<>(new MutableLong(0), reason);
2048 mTempWhitelistAppIdEndTimes.put(appId, entry);
2049 }
2050 entry.first.value = timeNow + duration;
Dianne Hackborna750a632015-06-16 17:18:23 -07002051 if (DEBUG) {
Felipe Lemea1b79bf2016-05-24 13:06:54 -07002052 Slog.d(TAG, "Adding AppId " + appId + " to temp whitelist. New entry: " + newEntry);
Dianne Hackborna750a632015-06-16 17:18:23 -07002053 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002054 if (newEntry) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002055 // No pending timeout for the app id, post a delayed message
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002056 try {
2057 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_START,
2058 reason, appId);
2059 } catch (RemoteException e) {
2060 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002061 postTempActiveTimeoutMessage(appId, duration);
Dianne Hackborn85e35642017-01-12 15:10:57 -08002062 updateTempWhitelistAppIdsLocked(appId, true);
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07002063 if (sync) {
2064 informWhitelistChanged = true;
2065 } else {
2066 mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED, appId, 1)
2067 .sendToTarget();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002068 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002069 reportTempWhitelistChangedLocked();
2070 }
2071 }
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07002072 if (informWhitelistChanged) {
2073 mNetworkPolicyManagerInternal.onTempPowerSaveWhitelistChange(appId, true);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002074 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002075 }
2076
Sudheer Shanka326b3112017-11-27 14:40:57 -08002077 /**
2078 * Removes an app from the temporary whitelist and notifies the observers.
2079 */
2080 private void removePowerSaveTempWhitelistAppInternal(String packageName, int userId) {
2081 try {
2082 final int uid = getContext().getPackageManager().getPackageUidAsUser(
2083 packageName, userId);
2084 final int appId = UserHandle.getAppId(uid);
2085 removePowerSaveTempWhitelistAppDirectInternal(appId);
2086 } catch (NameNotFoundException e) {
2087 }
2088 }
2089
2090 private void removePowerSaveTempWhitelistAppDirectInternal(int appId) {
2091 synchronized (this) {
2092 final int idx = mTempWhitelistAppIdEndTimes.indexOfKey(appId);
2093 if (idx < 0) {
2094 // Nothing else to do
2095 return;
2096 }
2097 final String reason = mTempWhitelistAppIdEndTimes.valueAt(idx).second;
2098 mTempWhitelistAppIdEndTimes.removeAt(idx);
2099 onAppRemovedFromTempWhitelistLocked(appId, reason);
2100 }
2101 }
2102
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002103 private void postTempActiveTimeoutMessage(int uid, long delay) {
Felipe Lemea1b79bf2016-05-24 13:06:54 -07002104 if (DEBUG) {
2105 Slog.d(TAG, "postTempActiveTimeoutMessage: uid=" + uid + ", delay=" + delay);
2106 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002107 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, uid, 0),
2108 delay);
2109 }
2110
2111 void checkTempAppWhitelistTimeout(int uid) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002112 final long timeNow = SystemClock.elapsedRealtime();
Felipe Lemea1b79bf2016-05-24 13:06:54 -07002113 if (DEBUG) {
2114 Slog.d(TAG, "checkTempAppWhitelistTimeout: uid=" + uid + ", timeNow=" + timeNow);
2115 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002116 synchronized (this) {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002117 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(uid);
2118 if (entry == null) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002119 // Nothing to do
2120 return;
2121 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002122 if (timeNow >= entry.first.value) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002123 mTempWhitelistAppIdEndTimes.delete(uid);
Sudheer Shanka326b3112017-11-27 14:40:57 -08002124 onAppRemovedFromTempWhitelistLocked(uid, entry.second);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002125 } else {
2126 // Need more time
Felipe Lemea1b79bf2016-05-24 13:06:54 -07002127 if (DEBUG) {
2128 Slog.d(TAG, "Time to remove UID " + uid + ": " + entry.first.value);
2129 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002130 postTempActiveTimeoutMessage(uid, entry.first.value - timeNow);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002131 }
2132 }
2133 }
2134
Sudheer Shanka326b3112017-11-27 14:40:57 -08002135 @GuardedBy("this")
2136 private void onAppRemovedFromTempWhitelistLocked(int appId, String reason) {
2137 if (DEBUG) {
2138 Slog.d(TAG, "Removing appId " + appId + " from temp whitelist");
2139 }
2140 updateTempWhitelistAppIdsLocked(appId, false);
2141 mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED, appId, 0)
2142 .sendToTarget();
2143 reportTempWhitelistChangedLocked();
2144 try {
2145 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH,
2146 reason, appId);
2147 } catch (RemoteException e) {
2148 }
2149 }
2150
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002151 public void exitIdleInternal(String reason) {
2152 synchronized (this) {
2153 becomeActiveLocked(reason, Binder.getCallingUid());
2154 }
2155 }
2156
Dianne Hackborn4cb96ca2016-05-17 13:55:29 -07002157 void updateConnectivityState(Intent connIntent) {
2158 ConnectivityService cm;
2159 synchronized (this) {
2160 cm = mConnectivityService;
2161 }
2162 if (cm == null) {
2163 return;
2164 }
2165 // Note: can't call out to ConnectivityService with our lock held.
2166 NetworkInfo ni = cm.getActiveNetworkInfo();
2167 synchronized (this) {
Dianne Hackborn88c41352016-04-07 15:18:58 -07002168 boolean conn;
2169 if (ni == null) {
2170 conn = false;
2171 } else {
2172 if (connIntent == null) {
2173 conn = ni.isConnected();
2174 } else {
2175 final int networkType =
2176 connIntent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE,
2177 ConnectivityManager.TYPE_NONE);
2178 if (ni.getType() != networkType) {
2179 return;
2180 }
2181 conn = !connIntent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,
2182 false);
2183 }
2184 }
2185 if (conn != mNetworkConnected) {
2186 mNetworkConnected = conn;
2187 if (conn && mLightState == LIGHT_STATE_WAITING_FOR_NETWORK) {
2188 stepLightIdleStateLocked("network");
2189 }
2190 }
2191 }
2192 }
2193
Kweku Adams00e3a372018-09-28 16:57:09 -07002194 @VisibleForTesting
2195 boolean isScreenOn() {
2196 return mScreenOn;
2197 }
2198
Dianne Hackborn3dba8ce2017-09-01 17:07:04 -07002199 void updateInteractivityLocked() {
2200 // The interactivity state from the power manager tells us whether the display is
2201 // in a state that we need to keep things running so they will update at a normal
2202 // frequency.
2203 boolean screenOn = mPowerManager.isInteractive();
2204 if (DEBUG) Slog.d(TAG, "updateInteractivityLocked: screenOn=" + screenOn);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002205 if (!screenOn && mScreenOn) {
2206 mScreenOn = false;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002207 if (!mForceIdle) {
2208 becomeInactiveIfAppropriateLocked();
2209 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002210 } else if (screenOn) {
2211 mScreenOn = true;
Amith Yamasani396a10c2018-01-19 10:58:07 -08002212 if (!mForceIdle && (!mScreenLocked || !mConstants.WAIT_FOR_UNLOCK)) {
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002213 becomeActiveLocked("screen", Process.myUid());
2214 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002215 }
2216 }
2217
Kweku Adams00e3a372018-09-28 16:57:09 -07002218 @VisibleForTesting
2219 boolean isCharging() {
2220 return mCharging;
2221 }
2222
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002223 void updateChargingLocked(boolean charging) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002224 if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002225 if (!charging && mCharging) {
2226 mCharging = false;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002227 if (!mForceIdle) {
2228 becomeInactiveIfAppropriateLocked();
2229 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002230 } else if (charging) {
2231 mCharging = charging;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002232 if (!mForceIdle) {
2233 becomeActiveLocked("charging", Process.myUid());
2234 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002235 }
2236 }
2237
Amith Yamasani396a10c2018-01-19 10:58:07 -08002238 void keyguardShowingLocked(boolean showing) {
2239 if (DEBUG) Slog.i(TAG, "keyguardShowing=" + showing);
2240 if (mScreenLocked != showing) {
2241 mScreenLocked = showing;
2242 if (mScreenOn && !mForceIdle && !mScreenLocked) {
2243 becomeActiveLocked("unlocked", Process.myUid());
2244 }
2245 }
2246 }
2247
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002248 void scheduleReportActiveLocked(String activeReason, int activeUid) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002249 Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid, 0, activeReason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002250 mHandler.sendMessage(msg);
2251 }
2252
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002253 void becomeActiveLocked(String activeReason, int activeUid) {
2254 if (DEBUG) Slog.i(TAG, "becomeActiveLocked, reason = " + activeReason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002255 if (mState != STATE_ACTIVE || mLightState != STATE_ACTIVE) {
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002256 EventLogTags.writeDeviceIdle(STATE_ACTIVE, activeReason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002257 EventLogTags.writeDeviceIdleLight(LIGHT_STATE_ACTIVE, activeReason);
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002258 scheduleReportActiveLocked(activeReason, activeUid);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002259 mState = STATE_ACTIVE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002260 mLightState = LIGHT_STATE_ACTIVE;
Adam Lesinski31c05d12015-06-09 17:34:04 -07002261 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002262 mCurIdleBudget = 0;
2263 mMaintenanceStartTime = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002264 resetIdleManagementLocked();
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002265 resetLightIdleManagementLocked();
Amith Yamasaniac6517a2018-04-23 12:19:34 -07002266 addEvent(EVENT_NORMAL, activeReason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002267 }
2268 }
2269
Kweku Adams00e3a372018-09-28 16:57:09 -07002270 /** Must only be used in tests. */
2271 @VisibleForTesting
2272 void setDeepEnabledForTest(boolean enabled) {
2273 mDeepEnabled = enabled;
2274 }
2275
2276 /** Must only be used in tests. */
2277 @VisibleForTesting
2278 void setLightEnabledForTest(boolean enabled) {
2279 mLightEnabled = enabled;
2280 }
2281
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002282 void becomeInactiveIfAppropriateLocked() {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002283 if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()");
Dianne Hackbornb6843652016-02-22 12:20:13 -08002284 if ((!mScreenOn && !mCharging) || mForceIdle) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002285 // Screen has turned off; we are now going to become inactive and start
2286 // waiting to see if we will ultimately go idle.
Dianne Hackbornb6843652016-02-22 12:20:13 -08002287 if (mState == STATE_ACTIVE && mDeepEnabled) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002288 mState = STATE_INACTIVE;
2289 if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE");
2290 resetIdleManagementLocked();
2291 scheduleAlarmLocked(mInactiveTimeout, false);
2292 EventLogTags.writeDeviceIdle(mState, "no activity");
2293 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08002294 if (mLightState == LIGHT_STATE_ACTIVE && mLightEnabled) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002295 mLightState = LIGHT_STATE_INACTIVE;
2296 if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE");
2297 resetLightIdleManagementLocked();
Dianne Hackborn953fc942016-03-29 15:36:24 -07002298 scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002299 EventLogTags.writeDeviceIdleLight(mLightState, "no activity");
2300 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002301 }
2302 }
2303
Kweku Adams00e3a372018-09-28 16:57:09 -07002304 private void resetIdleManagementLocked() {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002305 mNextIdlePendingDelay = 0;
2306 mNextIdleDelay = 0;
Dianne Hackborn953fc942016-03-29 15:36:24 -07002307 mNextLightIdleDelay = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002308 cancelAlarmLocked();
Kevin Gabayan92f15e62016-04-04 17:52:22 -07002309 cancelSensingTimeoutAlarmLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002310 cancelLocatingLocked();
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002311 stopMonitoringMotionLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002312 mAnyMotionDetector.stop();
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002313 }
2314
Kweku Adams00e3a372018-09-28 16:57:09 -07002315 private void resetLightIdleManagementLocked() {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002316 cancelLightAlarmLocked();
2317 }
2318
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002319 void exitForceIdleLocked() {
2320 if (mForceIdle) {
2321 mForceIdle = false;
2322 if (mScreenOn || mCharging) {
Dianne Hackborn88c41352016-04-07 15:18:58 -07002323 becomeActiveLocked("exit-force", Process.myUid());
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002324 }
2325 }
2326 }
2327
Kweku Adams00e3a372018-09-28 16:57:09 -07002328 @VisibleForTesting
2329 int getLightState() {
2330 return mLightState;
2331 }
2332
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002333 void stepLightIdleStateLocked(String reason) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002334 if (mLightState == LIGHT_STATE_OVERRIDE) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08002335 // If we are already in deep device idle mode, then
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002336 // there is nothing left to do for light mode.
2337 return;
2338 }
2339
2340 if (DEBUG) Slog.d(TAG, "stepLightIdleStateLocked: mLightState=" + mLightState);
2341 EventLogTags.writeDeviceIdleLightStep();
2342
2343 switch (mLightState) {
2344 case LIGHT_STATE_INACTIVE:
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002345 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
Dianne Hackborn953fc942016-03-29 15:36:24 -07002346 // Reset the upcoming idle delays.
2347 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002348 mMaintenanceStartTime = 0;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002349 if (!isOpsInactiveLocked()) {
2350 // We have some active ops going on... give them a chance to finish
2351 // before going in to our first idle.
2352 mLightState = LIGHT_STATE_PRE_IDLE;
2353 EventLogTags.writeDeviceIdleLight(mLightState, reason);
2354 scheduleLightAlarmLocked(mConstants.LIGHT_PRE_IDLE_TIMEOUT);
2355 break;
2356 }
2357 // Nothing active, fall through to immediately idle.
2358 case LIGHT_STATE_PRE_IDLE:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002359 case LIGHT_STATE_IDLE_MAINTENANCE:
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002360 if (mMaintenanceStartTime != 0) {
2361 long duration = SystemClock.elapsedRealtime() - mMaintenanceStartTime;
2362 if (duration < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
2363 // We didn't use up all of our minimum budget; add this to the reserve.
2364 mCurIdleBudget += (mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET-duration);
2365 } else {
2366 // We used more than our minimum budget; this comes out of the reserve.
2367 mCurIdleBudget -= (duration-mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET);
2368 }
2369 }
2370 mMaintenanceStartTime = 0;
Dianne Hackborn953fc942016-03-29 15:36:24 -07002371 scheduleLightAlarmLocked(mNextLightIdleDelay);
2372 mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT,
2373 (long)(mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR));
2374 if (mNextLightIdleDelay < mConstants.LIGHT_IDLE_TIMEOUT) {
2375 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT;
2376 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002377 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_STATE_IDLE.");
2378 mLightState = LIGHT_STATE_IDLE;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002379 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Amith Yamasaniac6517a2018-04-23 12:19:34 -07002380 addEvent(EVENT_LIGHT_IDLE, null);
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08002381 mGoingIdleWakeLock.acquire();
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002382 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON_LIGHT);
2383 break;
2384 case LIGHT_STATE_IDLE:
Dianne Hackborn88c41352016-04-07 15:18:58 -07002385 case LIGHT_STATE_WAITING_FOR_NETWORK:
2386 if (mNetworkConnected || mLightState == LIGHT_STATE_WAITING_FOR_NETWORK) {
2387 // We have been idling long enough, now it is time to do some work.
2388 mActiveIdleOpCount = 1;
2389 mActiveIdleWakeLock.acquire();
2390 mMaintenanceStartTime = SystemClock.elapsedRealtime();
2391 if (mCurIdleBudget < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
2392 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
2393 } else if (mCurIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) {
2394 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
2395 }
2396 scheduleLightAlarmLocked(mCurIdleBudget);
2397 if (DEBUG) Slog.d(TAG,
2398 "Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE.");
2399 mLightState = LIGHT_STATE_IDLE_MAINTENANCE;
2400 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Amith Yamasaniac6517a2018-04-23 12:19:34 -07002401 addEvent(EVENT_LIGHT_MAINTENANCE, null);
Dianne Hackborn88c41352016-04-07 15:18:58 -07002402 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
2403 } else {
2404 // We'd like to do maintenance, but currently don't have network
2405 // connectivity... let's try to wait until the network comes back.
2406 // We'll only wait for another full idle period, however, and then give up.
2407 scheduleLightAlarmLocked(mNextLightIdleDelay);
2408 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_WAITING_FOR_NETWORK.");
2409 mLightState = LIGHT_STATE_WAITING_FOR_NETWORK;
2410 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002411 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002412 break;
2413 }
2414 }
2415
Kweku Adams00e3a372018-09-28 16:57:09 -07002416 /** Must only be used in tests. */
2417 @VisibleForTesting
2418 void setLocationManagerForTest(LocationManager lm) {
2419 mLocationManager = lm;
2420 }
2421
2422 @VisibleForTesting
2423 int getState() {
2424 return mState;
2425 }
2426
2427 @VisibleForTesting
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002428 void stepIdleStateLocked(String reason) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002429 if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002430 EventLogTags.writeDeviceIdleStep();
2431
2432 final long now = SystemClock.elapsedRealtime();
Adam Lesinski31c05d12015-06-09 17:34:04 -07002433 if ((now+mConstants.MIN_TIME_TO_ALARM) > mAlarmManager.getNextWakeFromIdleTime()) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002434 // Whoops, there is an upcoming alarm. We don't actually want to go idle.
2435 if (mState != STATE_ACTIVE) {
Dianne Hackbornb6683c42015-06-18 17:40:33 -07002436 becomeActiveLocked("alarm", Process.myUid());
Koji Fukui27b33302015-12-16 19:43:01 +09002437 becomeInactiveIfAppropriateLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002438 }
2439 return;
2440 }
2441
2442 switch (mState) {
2443 case STATE_INACTIVE:
2444 // We have now been inactive long enough, it is time to start looking
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002445 // for motion and sleep some more while doing so.
2446 startMonitoringMotionLocked();
Adam Lesinski31c05d12015-06-09 17:34:04 -07002447 scheduleAlarmLocked(mConstants.IDLE_AFTER_INACTIVE_TIMEOUT, false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002448 // Reset the upcoming idle delays.
Adam Lesinski31c05d12015-06-09 17:34:04 -07002449 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
2450 mNextIdleDelay = mConstants.IDLE_TIMEOUT;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002451 mState = STATE_IDLE_PENDING;
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002452 if (DEBUG) Slog.d(TAG, "Moved from STATE_INACTIVE to STATE_IDLE_PENDING.");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002453 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002454 break;
2455 case STATE_IDLE_PENDING:
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002456 mState = STATE_SENSING;
2457 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING.");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002458 EventLogTags.writeDeviceIdle(mState, reason);
Kevin Gabayan92f15e62016-04-04 17:52:22 -07002459 scheduleSensingTimeoutAlarmLocked(mConstants.SENSING_TIMEOUT);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002460 cancelLocatingLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002461 mNotMoving = false;
2462 mLocated = false;
2463 mLastGenericLocation = null;
2464 mLastGpsLocation = null;
Kevin Gabayan92f15e62016-04-04 17:52:22 -07002465 mAnyMotionDetector.checkForAnyMotion();
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002466 break;
2467 case STATE_SENSING:
Kevin Gabayan92f15e62016-04-04 17:52:22 -07002468 cancelSensingTimeoutAlarmLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002469 mState = STATE_LOCATING;
2470 if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING.");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002471 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002472 scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT, false);
Joe LaPenna23d681b2015-08-27 15:12:11 -07002473 if (mLocationManager != null
2474 && mLocationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
2475 mLocationManager.requestLocationUpdates(mLocationRequest,
2476 mGenericLocationListener, mHandler.getLooper());
2477 mLocating = true;
2478 } else {
2479 mHasNetworkLocation = false;
2480 }
2481 if (mLocationManager != null
2482 && mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
2483 mHasGps = true;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002484 mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5,
2485 mGpsLocationListener, mHandler.getLooper());
Joe LaPenna23d681b2015-08-27 15:12:11 -07002486 mLocating = true;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002487 } else {
Joe LaPenna23d681b2015-08-27 15:12:11 -07002488 mHasGps = false;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002489 }
Joe LaPenna23d681b2015-08-27 15:12:11 -07002490 // If we have a location provider, we're all set, the listeners will move state
2491 // forward.
2492 if (mLocating) {
2493 break;
2494 }
2495
2496 // Otherwise, we have to move from locating into idle maintenance.
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002497 case STATE_LOCATING:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002498 cancelAlarmLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002499 cancelLocatingLocked();
2500 mAnyMotionDetector.stop();
Dianne Hackborn953fc942016-03-29 15:36:24 -07002501
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002502 case STATE_IDLE_MAINTENANCE:
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002503 scheduleAlarmLocked(mNextIdleDelay, true);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002504 if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay +
2505 " ms.");
Adam Lesinski31c05d12015-06-09 17:34:04 -07002506 mNextIdleDelay = (long)(mNextIdleDelay * mConstants.IDLE_FACTOR);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002507 if (DEBUG) Slog.d(TAG, "Setting mNextIdleDelay = " + mNextIdleDelay);
Adam Lesinski31c05d12015-06-09 17:34:04 -07002508 mNextIdleDelay = Math.min(mNextIdleDelay, mConstants.MAX_IDLE_TIMEOUT);
Dianne Hackborn953fc942016-03-29 15:36:24 -07002509 if (mNextIdleDelay < mConstants.IDLE_TIMEOUT) {
2510 mNextIdleDelay = mConstants.IDLE_TIMEOUT;
2511 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002512 mState = STATE_IDLE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002513 if (mLightState != LIGHT_STATE_OVERRIDE) {
2514 mLightState = LIGHT_STATE_OVERRIDE;
2515 cancelLightAlarmLocked();
2516 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002517 EventLogTags.writeDeviceIdle(mState, reason);
Amith Yamasaniac6517a2018-04-23 12:19:34 -07002518 addEvent(EVENT_DEEP_IDLE, null);
Joe Onorato8f0e9ced2016-12-08 17:48:49 -08002519 mGoingIdleWakeLock.acquire();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002520 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON);
2521 break;
2522 case STATE_IDLE:
2523 // We have been idling long enough, now it is time to do some work.
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002524 mActiveIdleOpCount = 1;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002525 mActiveIdleWakeLock.acquire();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002526 scheduleAlarmLocked(mNextIdlePendingDelay, false);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002527 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE to STATE_IDLE_MAINTENANCE. " +
2528 "Next alarm in " + mNextIdlePendingDelay + " ms.");
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002529 mMaintenanceStartTime = SystemClock.elapsedRealtime();
Adam Lesinski31c05d12015-06-09 17:34:04 -07002530 mNextIdlePendingDelay = Math.min(mConstants.MAX_IDLE_PENDING_TIMEOUT,
2531 (long)(mNextIdlePendingDelay * mConstants.IDLE_PENDING_FACTOR));
Dianne Hackborn953fc942016-03-29 15:36:24 -07002532 if (mNextIdlePendingDelay < mConstants.IDLE_PENDING_TIMEOUT) {
2533 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
2534 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002535 mState = STATE_IDLE_MAINTENANCE;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002536 EventLogTags.writeDeviceIdle(mState, reason);
Amith Yamasaniac6517a2018-04-23 12:19:34 -07002537 addEvent(EVENT_DEEP_MAINTENANCE, null);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002538 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
2539 break;
2540 }
2541 }
2542
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002543 void incActiveIdleOps() {
2544 synchronized (this) {
2545 mActiveIdleOpCount++;
2546 }
2547 }
2548
2549 void decActiveIdleOps() {
2550 synchronized (this) {
2551 mActiveIdleOpCount--;
2552 if (mActiveIdleOpCount <= 0) {
2553 exitMaintenanceEarlyIfNeededLocked();
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002554 mActiveIdleWakeLock.release();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002555 }
2556 }
2557 }
2558
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002559 void setJobsActive(boolean active) {
2560 synchronized (this) {
2561 mJobsActive = active;
Yao Chenca5edbb2016-01-13 14:44:36 -08002562 reportMaintenanceActivityIfNeededLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002563 if (!active) {
2564 exitMaintenanceEarlyIfNeededLocked();
2565 }
2566 }
2567 }
2568
2569 void setAlarmsActive(boolean active) {
2570 synchronized (this) {
2571 mAlarmsActive = active;
2572 if (!active) {
2573 exitMaintenanceEarlyIfNeededLocked();
2574 }
2575 }
2576 }
2577
Yao Chenca5edbb2016-01-13 14:44:36 -08002578 boolean registerMaintenanceActivityListener(IMaintenanceActivityListener listener) {
2579 synchronized (this) {
2580 mMaintenanceActivityListeners.register(listener);
2581 return mReportedMaintenanceActivity;
2582 }
2583 }
2584
2585 void unregisterMaintenanceActivityListener(IMaintenanceActivityListener listener) {
2586 synchronized (this) {
2587 mMaintenanceActivityListeners.unregister(listener);
2588 }
2589 }
2590
2591 void reportMaintenanceActivityIfNeededLocked() {
Dianne Hackborn7ab40252016-06-15 17:30:24 -07002592 boolean active = mJobsActive;
Yao Chenca5edbb2016-01-13 14:44:36 -08002593 if (active == mReportedMaintenanceActivity) {
2594 return;
2595 }
2596 mReportedMaintenanceActivity = active;
2597 Message msg = mHandler.obtainMessage(MSG_REPORT_MAINTENANCE_ACTIVITY,
2598 mReportedMaintenanceActivity ? 1 : 0, 0);
2599 mHandler.sendMessage(msg);
2600 }
2601
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002602 boolean isOpsInactiveLocked() {
Dianne Hackborn7ab40252016-06-15 17:30:24 -07002603 return mActiveIdleOpCount <= 0 && !mJobsActive && !mAlarmsActive;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002604 }
2605
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002606 void exitMaintenanceEarlyIfNeededLocked() {
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002607 if (mState == STATE_IDLE_MAINTENANCE || mLightState == LIGHT_STATE_IDLE_MAINTENANCE
2608 || mLightState == LIGHT_STATE_PRE_IDLE) {
2609 if (isOpsInactiveLocked()) {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002610 final long now = SystemClock.elapsedRealtime();
2611 if (DEBUG) {
2612 StringBuilder sb = new StringBuilder();
2613 sb.append("Exit: start=");
2614 TimeUtils.formatDuration(mMaintenanceStartTime, sb);
2615 sb.append(" now=");
2616 TimeUtils.formatDuration(now, sb);
2617 Slog.d(TAG, sb.toString());
2618 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002619 if (mState == STATE_IDLE_MAINTENANCE) {
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002620 stepIdleStateLocked("s:early");
2621 } else if (mLightState == LIGHT_STATE_PRE_IDLE) {
2622 stepLightIdleStateLocked("s:predone");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002623 } else {
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002624 stepLightIdleStateLocked("s:early");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002625 }
2626 }
2627 }
2628 }
2629
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002630 void motionLocked() {
2631 if (DEBUG) Slog.d(TAG, "motionLocked()");
2632 // The motion sensor will have been disabled at this point
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002633 handleMotionDetectedLocked(mConstants.MOTION_INACTIVE_TIMEOUT, "motion");
2634 }
2635
2636 void handleMotionDetectedLocked(long timeout, String type) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002637 // The device is not yet active, so we want to go back to the pending idle
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002638 // state to wait again for no motion. Note that we only monitor for motion
2639 // after moving out of the inactive state, so no need to worry about that.
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002640 boolean becomeInactive = false;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002641 if (mState != STATE_ACTIVE) {
Amith Yamasani4cb42572018-04-27 10:02:57 -07002642 // Motion shouldn't affect light state, if it's already in doze-light or maintenance
2643 boolean lightIdle = mLightState == LIGHT_STATE_IDLE
2644 || mLightState == LIGHT_STATE_WAITING_FOR_NETWORK
2645 || mLightState == LIGHT_STATE_IDLE_MAINTENANCE;
2646 if (!lightIdle) {
2647 // Only switch to active state if we're not in either idle state
2648 scheduleReportActiveLocked(type, Process.myUid());
2649 addEvent(EVENT_NORMAL, type);
2650 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002651 mState = STATE_ACTIVE;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002652 mInactiveTimeout = timeout;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002653 mCurIdleBudget = 0;
2654 mMaintenanceStartTime = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002655 EventLogTags.writeDeviceIdle(mState, type);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002656 becomeInactive = true;
2657 }
2658 if (mLightState == LIGHT_STATE_OVERRIDE) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08002659 // We went out of light idle mode because we had started deep idle mode... let's
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002660 // now go back and reset things so we resume light idling if appropriate.
Amith Yamasani4cb42572018-04-27 10:02:57 -07002661 mLightState = LIGHT_STATE_ACTIVE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002662 EventLogTags.writeDeviceIdleLight(mLightState, type);
2663 becomeInactive = true;
2664 }
2665 if (becomeInactive) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002666 becomeInactiveIfAppropriateLocked();
2667 }
2668 }
2669
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002670 void receivedGenericLocationLocked(Location location) {
2671 if (mState != STATE_LOCATING) {
2672 cancelLocatingLocked();
2673 return;
2674 }
2675 if (DEBUG) Slog.d(TAG, "Generic location: " + location);
2676 mLastGenericLocation = new Location(location);
Joe LaPenna23d681b2015-08-27 15:12:11 -07002677 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHasGps) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002678 return;
2679 }
2680 mLocated = true;
2681 if (mNotMoving) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002682 stepIdleStateLocked("s:location");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002683 }
2684 }
2685
2686 void receivedGpsLocationLocked(Location location) {
2687 if (mState != STATE_LOCATING) {
2688 cancelLocatingLocked();
2689 return;
2690 }
2691 if (DEBUG) Slog.d(TAG, "GPS location: " + location);
2692 mLastGpsLocation = new Location(location);
2693 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY) {
2694 return;
2695 }
2696 mLocated = true;
2697 if (mNotMoving) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002698 stepIdleStateLocked("s:gps");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002699 }
2700 }
2701
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002702 void startMonitoringMotionLocked() {
2703 if (DEBUG) Slog.d(TAG, "startMonitoringMotionLocked()");
2704 if (mMotionSensor != null && !mMotionListener.active) {
2705 mMotionListener.registerLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002706 }
2707 }
2708
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002709 void stopMonitoringMotionLocked() {
2710 if (DEBUG) Slog.d(TAG, "stopMonitoringMotionLocked()");
2711 if (mMotionSensor != null && mMotionListener.active) {
2712 mMotionListener.unregisterLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002713 }
2714 }
2715
2716 void cancelAlarmLocked() {
2717 if (mNextAlarmTime != 0) {
2718 mNextAlarmTime = 0;
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002719 mAlarmManager.cancel(mDeepAlarmListener);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002720 }
2721 }
2722
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002723 void cancelLightAlarmLocked() {
2724 if (mNextLightAlarmTime != 0) {
2725 mNextLightAlarmTime = 0;
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002726 mAlarmManager.cancel(mLightAlarmListener);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002727 }
2728 }
2729
2730 void cancelLocatingLocked() {
2731 if (mLocating) {
2732 mLocationManager.removeUpdates(mGenericLocationListener);
2733 mLocationManager.removeUpdates(mGpsLocationListener);
2734 mLocating = false;
2735 }
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002736 }
2737
Kevin Gabayan92f15e62016-04-04 17:52:22 -07002738 void cancelSensingTimeoutAlarmLocked() {
2739 if (mNextSensingTimeoutAlarmTime != 0) {
2740 mNextSensingTimeoutAlarmTime = 0;
2741 mAlarmManager.cancel(mSensingTimeoutAlarmListener);
2742 }
2743 }
2744
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002745 void scheduleAlarmLocked(long delay, boolean idleUntil) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002746 if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")");
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002747 if (mMotionSensor == null) {
Joe LaPenna23d681b2015-08-27 15:12:11 -07002748 // If there is no motion sensor on this device, then we won't schedule
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002749 // alarms, because we can't determine if the device is not moving. This effectively
Joe LaPenna23d681b2015-08-27 15:12:11 -07002750 // turns off normal execution of device idling, although it is still possible to
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002751 // manually poke it by pretending like the alarm is going off.
2752 return;
2753 }
2754 mNextAlarmTime = SystemClock.elapsedRealtime() + delay;
2755 if (idleUntil) {
2756 mAlarmManager.setIdleUntil(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002757 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002758 } else {
2759 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002760 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002761 }
2762 }
2763
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002764 void scheduleLightAlarmLocked(long delay) {
2765 if (DEBUG) Slog.d(TAG, "scheduleLightAlarmLocked(" + delay + ")");
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002766 mNextLightAlarmTime = SystemClock.elapsedRealtime() + delay;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002767 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002768 mNextLightAlarmTime, "DeviceIdleController.light", mLightAlarmListener, mHandler);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002769 }
2770
Kevin Gabayan92f15e62016-04-04 17:52:22 -07002771 void scheduleSensingTimeoutAlarmLocked(long delay) {
2772 if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")");
2773 mNextSensingTimeoutAlarmTime = SystemClock.elapsedRealtime() + delay;
2774 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextSensingTimeoutAlarmTime,
2775 "DeviceIdleController.sensing", mSensingTimeoutAlarmListener, mHandler);
2776 }
2777
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002778 private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps,
2779 ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds) {
2780 outAppIds.clear();
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002781 if (systemApps != null) {
2782 for (int i = 0; i < systemApps.size(); i++) {
2783 outAppIds.put(systemApps.valueAt(i), true);
2784 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002785 }
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002786 if (userApps != null) {
2787 for (int i = 0; i < userApps.size(); i++) {
2788 outAppIds.put(userApps.valueAt(i), true);
2789 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002790 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002791 int size = outAppIds.size();
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002792 int[] appids = new int[size];
2793 for (int i = 0; i < size; i++) {
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002794 appids[i] = outAppIds.keyAt(i);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002795 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002796 return appids;
2797 }
2798
2799 private void updateWhitelistAppIdsLocked() {
2800 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(mPowerSaveWhitelistAppsExceptIdle,
2801 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistExceptIdleAppIds);
2802 mPowerSaveWhitelistAllAppIdArray = buildAppIdArray(mPowerSaveWhitelistApps,
2803 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistAllAppIds);
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002804 mPowerSaveWhitelistUserAppIdArray = buildAppIdArray(null,
2805 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistUserAppIds);
Dianne Hackborn85e35642017-01-12 15:10:57 -08002806 if (mLocalActivityManager != null) {
Makoto Onukiaf8ff4f2018-06-04 14:44:19 -07002807 mLocalActivityManager.setDeviceIdleWhitelist(
2808 mPowerSaveWhitelistAllAppIdArray, mPowerSaveWhitelistExceptIdleAppIdArray);
Dianne Hackborn85e35642017-01-12 15:10:57 -08002809 }
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002810 if (mLocalPowerManager != null) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002811 if (DEBUG) {
2812 Slog.d(TAG, "Setting wakelock whitelist to "
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002813 + Arrays.toString(mPowerSaveWhitelistAllAppIdArray));
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002814 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002815 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002816 }
Suprabh Shukla5bf49812018-05-24 18:38:50 -07002817 passWhiteListsToForceAppStandbyTrackerLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002818 }
2819
Dianne Hackborn85e35642017-01-12 15:10:57 -08002820 private void updateTempWhitelistAppIdsLocked(int appId, boolean adding) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002821 final int size = mTempWhitelistAppIdEndTimes.size();
2822 if (mTempWhitelistAppIdArray.length != size) {
2823 mTempWhitelistAppIdArray = new int[size];
2824 }
2825 for (int i = 0; i < size; i++) {
2826 mTempWhitelistAppIdArray[i] = mTempWhitelistAppIdEndTimes.keyAt(i);
2827 }
Dianne Hackborn85e35642017-01-12 15:10:57 -08002828 if (mLocalActivityManager != null) {
2829 if (DEBUG) {
2830 Slog.d(TAG, "Setting activity manager temp whitelist to "
2831 + Arrays.toString(mTempWhitelistAppIdArray));
2832 }
2833 mLocalActivityManager.updateDeviceIdleTempWhitelist(mTempWhitelistAppIdArray, appId,
2834 adding);
2835 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002836 if (mLocalPowerManager != null) {
2837 if (DEBUG) {
2838 Slog.d(TAG, "Setting wakelock temp whitelist to "
2839 + Arrays.toString(mTempWhitelistAppIdArray));
2840 }
2841 mLocalPowerManager.setDeviceIdleTempWhitelist(mTempWhitelistAppIdArray);
2842 }
Suprabh Shukla5bf49812018-05-24 18:38:50 -07002843 passWhiteListsToForceAppStandbyTrackerLocked();
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002844 }
2845
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002846 private void reportPowerSaveWhitelistChangedLocked() {
2847 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
2848 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Xiaohui Chene4de5a02015-09-22 15:33:31 -07002849 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002850 }
2851
2852 private void reportTempWhitelistChangedLocked() {
2853 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED);
2854 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Xiaohui Chene4de5a02015-09-22 15:33:31 -07002855 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002856 }
2857
Suprabh Shukla5bf49812018-05-24 18:38:50 -07002858 private void passWhiteListsToForceAppStandbyTrackerLocked() {
Makoto Onukie4918212018-02-06 11:30:15 -08002859 mAppStateTracker.setPowerSaveWhitelistAppIds(
Makoto Onuki71755c92018-01-16 14:15:44 -08002860 mPowerSaveWhitelistExceptIdleAppIdArray,
Suprabh Shukla5bf49812018-05-24 18:38:50 -07002861 mPowerSaveWhitelistUserAppIdArray,
Makoto Onuki2206af32017-11-21 16:25:35 -08002862 mTempWhitelistAppIdArray);
2863 }
2864
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002865 void readConfigFileLocked() {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002866 if (DEBUG) Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002867 mPowerSaveWhitelistUserApps.clear();
2868 FileInputStream stream;
2869 try {
2870 stream = mConfigFile.openRead();
2871 } catch (FileNotFoundException e) {
2872 return;
2873 }
2874 try {
2875 XmlPullParser parser = Xml.newPullParser();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01002876 parser.setInput(stream, StandardCharsets.UTF_8.name());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002877 readConfigFileLocked(parser);
2878 } catch (XmlPullParserException e) {
2879 } finally {
2880 try {
2881 stream.close();
2882 } catch (IOException e) {
2883 }
2884 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002885 }
2886
2887 private void readConfigFileLocked(XmlPullParser parser) {
2888 final PackageManager pm = getContext().getPackageManager();
2889
2890 try {
2891 int type;
2892 while ((type = parser.next()) != XmlPullParser.START_TAG
2893 && type != XmlPullParser.END_DOCUMENT) {
2894 ;
2895 }
2896
2897 if (type != XmlPullParser.START_TAG) {
2898 throw new IllegalStateException("no start tag found");
2899 }
2900
2901 int outerDepth = parser.getDepth();
2902 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2903 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2904 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2905 continue;
2906 }
2907
2908 String tagName = parser.getName();
Suprabh Shukla08105642017-09-26 14:45:30 -07002909 switch (tagName) {
2910 case "wl":
2911 String name = parser.getAttributeValue(null, "n");
2912 if (name != null) {
2913 try {
2914 ApplicationInfo ai = pm.getApplicationInfo(name,
2915 PackageManager.MATCH_ANY_USER);
2916 mPowerSaveWhitelistUserApps.put(ai.packageName,
2917 UserHandle.getAppId(ai.uid));
2918 } catch (PackageManager.NameNotFoundException e) {
2919 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002920 }
Suprabh Shukla08105642017-09-26 14:45:30 -07002921 break;
2922 case "un-wl":
2923 final String packageName = parser.getAttributeValue(null, "n");
2924 if (mPowerSaveWhitelistApps.containsKey(packageName)) {
2925 mRemovedFromSystemWhitelistApps.put(packageName,
2926 mPowerSaveWhitelistApps.remove(packageName));
2927 }
2928 break;
2929 default:
2930 Slog.w(TAG, "Unknown element under <config>: "
2931 + parser.getName());
2932 XmlUtils.skipCurrentTag(parser);
2933 break;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002934 }
2935 }
2936
2937 } catch (IllegalStateException e) {
2938 Slog.w(TAG, "Failed parsing config " + e);
2939 } catch (NullPointerException e) {
2940 Slog.w(TAG, "Failed parsing config " + e);
2941 } catch (NumberFormatException e) {
2942 Slog.w(TAG, "Failed parsing config " + e);
2943 } catch (XmlPullParserException e) {
2944 Slog.w(TAG, "Failed parsing config " + e);
2945 } catch (IOException e) {
2946 Slog.w(TAG, "Failed parsing config " + e);
2947 } catch (IndexOutOfBoundsException e) {
2948 Slog.w(TAG, "Failed parsing config " + e);
2949 }
2950 }
2951
2952 void writeConfigFileLocked() {
2953 mHandler.removeMessages(MSG_WRITE_CONFIG);
2954 mHandler.sendEmptyMessageDelayed(MSG_WRITE_CONFIG, 5000);
2955 }
2956
2957 void handleWriteConfigFile() {
2958 final ByteArrayOutputStream memStream = new ByteArrayOutputStream();
2959
2960 try {
2961 synchronized (this) {
2962 XmlSerializer out = new FastXmlSerializer();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01002963 out.setOutput(memStream, StandardCharsets.UTF_8.name());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002964 writeConfigFileLocked(out);
2965 }
2966 } catch (IOException e) {
2967 }
2968
2969 synchronized (mConfigFile) {
2970 FileOutputStream stream = null;
2971 try {
2972 stream = mConfigFile.startWrite();
2973 memStream.writeTo(stream);
2974 stream.flush();
2975 FileUtils.sync(stream);
2976 stream.close();
2977 mConfigFile.finishWrite(stream);
2978 } catch (IOException e) {
2979 Slog.w(TAG, "Error writing config file", e);
2980 mConfigFile.failWrite(stream);
2981 }
2982 }
2983 }
2984
2985 void writeConfigFileLocked(XmlSerializer out) throws IOException {
2986 out.startDocument(null, true);
2987 out.startTag(null, "config");
2988 for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) {
2989 String name = mPowerSaveWhitelistUserApps.keyAt(i);
2990 out.startTag(null, "wl");
2991 out.attribute(null, "n", name);
2992 out.endTag(null, "wl");
2993 }
Suprabh Shukla08105642017-09-26 14:45:30 -07002994 for (int i = 0; i < mRemovedFromSystemWhitelistApps.size(); i++) {
2995 out.startTag(null, "un-wl");
2996 out.attribute(null, "n", mRemovedFromSystemWhitelistApps.keyAt(i));
2997 out.endTag(null, "un-wl");
2998 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002999 out.endTag(null, "config");
3000 out.endDocument();
3001 }
3002
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003003 static void dumpHelp(PrintWriter pw) {
3004 pw.println("Device idle controller (deviceidle) commands:");
3005 pw.println(" help");
3006 pw.println(" Print this help text.");
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003007 pw.println(" step [light|deep]");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003008 pw.println(" Immediately step to next state, without waiting for alarm.");
Dianne Hackborn88c41352016-04-07 15:18:58 -07003009 pw.println(" force-idle [light|deep]");
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003010 pw.println(" Force directly into idle mode, regardless of other device state.");
Dianne Hackborn88c41352016-04-07 15:18:58 -07003011 pw.println(" force-inactive");
3012 pw.println(" Force to be inactive, ready to freely step idle states.");
3013 pw.println(" unforce");
3014 pw.println(" Resume normal functioning after force-idle or force-inactive.");
3015 pw.println(" get [light|deep|force|screen|charging|network]");
3016 pw.println(" Retrieve the current given state.");
Dianne Hackbornb6843652016-02-22 12:20:13 -08003017 pw.println(" disable [light|deep|all]");
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003018 pw.println(" Completely disable device idle mode.");
Dianne Hackbornb6843652016-02-22 12:20:13 -08003019 pw.println(" enable [light|deep|all]");
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003020 pw.println(" Re-enable device idle mode after it had previously been disabled.");
Dianne Hackbornb6843652016-02-22 12:20:13 -08003021 pw.println(" enabled [light|deep|all]");
Dianne Hackborn92617032015-06-19 15:32:19 -07003022 pw.println(" Print 1 if device idle mode is currently enabled, else 0.");
Dianne Hackborn1b139682015-07-06 15:13:37 -07003023 pw.println(" whitelist");
3024 pw.println(" Print currently whitelisted apps.");
Dianne Hackborn92617032015-06-19 15:32:19 -07003025 pw.println(" whitelist [package ...]");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003026 pw.println(" Add (prefix with +) or remove (prefix with -) packages.");
Suprabh Shukla08105642017-09-26 14:45:30 -07003027 pw.println(" sys-whitelist [package ...|reset]");
3028 pw.println(" Prefix the package with '-' to remove it from the system whitelist or '+'"
3029 + " to put it back in the system whitelist.");
3030 pw.println(" Note that only packages that were"
3031 + " earlier removed from the system whitelist can be added back.");
3032 pw.println(" reset will reset the whitelist to the original state");
3033 pw.println(" Prints the system whitelist if no arguments are specified");
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07003034 pw.println(" except-idle-whitelist [package ...|reset]");
3035 pw.println(" Prefix the package with '+' to add it to whitelist or "
3036 + "'=' to check if it is already whitelisted");
3037 pw.println(" [reset] will reset the whitelist to it's original state");
3038 pw.println(" Note that unlike <whitelist> cmd, "
3039 + "changes made using this won't be persisted across boots");
Felipe Lemea1b79bf2016-05-24 13:06:54 -07003040 pw.println(" tempwhitelist");
3041 pw.println(" Print packages that are temporarily whitelisted.");
Sudheer Shanka326b3112017-11-27 14:40:57 -08003042 pw.println(" tempwhitelist [-u USER] [-d DURATION] [-r] [package]");
3043 pw.println(" Temporarily place package in whitelist for DURATION milliseconds.");
Dianne Hackborn85e35642017-01-12 15:10:57 -08003044 pw.println(" If no DURATION is specified, 10 seconds is used");
Sudheer Shanka326b3112017-11-27 14:40:57 -08003045 pw.println(" If [-r] option is used, then the package is removed from temp whitelist "
3046 + "and any [-d] is ignored");
Amith Yamasani4cb42572018-04-27 10:02:57 -07003047 pw.println(" motion");
3048 pw.println(" Simulate a motion event to bring the device out of deep doze");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003049 }
3050
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003051 class Shell extends ShellCommand {
3052 int userId = UserHandle.USER_SYSTEM;
3053
3054 @Override
3055 public int onCommand(String cmd) {
3056 return onShellCommand(this, cmd);
3057 }
3058
3059 @Override
3060 public void onHelp() {
3061 PrintWriter pw = getOutPrintWriter();
3062 dumpHelp(pw);
3063 }
3064 }
3065
3066 int onShellCommand(Shell shell, String cmd) {
3067 PrintWriter pw = shell.getOutPrintWriter();
3068 if ("step".equals(cmd)) {
3069 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3070 null);
3071 synchronized (this) {
3072 long token = Binder.clearCallingIdentity();
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003073 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003074 try {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003075 if (arg == null || "deep".equals(arg)) {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003076 stepIdleStateLocked("s:shell");
3077 pw.print("Stepped to deep: ");
3078 pw.println(stateToString(mState));
3079 } else if ("light".equals(arg)) {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07003080 stepLightIdleStateLocked("s:shell");
3081 pw.print("Stepped to light: "); pw.println(lightStateToString(mLightState));
3082 } else {
3083 pw.println("Unknown idle mode: " + arg);
3084 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003085 } finally {
3086 Binder.restoreCallingIdentity(token);
3087 }
3088 }
3089 } else if ("force-idle".equals(cmd)) {
3090 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3091 null);
3092 synchronized (this) {
3093 long token = Binder.clearCallingIdentity();
Dianne Hackborn88c41352016-04-07 15:18:58 -07003094 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003095 try {
Dianne Hackborn88c41352016-04-07 15:18:58 -07003096 if (arg == null || "deep".equals(arg)) {
3097 if (!mDeepEnabled) {
3098 pw.println("Unable to go deep idle; not enabled");
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003099 return -1;
3100 }
Dianne Hackborn88c41352016-04-07 15:18:58 -07003101 mForceIdle = true;
3102 becomeInactiveIfAppropriateLocked();
3103 int curState = mState;
3104 while (curState != STATE_IDLE) {
3105 stepIdleStateLocked("s:shell");
3106 if (curState == mState) {
3107 pw.print("Unable to go deep idle; stopped at ");
3108 pw.println(stateToString(mState));
3109 exitForceIdleLocked();
3110 return -1;
3111 }
3112 curState = mState;
3113 }
3114 pw.println("Now forced in to deep idle mode");
3115 } else if ("light".equals(arg)) {
3116 mForceIdle = true;
3117 becomeInactiveIfAppropriateLocked();
3118 int curLightState = mLightState;
3119 while (curLightState != LIGHT_STATE_IDLE) {
Tej Singh93cf3e32017-12-07 13:05:38 -08003120 stepLightIdleStateLocked("s:shell");
Dianne Hackborn88c41352016-04-07 15:18:58 -07003121 if (curLightState == mLightState) {
3122 pw.print("Unable to go light idle; stopped at ");
3123 pw.println(lightStateToString(mLightState));
3124 exitForceIdleLocked();
3125 return -1;
3126 }
3127 curLightState = mLightState;
3128 }
3129 pw.println("Now forced in to light idle mode");
3130 } else {
3131 pw.println("Unknown idle mode: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003132 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003133 } finally {
3134 Binder.restoreCallingIdentity(token);
3135 }
3136 }
Dianne Hackborn88c41352016-04-07 15:18:58 -07003137 } else if ("force-inactive".equals(cmd)) {
3138 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3139 null);
3140 synchronized (this) {
3141 long token = Binder.clearCallingIdentity();
3142 try {
3143 mForceIdle = true;
3144 becomeInactiveIfAppropriateLocked();
3145 pw.print("Light state: ");
3146 pw.print(lightStateToString(mLightState));
3147 pw.print(", deep state: ");
3148 pw.println(stateToString(mState));
3149 } finally {
3150 Binder.restoreCallingIdentity(token);
3151 }
3152 }
3153 } else if ("unforce".equals(cmd)) {
3154 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3155 null);
3156 synchronized (this) {
3157 long token = Binder.clearCallingIdentity();
3158 try {
3159 exitForceIdleLocked();
3160 pw.print("Light state: ");
3161 pw.print(lightStateToString(mLightState));
3162 pw.print(", deep state: ");
3163 pw.println(stateToString(mState));
3164 } finally {
3165 Binder.restoreCallingIdentity(token);
3166 }
3167 }
3168 } else if ("get".equals(cmd)) {
3169 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3170 null);
3171 synchronized (this) {
3172 String arg = shell.getNextArg();
3173 if (arg != null) {
3174 long token = Binder.clearCallingIdentity();
3175 try {
3176 switch (arg) {
3177 case "light": pw.println(lightStateToString(mLightState)); break;
3178 case "deep": pw.println(stateToString(mState)); break;
3179 case "force": pw.println(mForceIdle); break;
3180 case "screen": pw.println(mScreenOn); break;
3181 case "charging": pw.println(mCharging); break;
3182 case "network": pw.println(mNetworkConnected); break;
3183 default: pw.println("Unknown get option: " + arg); break;
3184 }
3185 } finally {
3186 Binder.restoreCallingIdentity(token);
3187 }
3188 } else {
3189 pw.println("Argument required");
3190 }
3191 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003192 } else if ("disable".equals(cmd)) {
3193 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3194 null);
3195 synchronized (this) {
3196 long token = Binder.clearCallingIdentity();
Dianne Hackbornb6843652016-02-22 12:20:13 -08003197 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003198 try {
Dianne Hackbornb6843652016-02-22 12:20:13 -08003199 boolean becomeActive = false;
3200 boolean valid = false;
3201 if (arg == null || "deep".equals(arg) || "all".equals(arg)) {
3202 valid = true;
3203 if (mDeepEnabled) {
3204 mDeepEnabled = false;
3205 becomeActive = true;
3206 pw.println("Deep idle mode disabled");
3207 }
3208 }
3209 if (arg == null || "light".equals(arg) || "all".equals(arg)) {
3210 valid = true;
3211 if (mLightEnabled) {
3212 mLightEnabled = false;
3213 becomeActive = true;
3214 pw.println("Light idle mode disabled");
3215 }
3216 }
3217 if (becomeActive) {
3218 becomeActiveLocked((arg == null ? "all" : arg) + "-disabled",
3219 Process.myUid());
3220 }
3221 if (!valid) {
3222 pw.println("Unknown idle mode: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003223 }
3224 } finally {
3225 Binder.restoreCallingIdentity(token);
3226 }
3227 }
3228 } else if ("enable".equals(cmd)) {
3229 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3230 null);
3231 synchronized (this) {
3232 long token = Binder.clearCallingIdentity();
Dianne Hackbornb6843652016-02-22 12:20:13 -08003233 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003234 try {
Dianne Hackbornb6843652016-02-22 12:20:13 -08003235 boolean becomeInactive = false;
3236 boolean valid = false;
3237 if (arg == null || "deep".equals(arg) || "all".equals(arg)) {
3238 valid = true;
3239 if (!mDeepEnabled) {
3240 mDeepEnabled = true;
3241 becomeInactive = true;
3242 pw.println("Deep idle mode enabled");
3243 }
3244 }
3245 if (arg == null || "light".equals(arg) || "all".equals(arg)) {
3246 valid = true;
3247 if (!mLightEnabled) {
3248 mLightEnabled = true;
3249 becomeInactive = true;
3250 pw.println("Light idle mode enable");
3251 }
3252 }
3253 if (becomeInactive) {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003254 becomeInactiveIfAppropriateLocked();
Dianne Hackbornb6843652016-02-22 12:20:13 -08003255 }
3256 if (!valid) {
3257 pw.println("Unknown idle mode: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003258 }
3259 } finally {
3260 Binder.restoreCallingIdentity(token);
3261 }
3262 }
3263 } else if ("enabled".equals(cmd)) {
3264 synchronized (this) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08003265 String arg = shell.getNextArg();
3266 if (arg == null || "all".equals(arg)) {
3267 pw.println(mDeepEnabled && mLightEnabled ? "1" : 0);
3268 } else if ("deep".equals(arg)) {
3269 pw.println(mDeepEnabled ? "1" : 0);
3270 } else if ("light".equals(arg)) {
3271 pw.println(mLightEnabled ? "1" : 0);
3272 } else {
3273 pw.println("Unknown idle mode: " + arg);
3274 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003275 }
3276 } else if ("whitelist".equals(cmd)) {
Dianne Hackborneb909e32016-09-29 14:35:15 -07003277 String arg = shell.getNextArg();
3278 if (arg != null) {
3279 getContext().enforceCallingOrSelfPermission(
3280 android.Manifest.permission.DEVICE_POWER, null);
3281 long token = Binder.clearCallingIdentity();
3282 try {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003283 do {
3284 if (arg.length() < 1 || (arg.charAt(0) != '-'
Felipe Lemef8a46232016-02-10 13:51:54 -08003285 && arg.charAt(0) != '+' && arg.charAt(0) != '=')) {
3286 pw.println("Package must be prefixed with +, -, or =: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003287 return -1;
3288 }
3289 char op = arg.charAt(0);
3290 String pkg = arg.substring(1);
3291 if (op == '+') {
3292 if (addPowerSaveWhitelistAppInternal(pkg)) {
3293 pw.println("Added: " + pkg);
3294 } else {
3295 pw.println("Unknown package: " + pkg);
3296 }
Felipe Lemef8a46232016-02-10 13:51:54 -08003297 } else if (op == '-') {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003298 if (removePowerSaveWhitelistAppInternal(pkg)) {
3299 pw.println("Removed: " + pkg);
3300 }
Felipe Lemef8a46232016-02-10 13:51:54 -08003301 } else {
3302 pw.println(getPowerSaveWhitelistAppInternal(pkg));
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003303 }
3304 } while ((arg=shell.getNextArg()) != null);
Dianne Hackborneb909e32016-09-29 14:35:15 -07003305 } finally {
3306 Binder.restoreCallingIdentity(token);
3307 }
3308 } else {
3309 synchronized (this) {
3310 for (int j=0; j<mPowerSaveWhitelistAppsExceptIdle.size(); j++) {
3311 pw.print("system-excidle,");
3312 pw.print(mPowerSaveWhitelistAppsExceptIdle.keyAt(j));
3313 pw.print(",");
3314 pw.println(mPowerSaveWhitelistAppsExceptIdle.valueAt(j));
3315 }
3316 for (int j=0; j<mPowerSaveWhitelistApps.size(); j++) {
3317 pw.print("system,");
3318 pw.print(mPowerSaveWhitelistApps.keyAt(j));
3319 pw.print(",");
3320 pw.println(mPowerSaveWhitelistApps.valueAt(j));
3321 }
3322 for (int j=0; j<mPowerSaveWhitelistUserApps.size(); j++) {
3323 pw.print("user,");
3324 pw.print(mPowerSaveWhitelistUserApps.keyAt(j));
3325 pw.print(",");
3326 pw.println(mPowerSaveWhitelistUserApps.valueAt(j));
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003327 }
3328 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003329 }
3330 } else if ("tempwhitelist".equals(cmd)) {
Dianne Hackborn85e35642017-01-12 15:10:57 -08003331 long duration = 10000;
Sudheer Shanka326b3112017-11-27 14:40:57 -08003332 boolean removePkg = false;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003333 String opt;
3334 while ((opt=shell.getNextOption()) != null) {
3335 if ("-u".equals(opt)) {
3336 opt = shell.getNextArg();
3337 if (opt == null) {
3338 pw.println("-u requires a user number");
3339 return -1;
3340 }
3341 shell.userId = Integer.parseInt(opt);
Dianne Hackborn85e35642017-01-12 15:10:57 -08003342 } else if ("-d".equals(opt)) {
3343 opt = shell.getNextArg();
3344 if (opt == null) {
3345 pw.println("-d requires a duration");
3346 return -1;
3347 }
3348 duration = Long.parseLong(opt);
Sudheer Shanka326b3112017-11-27 14:40:57 -08003349 } else if ("-r".equals(opt)) {
3350 removePkg = true;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003351 }
3352 }
3353 String arg = shell.getNextArg();
3354 if (arg != null) {
3355 try {
Sudheer Shanka326b3112017-11-27 14:40:57 -08003356 if (removePkg) {
3357 removePowerSaveTempWhitelistAppChecked(arg, shell.userId);
3358 } else {
3359 addPowerSaveTempWhitelistAppChecked(arg, duration, shell.userId, "shell");
3360 }
Christopher Tateec3a9f32017-03-21 17:43:47 -07003361 } catch (Exception e) {
3362 pw.println("Failed: " + e);
3363 return -1;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003364 }
Sudheer Shanka326b3112017-11-27 14:40:57 -08003365 } else if (removePkg) {
3366 pw.println("[-r] requires a package name");
3367 return -1;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003368 } else {
Felipe Lemea1b79bf2016-05-24 13:06:54 -07003369 dumpTempWhitelistSchedule(pw, false);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003370 }
Sudheer Shanka3f4d7702017-04-28 17:38:03 -07003371 } else if ("except-idle-whitelist".equals(cmd)) {
3372 getContext().enforceCallingOrSelfPermission(
3373 android.Manifest.permission.DEVICE_POWER, null);
3374 final long token = Binder.clearCallingIdentity();
3375 try {
3376 String arg = shell.getNextArg();
3377 if (arg == null) {
3378 pw.println("No arguments given");
3379 return -1;
3380 } else if ("reset".equals(arg)) {
3381 resetPowerSaveWhitelistExceptIdleInternal();
3382 } else {
3383 do {
3384 if (arg.length() < 1 || (arg.charAt(0) != '-'
3385 && arg.charAt(0) != '+' && arg.charAt(0) != '=')) {
3386 pw.println("Package must be prefixed with +, -, or =: " + arg);
3387 return -1;
3388 }
3389 char op = arg.charAt(0);
3390 String pkg = arg.substring(1);
3391 if (op == '+') {
3392 if (addPowerSaveWhitelistExceptIdleInternal(pkg)) {
3393 pw.println("Added: " + pkg);
3394 } else {
3395 pw.println("Unknown package: " + pkg);
3396 }
3397 } else if (op == '=') {
3398 pw.println(getPowerSaveWhitelistExceptIdleInternal(pkg));
3399 } else {
3400 pw.println("Unknown argument: " + arg);
3401 return -1;
3402 }
3403 } while ((arg = shell.getNextArg()) != null);
3404 }
3405 } finally {
3406 Binder.restoreCallingIdentity(token);
3407 }
Suprabh Shukla08105642017-09-26 14:45:30 -07003408 } else if ("sys-whitelist".equals(cmd)) {
3409 String arg = shell.getNextArg();
3410 if (arg != null) {
3411 getContext().enforceCallingOrSelfPermission(
3412 android.Manifest.permission.DEVICE_POWER, null);
3413 final long token = Binder.clearCallingIdentity();
3414 try {
3415 if ("reset".equals(arg)) {
3416 resetSystemPowerWhitelistInternal();
3417 } else {
3418 do {
3419 if (arg.length() < 1
3420 || (arg.charAt(0) != '-' && arg.charAt(0) != '+')) {
3421 pw.println("Package must be prefixed with + or - " + arg);
3422 return -1;
3423 }
3424 final char op = arg.charAt(0);
3425 final String pkg = arg.substring(1);
3426 switch (op) {
3427 case '+':
3428 if (restoreSystemPowerWhitelistAppInternal(pkg)) {
3429 pw.println("Restored " + pkg);
3430 }
3431 break;
3432 case '-':
3433 if (removeSystemPowerWhitelistAppInternal(pkg)) {
3434 pw.println("Removed " + pkg);
3435 }
3436 break;
3437 }
3438 } while ((arg = shell.getNextArg()) != null);
3439 }
3440 } finally {
3441 Binder.restoreCallingIdentity(token);
3442 }
3443 } else {
3444 synchronized (this) {
Amith Yamasani4cb42572018-04-27 10:02:57 -07003445 for (int j = 0; j < mPowerSaveWhitelistApps.size(); j++) {
Suprabh Shukla08105642017-09-26 14:45:30 -07003446 pw.print(mPowerSaveWhitelistApps.keyAt(j));
3447 pw.print(",");
3448 pw.println(mPowerSaveWhitelistApps.valueAt(j));
3449 }
3450 }
3451 }
Amith Yamasani4cb42572018-04-27 10:02:57 -07003452 } else if ("motion".equals(cmd)) {
3453 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
3454 null);
3455 synchronized (this) {
3456 long token = Binder.clearCallingIdentity();
3457 try {
3458 motionLocked();
3459 pw.print("Light state: ");
3460 pw.print(lightStateToString(mLightState));
3461 pw.print(", deep state: ");
3462 pw.println(stateToString(mState));
3463 } finally {
3464 Binder.restoreCallingIdentity(token);
3465 }
3466 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003467 } else {
3468 return shell.handleDefaultCommands(cmd);
3469 }
3470 return 0;
3471 }
3472
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003473 void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06003474 if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003475
3476 if (args != null) {
Xiaohui Chen7c696362015-09-16 09:56:14 -07003477 int userId = UserHandle.USER_SYSTEM;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003478 for (int i=0; i<args.length; i++) {
3479 String arg = args[i];
3480 if ("-h".equals(arg)) {
3481 dumpHelp(pw);
3482 return;
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003483 } else if ("-u".equals(arg)) {
3484 i++;
3485 if (i < args.length) {
3486 arg = args[i];
3487 userId = Integer.parseInt(arg);
3488 }
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07003489 } else if ("-a".equals(arg)) {
3490 // Ignore, we always dump all.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003491 } else if (arg.length() > 0 && arg.charAt(0) == '-'){
3492 pw.println("Unknown option: " + arg);
3493 return;
3494 } else {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07003495 Shell shell = new Shell();
3496 shell.userId = userId;
3497 String[] newArgs = new String[args.length-i];
3498 System.arraycopy(args, i, newArgs, 0, args.length-i);
Dianne Hackborn354736e2016-08-22 17:00:05 -07003499 shell.exec(mBinderService, null, fd, null, newArgs, null,
3500 new ResultReceiver(null));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003501 return;
3502 }
3503 }
3504 }
3505
3506 synchronized (this) {
Dianne Hackborna750a632015-06-16 17:18:23 -07003507 mConstants.dump(pw);
3508
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08003509 if (mEventCmds[0] != EVENT_NULL) {
3510 pw.println(" Idling history:");
3511 long now = SystemClock.elapsedRealtime();
3512 for (int i=EVENT_BUFFER_SIZE-1; i>=0; i--) {
3513 int cmd = mEventCmds[i];
3514 if (cmd == EVENT_NULL) {
3515 continue;
3516 }
3517 String label;
3518 switch (mEventCmds[i]) {
3519 case EVENT_NORMAL: label = " normal"; break;
3520 case EVENT_LIGHT_IDLE: label = " light-idle"; break;
3521 case EVENT_LIGHT_MAINTENANCE: label = "light-maint"; break;
Dianne Hackbornb6843652016-02-22 12:20:13 -08003522 case EVENT_DEEP_IDLE: label = " deep-idle"; break;
3523 case EVENT_DEEP_MAINTENANCE: label = " deep-maint"; break;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08003524 default: label = " ??"; break;
3525 }
3526 pw.print(" ");
3527 pw.print(label);
3528 pw.print(": ");
Amith Yamasaniac6517a2018-04-23 12:19:34 -07003529 TimeUtils.formatDuration(mEventTimes[i], now, pw);
3530 if (mEventReasons[i] != null) {
3531 pw.print(" (");
3532 pw.print(mEventReasons[i]);
3533 pw.print(")");
3534 }
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08003535 pw.println();
Amith Yamasaniac6517a2018-04-23 12:19:34 -07003536
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08003537 }
3538 }
3539
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003540 int size = mPowerSaveWhitelistAppsExceptIdle.size();
3541 if (size > 0) {
3542 pw.println(" Whitelist (except idle) system apps:");
3543 for (int i = 0; i < size; i++) {
3544 pw.print(" ");
3545 pw.println(mPowerSaveWhitelistAppsExceptIdle.keyAt(i));
3546 }
3547 }
3548 size = mPowerSaveWhitelistApps.size();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003549 if (size > 0) {
3550 pw.println(" Whitelist system apps:");
3551 for (int i = 0; i < size; i++) {
3552 pw.print(" ");
3553 pw.println(mPowerSaveWhitelistApps.keyAt(i));
3554 }
3555 }
Suprabh Shukla08105642017-09-26 14:45:30 -07003556 size = mRemovedFromSystemWhitelistApps.size();
3557 if (size > 0) {
3558 pw.println(" Removed from whitelist system apps:");
3559 for (int i = 0; i < size; i++) {
3560 pw.print(" ");
3561 pw.println(mRemovedFromSystemWhitelistApps.keyAt(i));
3562 }
3563 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003564 size = mPowerSaveWhitelistUserApps.size();
3565 if (size > 0) {
3566 pw.println(" Whitelist user apps:");
3567 for (int i = 0; i < size; i++) {
3568 pw.print(" ");
3569 pw.println(mPowerSaveWhitelistUserApps.keyAt(i));
3570 }
3571 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003572 size = mPowerSaveWhitelistExceptIdleAppIds.size();
3573 if (size > 0) {
3574 pw.println(" Whitelist (except idle) all app ids:");
3575 for (int i = 0; i < size; i++) {
3576 pw.print(" ");
3577 pw.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
3578 pw.println();
3579 }
3580 }
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08003581 size = mPowerSaveWhitelistUserAppIds.size();
3582 if (size > 0) {
3583 pw.println(" Whitelist user app ids:");
3584 for (int i = 0; i < size; i++) {
3585 pw.print(" ");
3586 pw.print(mPowerSaveWhitelistUserAppIds.keyAt(i));
3587 pw.println();
3588 }
3589 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07003590 size = mPowerSaveWhitelistAllAppIds.size();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003591 if (size > 0) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07003592 pw.println(" Whitelist all app ids:");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003593 for (int i = 0; i < size; i++) {
Dianne Hackborna750a632015-06-16 17:18:23 -07003594 pw.print(" ");
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07003595 pw.print(mPowerSaveWhitelistAllAppIds.keyAt(i));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003596 pw.println();
3597 }
3598 }
Felipe Lemea1b79bf2016-05-24 13:06:54 -07003599 dumpTempWhitelistSchedule(pw, true);
3600
Dianne Hackborna750a632015-06-16 17:18:23 -07003601 size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0;
3602 if (size > 0) {
3603 pw.println(" Temp whitelist app ids:");
3604 for (int i = 0; i < size; i++) {
3605 pw.print(" ");
3606 pw.print(mTempWhitelistAppIdArray[i]);
3607 pw.println();
3608 }
3609 }
Adam Lesinski31c05d12015-06-09 17:34:04 -07003610
Dianne Hackbornb6843652016-02-22 12:20:13 -08003611 pw.print(" mLightEnabled="); pw.print(mLightEnabled);
Felipe Lemea1b79bf2016-05-24 13:06:54 -07003612 pw.print(" mDeepEnabled="); pw.println(mDeepEnabled);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003613 pw.print(" mForceIdle="); pw.println(mForceIdle);
Nick Vaccaro20feaea2015-09-17 17:22:44 -07003614 pw.print(" mMotionSensor="); pw.println(mMotionSensor);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003615 pw.print(" mScreenOn="); pw.println(mScreenOn);
Amith Yamasani396a10c2018-01-19 10:58:07 -08003616 pw.print(" mScreenLocked="); pw.println(mScreenLocked);
Dianne Hackborn88c41352016-04-07 15:18:58 -07003617 pw.print(" mNetworkConnected="); pw.println(mNetworkConnected);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003618 pw.print(" mCharging="); pw.println(mCharging);
Nick Vaccaro20feaea2015-09-17 17:22:44 -07003619 pw.print(" mMotionActive="); pw.println(mMotionListener.active);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003620 pw.print(" mNotMoving="); pw.println(mNotMoving);
Joe LaPenna23d681b2015-08-27 15:12:11 -07003621 pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHasGps=");
3622 pw.print(mHasGps); pw.print(" mHasNetwork=");
3623 pw.print(mHasNetworkLocation); pw.print(" mLocated="); pw.println(mLocated);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07003624 if (mLastGenericLocation != null) {
3625 pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation);
3626 }
3627 if (mLastGpsLocation != null) {
3628 pw.print(" mLastGpsLocation="); pw.println(mLastGpsLocation);
3629 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003630 pw.print(" mState="); pw.print(stateToString(mState));
3631 pw.print(" mLightState=");
3632 pw.println(lightStateToString(mLightState));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003633 pw.print(" mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw);
3634 pw.println();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003635 if (mActiveIdleOpCount != 0) {
3636 pw.print(" mActiveIdleOpCount="); pw.println(mActiveIdleOpCount);
3637 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003638 if (mNextAlarmTime != 0) {
3639 pw.print(" mNextAlarmTime=");
3640 TimeUtils.formatDuration(mNextAlarmTime, SystemClock.elapsedRealtime(), pw);
3641 pw.println();
3642 }
3643 if (mNextIdlePendingDelay != 0) {
3644 pw.print(" mNextIdlePendingDelay=");
3645 TimeUtils.formatDuration(mNextIdlePendingDelay, pw);
3646 pw.println();
3647 }
3648 if (mNextIdleDelay != 0) {
3649 pw.print(" mNextIdleDelay=");
3650 TimeUtils.formatDuration(mNextIdleDelay, pw);
3651 pw.println();
3652 }
Dianne Hackborn953fc942016-03-29 15:36:24 -07003653 if (mNextLightIdleDelay != 0) {
3654 pw.print(" mNextIdleDelay=");
3655 TimeUtils.formatDuration(mNextLightIdleDelay, pw);
3656 pw.println();
3657 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07003658 if (mNextLightAlarmTime != 0) {
3659 pw.print(" mNextLightAlarmTime=");
3660 TimeUtils.formatDuration(mNextLightAlarmTime, SystemClock.elapsedRealtime(), pw);
3661 pw.println();
3662 }
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08003663 if (mCurIdleBudget != 0) {
3664 pw.print(" mCurIdleBudget=");
3665 TimeUtils.formatDuration(mCurIdleBudget, pw);
3666 pw.println();
3667 }
3668 if (mMaintenanceStartTime != 0) {
3669 pw.print(" mMaintenanceStartTime=");
3670 TimeUtils.formatDuration(mMaintenanceStartTime, SystemClock.elapsedRealtime(), pw);
3671 pw.println();
3672 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003673 if (mJobsActive) {
3674 pw.print(" mJobsActive="); pw.println(mJobsActive);
3675 }
3676 if (mAlarmsActive) {
3677 pw.print(" mAlarmsActive="); pw.println(mAlarmsActive);
3678 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07003679 }
3680 }
Felipe Lemea1b79bf2016-05-24 13:06:54 -07003681
3682 void dumpTempWhitelistSchedule(PrintWriter pw, boolean printTitle) {
3683 final int size = mTempWhitelistAppIdEndTimes.size();
3684 if (size > 0) {
3685 String prefix = "";
3686 if (printTitle) {
3687 pw.println(" Temp whitelist schedule:");
3688 prefix = " ";
3689 }
3690 final long timeNow = SystemClock.elapsedRealtime();
3691 for (int i = 0; i < size; i++) {
3692 pw.print(prefix);
3693 pw.print("UID=");
3694 pw.print(mTempWhitelistAppIdEndTimes.keyAt(i));
3695 pw.print(": ");
3696 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.valueAt(i);
3697 TimeUtils.formatDuration(entry.first.value, timeNow, pw);
3698 pw.print(" - ");
3699 pw.println(entry.second);
3700 }
3701 }
3702 }
3703 }