blob: 6023d7f0c479808152d8f725a875126358153167 [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;
20import android.app.ActivityManagerNative;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070021import android.app.AlarmManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070022import android.content.BroadcastReceiver;
Adam Lesinski31c05d12015-06-09 17:34:04 -070023import android.content.ContentResolver;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070024import android.content.Context;
25import android.content.Intent;
26import android.content.IntentFilter;
27import android.content.pm.ApplicationInfo;
28import android.content.pm.PackageManager;
Amith Yamasaniaf575b92015-05-29 15:35:26 -070029import android.content.pm.PackageManager.NameNotFoundException;
Adam Lesinski31c05d12015-06-09 17:34:04 -070030import android.database.ContentObserver;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070031import android.hardware.Sensor;
32import android.hardware.SensorManager;
Nick Vaccaro20feaea2015-09-17 17:22:44 -070033import android.hardware.SensorEvent;
34import android.hardware.SensorEventListener;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070035import android.hardware.TriggerEvent;
36import android.hardware.TriggerEventListener;
37import android.hardware.display.DisplayManager;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -070038import android.location.LocationRequest;
39import android.location.Location;
40import android.location.LocationListener;
41import android.location.LocationManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070042import android.net.INetworkPolicyManager;
Adam Lesinski31c05d12015-06-09 17:34:04 -070043import android.net.Uri;
Dianne Hackbornfd854ee2015-07-13 18:00:37 -070044import android.os.BatteryStats;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070045import android.os.Binder;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -070046import android.os.Bundle;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070047import android.os.Environment;
48import android.os.FileUtils;
49import android.os.Handler;
Dianne Hackborn627dfa12015-11-11 18:10:30 -080050import android.os.IBinder;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070051import android.os.IDeviceIdleController;
Yao Chenca5edbb2016-01-13 14:44:36 -080052import android.os.IMaintenanceActivityListener;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070053import android.os.Looper;
54import android.os.Message;
55import android.os.PowerManager;
56import android.os.PowerManagerInternal;
Dianne Hackbornb6683c42015-06-18 17:40:33 -070057import android.os.Process;
Yao Chenca5edbb2016-01-13 14:44:36 -080058import android.os.RemoteCallbackList;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070059import android.os.RemoteException;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070060import android.os.ResultReceiver;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070061import android.os.ServiceManager;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070062import android.os.ShellCommand;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070063import android.os.SystemClock;
64import android.os.UserHandle;
Adam Lesinski31c05d12015-06-09 17:34:04 -070065import android.provider.Settings;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070066import android.util.ArrayMap;
67import android.util.ArraySet;
Adam Lesinski31c05d12015-06-09 17:34:04 -070068import android.util.KeyValueListParser;
Dianne Hackbornfd854ee2015-07-13 18:00:37 -070069import android.util.MutableLong;
70import android.util.Pair;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070071import android.util.Slog;
Dianne Hackbornfd854ee2015-07-13 18:00:37 -070072import android.util.SparseArray;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070073import android.util.SparseBooleanArray;
74import android.util.TimeUtils;
75import android.util.Xml;
76import android.view.Display;
Amith Yamasani520d8f22015-05-08 16:36:21 -070077
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070078import com.android.internal.app.IBatteryStats;
79import com.android.internal.os.AtomicFile;
80import com.android.internal.os.BackgroundThread;
81import com.android.internal.util.FastXmlSerializer;
82import com.android.internal.util.XmlUtils;
83import com.android.server.am.BatteryStatsService;
Amith Yamasani520d8f22015-05-08 16:36:21 -070084
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070085import org.xmlpull.v1.XmlPullParser;
86import org.xmlpull.v1.XmlPullParserException;
87import org.xmlpull.v1.XmlSerializer;
88
89import java.io.ByteArrayOutputStream;
90import java.io.File;
91import java.io.FileDescriptor;
92import java.io.FileInputStream;
93import java.io.FileNotFoundException;
94import java.io.FileOutputStream;
95import java.io.IOException;
96import java.io.PrintWriter;
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +010097import java.nio.charset.StandardCharsets;
Amith Yamasaniaf575b92015-05-29 15:35:26 -070098import java.util.Arrays;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070099
100/**
101 * Keeps track of device idleness and drives low power mode based on that.
102 */
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700103public class DeviceIdleController extends SystemService
104 implements AnyMotionDetector.DeviceIdleCallback {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700105 private static final String TAG = "DeviceIdleController";
106
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700107 private static final boolean DEBUG = false;
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700108
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700109 private static final boolean COMPRESS_TIME = false;
Amith Yamasani520d8f22015-05-08 16:36:21 -0700110
Dianne Hackborn953fc942016-03-29 15:36:24 -0700111 private static final int EVENT_BUFFER_SIZE = 100;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800112
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700113 private AlarmManager mAlarmManager;
114 private IBatteryStats mBatteryStats;
115 private PowerManagerInternal mLocalPowerManager;
Dianne Hackborn262ae5c2016-02-10 16:28:29 -0800116 private AlarmManagerService.LocalService mLocalAlarmManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700117 private INetworkPolicyManager mNetworkPolicyManager;
118 private DisplayManager mDisplayManager;
119 private SensorManager mSensorManager;
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700120 private Sensor mMotionSensor;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700121 private LocationManager mLocationManager;
122 private LocationRequest mLocationRequest;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700123 private Intent mIdleIntent;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700124 private Intent mLightIdleIntent;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700125 private Display mCurDisplay;
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700126 private AnyMotionDetector mAnyMotionDetector;
Dianne Hackbornb6843652016-02-22 12:20:13 -0800127 private boolean mLightEnabled;
128 private boolean mDeepEnabled;
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700129 private boolean mForceIdle;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700130 private boolean mScreenOn;
131 private boolean mCharging;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700132 private boolean mNotMoving;
133 private boolean mLocating;
134 private boolean mLocated;
Joe LaPenna23d681b2015-08-27 15:12:11 -0700135 private boolean mHasGps;
136 private boolean mHasNetworkLocation;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700137 private Location mLastGenericLocation;
138 private Location mLastGpsLocation;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700139
140 /** Device is currently active. */
141 private static final int STATE_ACTIVE = 0;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700142 /** Device is inactive (screen off, no motion) and we are waiting to for idle. */
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700143 private static final int STATE_INACTIVE = 1;
144 /** Device is past the initial inactive period, and waiting for the next idle period. */
145 private static final int STATE_IDLE_PENDING = 2;
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700146 /** Device is currently sensing motion. */
147 private static final int STATE_SENSING = 3;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700148 /** Device is currently finding location (and may still be sensing). */
149 private static final int STATE_LOCATING = 4;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700150 /** Device is in the idle state, trying to stay asleep as much as possible. */
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700151 private static final int STATE_IDLE = 5;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700152 /** Device is in the idle state, but temporarily out of idle to do regular maintenance. */
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700153 private static final int STATE_IDLE_MAINTENANCE = 6;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700154 private static String stateToString(int state) {
155 switch (state) {
156 case STATE_ACTIVE: return "ACTIVE";
157 case STATE_INACTIVE: return "INACTIVE";
158 case STATE_IDLE_PENDING: return "IDLE_PENDING";
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700159 case STATE_SENSING: return "SENSING";
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700160 case STATE_LOCATING: return "LOCATING";
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700161 case STATE_IDLE: return "IDLE";
162 case STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE";
163 default: return Integer.toString(state);
164 }
165 }
166
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700167 /** Device is currently active. */
168 private static final int LIGHT_STATE_ACTIVE = 0;
169 /** Device is inactive (screen off) and we are waiting to for the first light idle. */
170 private static final int LIGHT_STATE_INACTIVE = 1;
171 /** Device is in the light idle state, trying to stay asleep as much as possible. */
172 private static final int LIGHT_STATE_IDLE = 2;
173 /** Device is in the light idle state, but temporarily out of idle to do regular maintenance. */
174 private static final int LIGHT_STATE_IDLE_MAINTENANCE = 3;
Dianne Hackbornb6843652016-02-22 12:20:13 -0800175 /** Device light idle state is overriden, now applying deep doze state. */
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700176 private static final int LIGHT_STATE_OVERRIDE = 4;
177 private static String lightStateToString(int state) {
178 switch (state) {
179 case LIGHT_STATE_ACTIVE: return "ACTIVE";
180 case LIGHT_STATE_INACTIVE: return "INACTIVE";
181 case LIGHT_STATE_IDLE: return "IDLE";
182 case LIGHT_STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE";
183 case LIGHT_STATE_OVERRIDE: return "OVERRIDE";
184 default: return Integer.toString(state);
185 }
186 }
187
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700188 private int mState;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700189 private int mLightState;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700190
191 private long mInactiveTimeout;
192 private long mNextAlarmTime;
193 private long mNextIdlePendingDelay;
194 private long mNextIdleDelay;
Dianne Hackborn953fc942016-03-29 15:36:24 -0700195 private long mNextLightIdleDelay;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700196 private long mNextLightAlarmTime;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800197 private long mCurIdleBudget;
198 private long mMaintenanceStartTime;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700199
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800200 private int mActiveIdleOpCount;
201 private IBinder mDownloadServiceActive;
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800202 private boolean mJobsActive;
203 private boolean mAlarmsActive;
Yao Chenca5edbb2016-01-13 14:44:36 -0800204 private boolean mReportedMaintenanceActivity;
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800205
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700206 public final AtomicFile mConfigFile;
207
Yao Chenca5edbb2016-01-13 14:44:36 -0800208 private final RemoteCallbackList<IMaintenanceActivityListener> mMaintenanceActivityListeners =
209 new RemoteCallbackList<IMaintenanceActivityListener>();
210
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700211 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700212 * Package names the system has white-listed to opt out of power save restrictions,
213 * except for device idle mode.
214 */
215 private final ArrayMap<String, Integer> mPowerSaveWhitelistAppsExceptIdle = new ArrayMap<>();
216
217 /**
218 * Package names the system has white-listed to opt out of power save restrictions for
219 * all modes.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700220 */
221 private final ArrayMap<String, Integer> mPowerSaveWhitelistApps = new ArrayMap<>();
222
223 /**
224 * Package names the user has white-listed to opt out of power save restrictions.
225 */
226 private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>();
227
228 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700229 * App IDs of built-in system apps that have been white-listed except for idle modes.
230 */
231 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIdsExceptIdle
232 = new SparseBooleanArray();
233
234 /**
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700235 * App IDs of built-in system apps that have been white-listed.
236 */
237 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray();
238
239 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700240 * App IDs that have been white-listed to opt out of power save restrictions, except
241 * for device idle modes.
242 */
243 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
244
245 /**
246 * Current app IDs that are in the complete power save white list, but shouldn't be
247 * excluded from idle modes. This array can be shared with others because it will not be
248 * modified once set.
249 */
250 private int[] mPowerSaveWhitelistExceptIdleAppIdArray = new int[0];
251
252 /**
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700253 * App IDs that have been white-listed to opt out of power save restrictions.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700254 */
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700255 private final SparseBooleanArray mPowerSaveWhitelistAllAppIds = new SparseBooleanArray();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700256
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700257 /**
258 * Current app IDs that are in the complete power save white list. This array can
259 * be shared with others because it will not be modified once set.
260 */
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700261 private int[] mPowerSaveWhitelistAllAppIdArray = new int[0];
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700262
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700263 /**
Dianne Hackborn262ae5c2016-02-10 16:28:29 -0800264 * App IDs that have been white-listed by the user to opt out of power save restrictions.
265 */
266 private final SparseBooleanArray mPowerSaveWhitelistUserAppIds = new SparseBooleanArray();
267
268 /**
269 * Current app IDs that are in the user power save white list. This array can
270 * be shared with others because it will not be modified once set.
271 */
272 private int[] mPowerSaveWhitelistUserAppIdArray = new int[0];
273
274 /**
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700275 * List of end times for UIDs that are temporarily marked as being allowed to access
276 * the network and acquire wakelocks. Times are in milliseconds.
277 */
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700278 private final SparseArray<Pair<MutableLong, String>> mTempWhitelistAppIdEndTimes
279 = new SparseArray<>();
280
281 /**
282 * Callback to the NetworkPolicyManagerService to tell it that the temp whitelist has changed.
283 */
284 Runnable mNetworkPolicyTempWhitelistCallback;
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700285
286 /**
287 * Current app IDs of temporarily whitelist apps for high-priority messages.
288 */
289 private int[] mTempWhitelistAppIdArray = new int[0];
290
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800291 private static final int EVENT_NULL = 0;
292 private static final int EVENT_NORMAL = 1;
293 private static final int EVENT_LIGHT_IDLE = 2;
294 private static final int EVENT_LIGHT_MAINTENANCE = 3;
Dianne Hackbornb6843652016-02-22 12:20:13 -0800295 private static final int EVENT_DEEP_IDLE = 4;
296 private static final int EVENT_DEEP_MAINTENANCE = 5;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800297
298 private int[] mEventCmds = new int[EVENT_BUFFER_SIZE];
299 private long[] mEventTimes = new long[EVENT_BUFFER_SIZE];
300
301 private void addEvent(int cmd) {
302 if (mEventCmds[0] != cmd) {
303 System.arraycopy(mEventCmds, 0, mEventCmds, 1, EVENT_BUFFER_SIZE - 1);
304 System.arraycopy(mEventTimes, 0, mEventTimes, 1, EVENT_BUFFER_SIZE - 1);
305 mEventCmds[0] = cmd;
306 mEventTimes[0] = SystemClock.elapsedRealtime();
307 }
308 }
309
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700310 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
311 @Override public void onReceive(Context context, Intent intent) {
312 if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
313 int plugged = intent.getIntExtra("plugged", 0);
314 updateChargingLocked(plugged != 0);
Dianne Hackborn1b79ad72015-10-12 10:59:47 -0700315 } else if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
316 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
317 Uri data = intent.getData();
318 String ssp;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700319 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
Dianne Hackborn1b79ad72015-10-12 10:59:47 -0700320 removePowerSaveWhitelistAppInternal(ssp);
321 }
322 }
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700323 }
324 }
325 };
326
327 private final AlarmManager.OnAlarmListener mLightAlarmListener
328 = new AlarmManager.OnAlarmListener() {
329 @Override
330 public void onAlarm() {
331 synchronized (DeviceIdleController.this) {
332 stepLightIdleStateLocked("s:alarm");
333 }
334 }
335 };
336
337 private final AlarmManager.OnAlarmListener mDeepAlarmListener
338 = new AlarmManager.OnAlarmListener() {
339 @Override
340 public void onAlarm() {
341 synchronized (DeviceIdleController.this) {
342 stepIdleStateLocked("s:alarm");
343 }
344 }
345 };
346
347 private final AlarmManager.OnAlarmListener mMaintenanceMinCheckListener
348 = new AlarmManager.OnAlarmListener() {
349 @Override
350 public void onAlarm() {
351 synchronized (DeviceIdleController.this) {
352 exitMaintenanceEarlyIfNeededLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700353 }
354 }
355 };
356
Dianne Hackborn953fc942016-03-29 15:36:24 -0700357 private boolean mMaintenanceMinCheckScheduled;
358
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800359 private final BroadcastReceiver mIdleStartedDoneReceiver = new BroadcastReceiver() {
360 @Override public void onReceive(Context context, Intent intent) {
361 decActiveIdleOps();
362 }
363 };
364
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700365 private final DisplayManager.DisplayListener mDisplayListener
366 = new DisplayManager.DisplayListener() {
367 @Override public void onDisplayAdded(int displayId) {
368 }
369
370 @Override public void onDisplayRemoved(int displayId) {
371 }
372
373 @Override public void onDisplayChanged(int displayId) {
374 if (displayId == Display.DEFAULT_DISPLAY) {
375 synchronized (DeviceIdleController.this) {
376 updateDisplayLocked();
377 }
378 }
379 }
380 };
381
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700382 private final class MotionListener extends TriggerEventListener
383 implements SensorEventListener {
384
385 boolean active = false;
386
387 @Override
388 public void onTrigger(TriggerEvent event) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700389 synchronized (DeviceIdleController.this) {
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700390 active = false;
391 motionLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700392 }
393 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700394
395 @Override
396 public void onSensorChanged(SensorEvent event) {
397 synchronized (DeviceIdleController.this) {
398 mSensorManager.unregisterListener(this, mMotionSensor);
399 active = false;
400 motionLocked();
401 }
402 }
403
404 @Override
405 public void onAccuracyChanged(Sensor sensor, int accuracy) {}
406
407 public boolean registerLocked() {
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700408 boolean success;
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700409 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
410 success = mSensorManager.requestTriggerSensor(mMotionListener, mMotionSensor);
411 } else {
412 success = mSensorManager.registerListener(
413 mMotionListener, mMotionSensor, SensorManager.SENSOR_DELAY_NORMAL);
414 }
415 if (success) {
416 active = true;
417 } else {
418 Slog.e(TAG, "Unable to register for " + mMotionSensor);
419 }
420 return success;
421 }
422
423 public void unregisterLocked() {
424 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
425 mSensorManager.cancelTriggerSensor(mMotionListener, mMotionSensor);
426 } else {
427 mSensorManager.unregisterListener(mMotionListener);
428 }
429 active = false;
430 }
431 }
432 private final MotionListener mMotionListener = new MotionListener();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700433
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700434 private final LocationListener mGenericLocationListener = new LocationListener() {
435 @Override
436 public void onLocationChanged(Location location) {
437 synchronized (DeviceIdleController.this) {
438 receivedGenericLocationLocked(location);
439 }
440 }
441
442 @Override
443 public void onStatusChanged(String provider, int status, Bundle extras) {
444 }
445
446 @Override
447 public void onProviderEnabled(String provider) {
448 }
449
450 @Override
451 public void onProviderDisabled(String provider) {
452 }
453 };
454
455 private final LocationListener mGpsLocationListener = new LocationListener() {
456 @Override
457 public void onLocationChanged(Location location) {
458 synchronized (DeviceIdleController.this) {
459 receivedGpsLocationLocked(location);
460 }
461 }
462
463 @Override
464 public void onStatusChanged(String provider, int status, Bundle extras) {
465 }
466
467 @Override
468 public void onProviderEnabled(String provider) {
469 }
470
471 @Override
472 public void onProviderDisabled(String provider) {
473 }
474 };
475
Adam Lesinski31c05d12015-06-09 17:34:04 -0700476 /**
477 * All times are in milliseconds. These constants are kept synchronized with the system
478 * global Settings. Any access to this class or its fields should be done while
479 * holding the DeviceIdleController lock.
480 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700481 private final class Constants extends ContentObserver {
Adam Lesinski31c05d12015-06-09 17:34:04 -0700482 // Key names stored in the settings value.
Dianne Hackborn953fc942016-03-29 15:36:24 -0700483 private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT
484 = "light_after_inactive_to";
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700485 private static final String KEY_LIGHT_IDLE_TIMEOUT = "light_idle_to";
Dianne Hackborn953fc942016-03-29 15:36:24 -0700486 private static final String KEY_LIGHT_IDLE_FACTOR = "light_idle_factor";
487 private static final String KEY_LIGHT_MAX_IDLE_TIMEOUT = "light_max_idle_to";
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800488 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET
489 = "light_idle_maintenance_min_budget";
490 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET
491 = "light_idle_maintenance_max_budget";
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700492 private static final String KEY_MIN_LIGHT_MAINTENANCE_TIME = "min_light_maintenance_time";
493 private static final String KEY_MIN_DEEP_MAINTENANCE_TIME = "min_deep_maintenance_time";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700494 private static final String KEY_INACTIVE_TIMEOUT = "inactive_to";
495 private static final String KEY_SENSING_TIMEOUT = "sensing_to";
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700496 private static final String KEY_LOCATING_TIMEOUT = "locating_to";
497 private static final String KEY_LOCATION_ACCURACY = "location_accuracy";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700498 private static final String KEY_MOTION_INACTIVE_TIMEOUT = "motion_inactive_to";
499 private static final String KEY_IDLE_AFTER_INACTIVE_TIMEOUT = "idle_after_inactive_to";
500 private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to";
501 private static final String KEY_MAX_IDLE_PENDING_TIMEOUT = "max_idle_pending_to";
502 private static final String KEY_IDLE_PENDING_FACTOR = "idle_pending_factor";
503 private static final String KEY_IDLE_TIMEOUT = "idle_to";
504 private static final String KEY_MAX_IDLE_TIMEOUT = "max_idle_to";
505 private static final String KEY_IDLE_FACTOR = "idle_factor";
506 private static final String KEY_MIN_TIME_TO_ALARM = "min_time_to_alarm";
507 private static final String KEY_MAX_TEMP_APP_WHITELIST_DURATION =
508 "max_temp_app_whitelist_duration";
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700509 private static final String KEY_MMS_TEMP_APP_WHITELIST_DURATION =
510 "mms_temp_app_whitelist_duration";
Dianne Hackborn451c3462015-07-21 17:39:46 -0700511 private static final String KEY_SMS_TEMP_APP_WHITELIST_DURATION =
512 "sms_temp_app_whitelist_duration";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700513
514 /**
Dianne Hackborn953fc942016-03-29 15:36:24 -0700515 * This is the time, after becoming inactive, that we go in to the first
516 * light-weight idle mode.
517 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
518 * @see #KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT
519 */
520 public long LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT;
521
522 /**
523 * This is the initial time that we will run in idle maintenance mode.
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700524 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
525 * @see #KEY_LIGHT_IDLE_TIMEOUT
526 */
527 public long LIGHT_IDLE_TIMEOUT;
528
529 /**
Dianne Hackborn953fc942016-03-29 15:36:24 -0700530 * Scaling factor to apply to the light idle mode time each time we complete a cycle.
531 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
532 * @see #KEY_LIGHT_IDLE_FACTOR
533 */
534 public float LIGHT_IDLE_FACTOR;
535
536 /**
537 * This is the maximum time we will run in idle maintenence mode.
538 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
539 * @see #KEY_LIGHT_MAX_IDLE_TIMEOUT
540 */
541 public long LIGHT_MAX_IDLE_TIMEOUT;
542
543 /**
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800544 * This is the minimum amount of time we want to make available for maintenance mode
545 * when lightly idling. That is, we will always have at least this amount of time
546 * available maintenance before timing out and cutting off maintenance mode.
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700547 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800548 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700549 */
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800550 public long LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
551
552 /**
553 * This is the maximum amount of time we want to make available for maintenance mode
554 * when lightly idling. That is, if the system isn't using up its minimum maintenance
555 * budget and this time is being added to the budget reserve, this is the maximum
556 * reserve size we will allow to grow and thus the maximum amount of time we will
557 * allow for the maintenance window.
558 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
559 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET
560 */
561 public long LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700562
563 /**
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700564 * This is the minimum amount of time that we will stay in maintenance mode after
565 * a light doze. We have this minimum to allow various things to respond to switching
566 * in to maintenance mode and scheduling their work -- otherwise we may
567 * see there is nothing to do (no jobs or downloads pending) and go out of maintenance
568 * mode immediately.
569 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
570 * @see #KEY_MIN_LIGHT_MAINTENANCE_TIME
571 */
572 public long MIN_LIGHT_MAINTENANCE_TIME;
573
574 /**
575 * This is the minimum amount of time that we will stay in maintenance mode after
576 * a full doze. We have this minimum to allow various things to respond to switching
577 * in to maintenance mode and scheduling their work -- otherwise we may
578 * see there is nothing to do (no jobs or downloads pending) and go out of maintenance
579 * mode immediately.
580 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
581 * @see #KEY_MIN_DEEP_MAINTENANCE_TIME
582 */
583 public long MIN_DEEP_MAINTENANCE_TIME;
584
585 /**
Adam Lesinski31c05d12015-06-09 17:34:04 -0700586 * This is the time, after becoming inactive, at which we start looking at the
587 * motion sensor to determine if the device is being left alone. We don't do this
588 * immediately after going inactive just because we don't want to be continually running
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700589 * the motion sensor whenever the screen is off.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700590 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
591 * @see #KEY_INACTIVE_TIMEOUT
592 */
593 public long INACTIVE_TIMEOUT;
594
595 /**
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700596 * If we don't receive a callback from AnyMotion in this amount of time +
597 * {@link #LOCATING_TIMEOUT}, we will change from
Adam Lesinski31c05d12015-06-09 17:34:04 -0700598 * STATE_SENSING to STATE_INACTIVE, and any AnyMotion callbacks while not in STATE_SENSING
599 * will be ignored.
600 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
601 * @see #KEY_SENSING_TIMEOUT
602 */
603 public long SENSING_TIMEOUT;
604
605 /**
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700606 * This is how long we will wait to try to get a good location fix before going in to
607 * idle mode.
608 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
609 * @see #KEY_LOCATING_TIMEOUT
610 */
611 public long LOCATING_TIMEOUT;
612
613 /**
614 * The desired maximum accuracy (in meters) we consider the location to be good enough to go
615 * on to idle. We will be trying to get an accuracy fix at least this good or until
616 * {@link #LOCATING_TIMEOUT} expires.
617 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
618 * @see #KEY_LOCATION_ACCURACY
619 */
620 public float LOCATION_ACCURACY;
621
622 /**
Adam Lesinski31c05d12015-06-09 17:34:04 -0700623 * This is the time, after seeing motion, that we wait after becoming inactive from
624 * that until we start looking for motion again.
625 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
626 * @see #KEY_MOTION_INACTIVE_TIMEOUT
627 */
628 public long MOTION_INACTIVE_TIMEOUT;
629
630 /**
631 * This is the time, after the inactive timeout elapses, that we will wait looking
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700632 * for motion until we truly consider the device to be idle.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700633 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
634 * @see #KEY_IDLE_AFTER_INACTIVE_TIMEOUT
635 */
636 public long IDLE_AFTER_INACTIVE_TIMEOUT;
637
638 /**
639 * This is the initial time, after being idle, that we will allow ourself to be back
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700640 * in the IDLE_MAINTENANCE state allowing the system to run normally until we return to
641 * idle.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700642 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
643 * @see #KEY_IDLE_PENDING_TIMEOUT
644 */
645 public long IDLE_PENDING_TIMEOUT;
646
647 /**
648 * Maximum pending idle timeout (time spent running) we will be allowed to use.
649 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
650 * @see #KEY_MAX_IDLE_PENDING_TIMEOUT
651 */
652 public long MAX_IDLE_PENDING_TIMEOUT;
653
654 /**
655 * Scaling factor to apply to current pending idle timeout each time we cycle through
656 * that state.
657 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
658 * @see #KEY_IDLE_PENDING_FACTOR
659 */
660 public float IDLE_PENDING_FACTOR;
661
662 /**
663 * This is the initial time that we want to sit in the idle state before waking up
664 * again to return to pending idle and allowing normal work to run.
665 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
666 * @see #KEY_IDLE_TIMEOUT
667 */
668 public long IDLE_TIMEOUT;
669
670 /**
671 * Maximum idle duration we will be allowed to use.
672 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
673 * @see #KEY_MAX_IDLE_TIMEOUT
674 */
675 public long MAX_IDLE_TIMEOUT;
676
677 /**
678 * Scaling factor to apply to current idle timeout each time we cycle through that state.
679 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
680 * @see #KEY_IDLE_FACTOR
681 */
682 public float IDLE_FACTOR;
683
684 /**
685 * This is the minimum time we will allow until the next upcoming alarm for us to
686 * actually go in to idle mode.
687 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
688 * @see #KEY_MIN_TIME_TO_ALARM
689 */
690 public long MIN_TIME_TO_ALARM;
691
692 /**
693 * Max amount of time to temporarily whitelist an app when it receives a high priority
694 * tickle.
695 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
696 * @see #KEY_MAX_TEMP_APP_WHITELIST_DURATION
697 */
698 public long MAX_TEMP_APP_WHITELIST_DURATION;
699
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700700 /**
701 * Amount of time we would like to whitelist an app that is receiving an MMS.
702 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
703 * @see #KEY_MMS_TEMP_APP_WHITELIST_DURATION
704 */
705 public long MMS_TEMP_APP_WHITELIST_DURATION;
706
Dianne Hackborn451c3462015-07-21 17:39:46 -0700707 /**
708 * Amount of time we would like to whitelist an app that is receiving an SMS.
709 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
710 * @see #KEY_SMS_TEMP_APP_WHITELIST_DURATION
711 */
712 public long SMS_TEMP_APP_WHITELIST_DURATION;
713
Adam Lesinski31c05d12015-06-09 17:34:04 -0700714 private final ContentResolver mResolver;
Joe LaPennaf33b5bf2016-03-23 15:19:47 -0700715 private final boolean mHasWatch;
Adam Lesinski31c05d12015-06-09 17:34:04 -0700716 private final KeyValueListParser mParser = new KeyValueListParser(',');
717
718 public Constants(Handler handler, ContentResolver resolver) {
719 super(handler);
720 mResolver = resolver;
Joe LaPennaf33b5bf2016-03-23 15:19:47 -0700721 mHasWatch = getContext().getPackageManager().hasSystemFeature(
722 PackageManager.FEATURE_WATCH);
723 mResolver.registerContentObserver(Settings.Global.getUriFor(
724 mHasWatch ? Settings.Global.DEVICE_IDLE_CONSTANTS_WATCH
725 : Settings.Global.DEVICE_IDLE_CONSTANTS),
726 false, this);
Adam Lesinski31c05d12015-06-09 17:34:04 -0700727 updateConstants();
728 }
729
730 @Override
731 public void onChange(boolean selfChange, Uri uri) {
732 updateConstants();
733 }
734
735 private void updateConstants() {
736 synchronized (DeviceIdleController.this) {
737 try {
738 mParser.setString(Settings.Global.getString(mResolver,
Joe LaPennaf33b5bf2016-03-23 15:19:47 -0700739 mHasWatch ? Settings.Global.DEVICE_IDLE_CONSTANTS_WATCH
740 : Settings.Global.DEVICE_IDLE_CONSTANTS));
Adam Lesinski31c05d12015-06-09 17:34:04 -0700741 } catch (IllegalArgumentException e) {
742 // Failed to parse the settings string, log this and move on
743 // with defaults.
744 Slog.e(TAG, "Bad device idle settings", e);
745 }
746
Dianne Hackborn953fc942016-03-29 15:36:24 -0700747 LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getLong(
748 KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
749 !COMPRESS_TIME ? 5 * 60 * 1000L : 15 * 1000L);
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700750 LIGHT_IDLE_TIMEOUT = mParser.getLong(KEY_LIGHT_IDLE_TIMEOUT,
Dianne Hackborn953fc942016-03-29 15:36:24 -0700751 !COMPRESS_TIME ? 5 * 60 * 1000L : 15 * 1000L);
752 LIGHT_IDLE_FACTOR = mParser.getFloat(KEY_LIGHT_IDLE_FACTOR,
753 2f);
754 LIGHT_MAX_IDLE_TIMEOUT = mParser.getLong(KEY_LIGHT_MAX_IDLE_TIMEOUT,
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700755 !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800756 LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = mParser.getLong(
757 KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET,
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700758 !COMPRESS_TIME ? 1 * 60 * 1000L : 15 * 1000L);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800759 LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = mParser.getLong(
760 KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET,
761 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L);
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700762 MIN_LIGHT_MAINTENANCE_TIME = mParser.getLong(
763 KEY_MIN_LIGHT_MAINTENANCE_TIME,
764 !COMPRESS_TIME ? 5 * 1000L : 1 * 1000L);
765 MIN_DEEP_MAINTENANCE_TIME = mParser.getLong(
766 KEY_MIN_DEEP_MAINTENANCE_TIME,
767 !COMPRESS_TIME ? 30 * 1000L : 5 * 1000L);
Joe LaPenna0c5d3e92016-03-24 13:29:56 -0700768 long inactiveTimeoutDefault = (mHasWatch ? 15 : 30) * 60 * 1000L;
Adam Lesinski31c05d12015-06-09 17:34:04 -0700769 INACTIVE_TIMEOUT = mParser.getLong(KEY_INACTIVE_TIMEOUT,
Joe LaPenna0c5d3e92016-03-24 13:29:56 -0700770 !COMPRESS_TIME ? inactiveTimeoutDefault : (inactiveTimeoutDefault / 10));
Adam Lesinski31c05d12015-06-09 17:34:04 -0700771 SENSING_TIMEOUT = mParser.getLong(KEY_SENSING_TIMEOUT,
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700772 !DEBUG ? 4 * 60 * 1000L : 60 * 1000L);
773 LOCATING_TIMEOUT = mParser.getLong(KEY_LOCATING_TIMEOUT,
774 !DEBUG ? 30 * 1000L : 15 * 1000L);
775 LOCATION_ACCURACY = mParser.getFloat(KEY_LOCATION_ACCURACY, 20);
Adam Lesinski31c05d12015-06-09 17:34:04 -0700776 MOTION_INACTIVE_TIMEOUT = mParser.getLong(KEY_MOTION_INACTIVE_TIMEOUT,
777 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
Joe LaPenna0c5d3e92016-03-24 13:29:56 -0700778 long idleAfterInactiveTimeout = (mHasWatch ? 15 : 30) * 60 * 1000L;
Adam Lesinski31c05d12015-06-09 17:34:04 -0700779 IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getLong(KEY_IDLE_AFTER_INACTIVE_TIMEOUT,
Joe LaPenna0c5d3e92016-03-24 13:29:56 -0700780 !COMPRESS_TIME ? idleAfterInactiveTimeout
781 : (idleAfterInactiveTimeout / 10));
Adam Lesinski31c05d12015-06-09 17:34:04 -0700782 IDLE_PENDING_TIMEOUT = mParser.getLong(KEY_IDLE_PENDING_TIMEOUT,
783 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L);
784 MAX_IDLE_PENDING_TIMEOUT = mParser.getLong(KEY_MAX_IDLE_PENDING_TIMEOUT,
785 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
786 IDLE_PENDING_FACTOR = mParser.getFloat(KEY_IDLE_PENDING_FACTOR,
787 2f);
788 IDLE_TIMEOUT = mParser.getLong(KEY_IDLE_TIMEOUT,
789 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
790 MAX_IDLE_TIMEOUT = mParser.getLong(KEY_MAX_IDLE_TIMEOUT,
791 !COMPRESS_TIME ? 6 * 60 * 60 * 1000L : 30 * 60 * 1000L);
792 IDLE_FACTOR = mParser.getFloat(KEY_IDLE_FACTOR,
793 2f);
794 MIN_TIME_TO_ALARM = mParser.getLong(KEY_MIN_TIME_TO_ALARM,
795 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700796 MAX_TEMP_APP_WHITELIST_DURATION = mParser.getLong(
797 KEY_MAX_TEMP_APP_WHITELIST_DURATION, 5 * 60 * 1000L);
798 MMS_TEMP_APP_WHITELIST_DURATION = mParser.getLong(
Dianne Hackborn0b6134b2015-07-14 18:48:07 -0700799 KEY_MMS_TEMP_APP_WHITELIST_DURATION, 60 * 1000L);
Dianne Hackborn451c3462015-07-21 17:39:46 -0700800 SMS_TEMP_APP_WHITELIST_DURATION = mParser.getLong(
801 KEY_SMS_TEMP_APP_WHITELIST_DURATION, 20 * 1000L);
Adam Lesinski31c05d12015-06-09 17:34:04 -0700802 }
803 }
804
805 void dump(PrintWriter pw) {
806 pw.println(" Settings:");
807
Dianne Hackborn953fc942016-03-29 15:36:24 -0700808 pw.print(" "); pw.print(KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("=");
809 TimeUtils.formatDuration(LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT, pw);
810 pw.println();
811
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700812 pw.print(" "); pw.print(KEY_LIGHT_IDLE_TIMEOUT); pw.print("=");
813 TimeUtils.formatDuration(LIGHT_IDLE_TIMEOUT, pw);
814 pw.println();
815
Dianne Hackborn953fc942016-03-29 15:36:24 -0700816 pw.print(" "); pw.print(KEY_LIGHT_IDLE_FACTOR); pw.print("=");
817 pw.print(LIGHT_IDLE_FACTOR);
818 pw.println();
819
820 pw.print(" "); pw.print(KEY_LIGHT_MAX_IDLE_TIMEOUT); pw.print("=");
821 TimeUtils.formatDuration(LIGHT_MAX_IDLE_TIMEOUT, pw);
822 pw.println();
823
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800824 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET); pw.print("=");
825 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MIN_BUDGET, pw);
826 pw.println();
827
828 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET); pw.print("=");
829 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MAX_BUDGET, pw);
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700830 pw.println();
831
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700832 pw.print(" "); pw.print(KEY_MIN_LIGHT_MAINTENANCE_TIME); pw.print("=");
833 TimeUtils.formatDuration(MIN_LIGHT_MAINTENANCE_TIME, pw);
834 pw.println();
835
836 pw.print(" "); pw.print(KEY_MIN_DEEP_MAINTENANCE_TIME); pw.print("=");
837 TimeUtils.formatDuration(MIN_DEEP_MAINTENANCE_TIME, pw);
838 pw.println();
839
Dianne Hackborna750a632015-06-16 17:18:23 -0700840 pw.print(" "); pw.print(KEY_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700841 TimeUtils.formatDuration(INACTIVE_TIMEOUT, pw);
842 pw.println();
843
Dianne Hackborna750a632015-06-16 17:18:23 -0700844 pw.print(" "); pw.print(KEY_SENSING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700845 TimeUtils.formatDuration(SENSING_TIMEOUT, pw);
846 pw.println();
847
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700848 pw.print(" "); pw.print(KEY_LOCATING_TIMEOUT); pw.print("=");
849 TimeUtils.formatDuration(LOCATING_TIMEOUT, pw);
850 pw.println();
851
852 pw.print(" "); pw.print(KEY_LOCATION_ACCURACY); pw.print("=");
853 pw.print(LOCATION_ACCURACY); pw.print("m");
854 pw.println();
855
Dianne Hackborna750a632015-06-16 17:18:23 -0700856 pw.print(" "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700857 TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT, pw);
858 pw.println();
859
Dianne Hackborna750a632015-06-16 17:18:23 -0700860 pw.print(" "); pw.print(KEY_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700861 TimeUtils.formatDuration(IDLE_AFTER_INACTIVE_TIMEOUT, pw);
862 pw.println();
863
Dianne Hackborna750a632015-06-16 17:18:23 -0700864 pw.print(" "); pw.print(KEY_IDLE_PENDING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700865 TimeUtils.formatDuration(IDLE_PENDING_TIMEOUT, pw);
866 pw.println();
867
Dianne Hackborna750a632015-06-16 17:18:23 -0700868 pw.print(" "); pw.print(KEY_MAX_IDLE_PENDING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700869 TimeUtils.formatDuration(MAX_IDLE_PENDING_TIMEOUT, pw);
870 pw.println();
871
Dianne Hackborna750a632015-06-16 17:18:23 -0700872 pw.print(" "); pw.print(KEY_IDLE_PENDING_FACTOR); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700873 pw.println(IDLE_PENDING_FACTOR);
874
Dianne Hackborna750a632015-06-16 17:18:23 -0700875 pw.print(" "); pw.print(KEY_IDLE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700876 TimeUtils.formatDuration(IDLE_TIMEOUT, pw);
877 pw.println();
878
Dianne Hackborna750a632015-06-16 17:18:23 -0700879 pw.print(" "); pw.print(KEY_MAX_IDLE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700880 TimeUtils.formatDuration(MAX_IDLE_TIMEOUT, pw);
881 pw.println();
882
Dianne Hackborna750a632015-06-16 17:18:23 -0700883 pw.print(" "); pw.print(KEY_IDLE_FACTOR); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700884 pw.println(IDLE_FACTOR);
885
Dianne Hackborna750a632015-06-16 17:18:23 -0700886 pw.print(" "); pw.print(KEY_MIN_TIME_TO_ALARM); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700887 TimeUtils.formatDuration(MIN_TIME_TO_ALARM, pw);
888 pw.println();
889
Dianne Hackborna750a632015-06-16 17:18:23 -0700890 pw.print(" "); pw.print(KEY_MAX_TEMP_APP_WHITELIST_DURATION); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700891 TimeUtils.formatDuration(MAX_TEMP_APP_WHITELIST_DURATION, pw);
892 pw.println();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700893
894 pw.print(" "); pw.print(KEY_MMS_TEMP_APP_WHITELIST_DURATION); pw.print("=");
895 TimeUtils.formatDuration(MMS_TEMP_APP_WHITELIST_DURATION, pw);
896 pw.println();
Dianne Hackborn451c3462015-07-21 17:39:46 -0700897
898 pw.print(" "); pw.print(KEY_SMS_TEMP_APP_WHITELIST_DURATION); pw.print("=");
899 TimeUtils.formatDuration(SMS_TEMP_APP_WHITELIST_DURATION, pw);
900 pw.println();
Adam Lesinski31c05d12015-06-09 17:34:04 -0700901 }
902 }
903
904 private Constants mConstants;
905
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700906 @Override
907 public void onAnyMotionResult(int result) {
908 if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700909 if (result == AnyMotionDetector.RESULT_MOVED) {
910 if (DEBUG) Slog.d(TAG, "RESULT_MOVED received.");
911 synchronized (this) {
912 handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "sense_motion");
913 }
914 } else if (result == AnyMotionDetector.RESULT_STATIONARY) {
915 if (DEBUG) Slog.d(TAG, "RESULT_STATIONARY received.");
916 if (mState == STATE_SENSING) {
917 // If we are currently sensing, it is time to move to locating.
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700918 synchronized (this) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700919 mNotMoving = true;
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800920 stepIdleStateLocked("s:stationary");
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700921 }
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700922 } else if (mState == STATE_LOCATING) {
923 // If we are currently locating, note that we are not moving and step
924 // if we have located the position.
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700925 synchronized (this) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700926 mNotMoving = true;
927 if (mLocated) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800928 stepIdleStateLocked("s:stationary");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700929 }
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700930 }
931 }
932 }
933 }
934
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700935 static final int MSG_WRITE_CONFIG = 1;
936 static final int MSG_REPORT_IDLE_ON = 2;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700937 static final int MSG_REPORT_IDLE_ON_LIGHT = 3;
938 static final int MSG_REPORT_IDLE_OFF = 4;
939 static final int MSG_REPORT_ACTIVE = 5;
940 static final int MSG_TEMP_APP_WHITELIST_TIMEOUT = 6;
Yao Chenca5edbb2016-01-13 14:44:36 -0800941 static final int MSG_REPORT_MAINTENANCE_ACTIVITY = 7;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700942
943 final class MyHandler extends Handler {
944 MyHandler(Looper looper) {
945 super(looper);
946 }
947
948 @Override public void handleMessage(Message msg) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700949 if (DEBUG) Slog.d(TAG, "handleMessage(" + msg.what + ")");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700950 switch (msg.what) {
951 case MSG_WRITE_CONFIG: {
952 handleWriteConfigFile();
953 } break;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700954 case MSG_REPORT_IDLE_ON:
955 case MSG_REPORT_IDLE_ON_LIGHT: {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700956 EventLogTags.writeDeviceIdleOnStart();
Dianne Hackbornb6843652016-02-22 12:20:13 -0800957 final boolean deepChanged;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700958 final boolean lightChanged;
959 if (msg.what == MSG_REPORT_IDLE_ON) {
Dianne Hackbornb6843652016-02-22 12:20:13 -0800960 deepChanged = mLocalPowerManager.setDeviceIdleMode(true);
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700961 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
962 } else {
Dianne Hackbornb6843652016-02-22 12:20:13 -0800963 deepChanged = mLocalPowerManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700964 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(true);
965 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700966 try {
967 mNetworkPolicyManager.setDeviceIdleMode(true);
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700968 mBatteryStats.noteDeviceIdleMode(msg.what == MSG_REPORT_IDLE_ON
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700969 ? BatteryStats.DEVICE_IDLE_MODE_DEEP
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700970 : BatteryStats.DEVICE_IDLE_MODE_LIGHT, null, Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700971 } catch (RemoteException e) {
972 }
Dianne Hackbornb6843652016-02-22 12:20:13 -0800973 if (deepChanged) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700974 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
975 }
976 if (lightChanged) {
977 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL);
978 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700979 EventLogTags.writeDeviceIdleOnComplete();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700980 } break;
981 case MSG_REPORT_IDLE_OFF: {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700982 EventLogTags.writeDeviceIdleOffStart("unknown");
Dianne Hackbornb6843652016-02-22 12:20:13 -0800983 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700984 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700985 try {
986 mNetworkPolicyManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700987 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF,
988 null, Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700989 } catch (RemoteException e) {
990 }
Dianne Hackbornb6843652016-02-22 12:20:13 -0800991 if (deepChanged) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800992 incActiveIdleOps();
993 getContext().sendOrderedBroadcastAsUser(mIdleIntent, UserHandle.ALL,
994 null, mIdleStartedDoneReceiver, null, 0, null, null);
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700995 }
996 if (lightChanged) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800997 incActiveIdleOps();
998 getContext().sendOrderedBroadcastAsUser(mLightIdleIntent, UserHandle.ALL,
999 null, mIdleStartedDoneReceiver, null, 0, null, null);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001000 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001001 // Always start with one active op for the message being sent here.
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001002 // Now we are done!
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001003 decActiveIdleOps();
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001004 EventLogTags.writeDeviceIdleOffComplete();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001005 } break;
1006 case MSG_REPORT_ACTIVE: {
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001007 String activeReason = (String)msg.obj;
1008 int activeUid = msg.arg1;
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001009 EventLogTags.writeDeviceIdleOffStart(
1010 activeReason != null ? activeReason : "unknown");
Dianne Hackbornb6843652016-02-22 12:20:13 -08001011 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001012 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001013 try {
1014 mNetworkPolicyManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001015 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF,
1016 activeReason, activeUid);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001017 } catch (RemoteException e) {
1018 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08001019 if (deepChanged) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001020 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
1021 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001022 if (lightChanged) {
1023 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL);
1024 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001025 EventLogTags.writeDeviceIdleOffComplete();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001026 } break;
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001027 case MSG_TEMP_APP_WHITELIST_TIMEOUT: {
1028 int uid = msg.arg1;
1029 checkTempAppWhitelistTimeout(uid);
1030 } break;
Yao Chenca5edbb2016-01-13 14:44:36 -08001031 case MSG_REPORT_MAINTENANCE_ACTIVITY: {
1032 boolean active = (msg.arg1 == 1);
1033 final int size = mMaintenanceActivityListeners.beginBroadcast();
1034 try {
1035 for (int i = 0; i < size; i++) {
1036 try {
1037 mMaintenanceActivityListeners.getBroadcastItem(i)
1038 .onMaintenanceActivityChanged(active);
1039 } catch (RemoteException ignored) {
1040 }
1041 }
1042 } finally {
1043 mMaintenanceActivityListeners.finishBroadcast();
1044 }
1045 } break;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001046 }
1047 }
1048 }
1049
1050 final MyHandler mHandler;
1051
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001052 BinderService mBinderService;
1053
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001054 private final class BinderService extends IDeviceIdleController.Stub {
1055 @Override public void addPowerSaveWhitelistApp(String name) {
1056 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1057 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001058 long ident = Binder.clearCallingIdentity();
1059 try {
1060 addPowerSaveWhitelistAppInternal(name);
1061 } finally {
1062 Binder.restoreCallingIdentity(ident);
1063 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001064 }
1065
1066 @Override public void removePowerSaveWhitelistApp(String name) {
1067 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1068 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001069 long ident = Binder.clearCallingIdentity();
1070 try {
1071 removePowerSaveWhitelistAppInternal(name);
1072 } finally {
1073 Binder.restoreCallingIdentity(ident);
1074 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001075 }
1076
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001077 @Override public String[] getSystemPowerWhitelistExceptIdle() {
1078 return getSystemPowerWhitelistExceptIdleInternal();
1079 }
1080
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001081 @Override public String[] getSystemPowerWhitelist() {
1082 return getSystemPowerWhitelistInternal();
1083 }
1084
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001085 @Override public String[] getUserPowerWhitelist() {
1086 return getUserPowerWhitelistInternal();
1087 }
1088
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001089 @Override public String[] getFullPowerWhitelistExceptIdle() {
1090 return getFullPowerWhitelistExceptIdleInternal();
1091 }
1092
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001093 @Override public String[] getFullPowerWhitelist() {
1094 return getFullPowerWhitelistInternal();
1095 }
1096
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001097 @Override public int[] getAppIdWhitelistExceptIdle() {
1098 return getAppIdWhitelistExceptIdleInternal();
1099 }
1100
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001101 @Override public int[] getAppIdWhitelist() {
1102 return getAppIdWhitelistInternal();
1103 }
1104
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001105 @Override public int[] getAppIdUserWhitelist() {
1106 return getAppIdUserWhitelistInternal();
1107 }
1108
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001109 @Override public int[] getAppIdTempWhitelist() {
1110 return getAppIdTempWhitelistInternal();
1111 }
1112
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001113 @Override public boolean isPowerSaveWhitelistExceptIdleApp(String name) {
1114 return isPowerSaveWhitelistExceptIdleAppInternal(name);
1115 }
1116
Amith Yamasani06bf8242015-05-08 16:36:21 -07001117 @Override public boolean isPowerSaveWhitelistApp(String name) {
1118 return isPowerSaveWhitelistAppInternal(name);
1119 }
1120
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001121 @Override public void addPowerSaveTempWhitelistApp(String packageName, long duration,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001122 int userId, String reason) throws RemoteException {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001123 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001124 }
1125
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001126 @Override public long addPowerSaveTempWhitelistAppForMms(String packageName,
1127 int userId, String reason) throws RemoteException {
1128 long duration = mConstants.MMS_TEMP_APP_WHITELIST_DURATION;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001129 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001130 return duration;
1131 }
1132
Dianne Hackborn451c3462015-07-21 17:39:46 -07001133 @Override public long addPowerSaveTempWhitelistAppForSms(String packageName,
1134 int userId, String reason) throws RemoteException {
1135 long duration = mConstants.SMS_TEMP_APP_WHITELIST_DURATION;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001136 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Dianne Hackborn451c3462015-07-21 17:39:46 -07001137 return duration;
1138 }
1139
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001140 @Override public void exitIdle(String reason) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001141 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER,
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001142 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001143 long ident = Binder.clearCallingIdentity();
1144 try {
1145 exitIdleInternal(reason);
1146 } finally {
1147 Binder.restoreCallingIdentity(ident);
1148 }
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001149 }
1150
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001151 @Override public void downloadServiceActive(IBinder token) {
1152 getContext().enforceCallingOrSelfPermission(
1153 "android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS", null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001154 long ident = Binder.clearCallingIdentity();
1155 try {
1156 DeviceIdleController.this.downloadServiceActive(token);
1157 } finally {
1158 Binder.restoreCallingIdentity(ident);
1159 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001160 }
1161
1162 @Override public void downloadServiceInactive() {
1163 getContext().enforceCallingOrSelfPermission(
1164 "android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS", null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001165 long ident = Binder.clearCallingIdentity();
1166 try {
1167 DeviceIdleController.this.downloadServiceInactive();
1168 } finally {
1169 Binder.restoreCallingIdentity(ident);
1170 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001171 }
1172
Yao Chenca5edbb2016-01-13 14:44:36 -08001173 @Override public boolean registerMaintenanceActivityListener(
1174 IMaintenanceActivityListener listener) {
1175 return DeviceIdleController.this.registerMaintenanceActivityListener(listener);
1176 }
1177
1178 @Override public void unregisterMaintenanceActivityListener(
1179 IMaintenanceActivityListener listener) {
1180 DeviceIdleController.this.unregisterMaintenanceActivityListener(listener);
1181 }
1182
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001183 @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1184 DeviceIdleController.this.dump(fd, pw, args);
1185 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001186
1187 @Override public void onShellCommand(FileDescriptor in, FileDescriptor out,
1188 FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
1189 (new Shell()).exec(this, in, out, err, args, resultReceiver);
1190 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001191 }
1192
Dianne Hackborna750a632015-06-16 17:18:23 -07001193 public final class LocalService {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001194 public void addPowerSaveTempWhitelistAppDirect(int appId, long duration, boolean sync,
1195 String reason) {
1196 addPowerSaveTempWhitelistAppDirectInternal(0, appId, duration, sync, reason);
1197 }
1198
1199 public void setNetworkPolicyTempWhitelistCallback(Runnable callback) {
1200 setNetworkPolicyTempWhitelistCallbackInternal(callback);
Dianne Hackborna750a632015-06-16 17:18:23 -07001201 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001202
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001203 public void setJobsActive(boolean active) {
1204 DeviceIdleController.this.setJobsActive(active);
1205 }
1206
1207 // Up-call from alarm manager.
1208 public void setAlarmsActive(boolean active) {
1209 DeviceIdleController.this.setAlarmsActive(active);
1210 }
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001211
1212 /**
1213 * Returns the array of app ids whitelisted by user. Take care not to
1214 * modify this, as it is a reference to the original copy. But the reference
1215 * can change when the list changes, so it needs to be re-acquired when
1216 * {@link PowerManager#ACTION_POWER_SAVE_WHITELIST_CHANGED} is sent.
1217 */
1218 public int[] getPowerSaveWhitelistUserAppIds() {
1219 return DeviceIdleController.this.getPowerSaveWhitelistUserAppIds();
1220 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001221 }
1222
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001223 public DeviceIdleController(Context context) {
1224 super(context);
1225 mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml"));
1226 mHandler = new MyHandler(BackgroundThread.getHandler().getLooper());
1227 }
1228
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001229 int[] getPowerSaveWhitelistUserAppIds() {
1230 synchronized (this) {
1231 return mPowerSaveWhitelistUserAppIdArray;
1232 }
1233 }
1234
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001235 private static File getSystemDir() {
1236 return new File(Environment.getDataDirectory(), "system");
1237 }
1238
1239 @Override
1240 public void onStart() {
1241 final PackageManager pm = getContext().getPackageManager();
1242
1243 synchronized (this) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08001244 mLightEnabled = mDeepEnabled = getContext().getResources().getBoolean(
Dianne Hackborn92617032015-06-19 15:32:19 -07001245 com.android.internal.R.bool.config_enableAutoPowerModes);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001246 SystemConfig sysConfig = SystemConfig.getInstance();
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001247 ArraySet<String> allowPowerExceptIdle = sysConfig.getAllowInPowerSaveExceptIdle();
1248 for (int i=0; i<allowPowerExceptIdle.size(); i++) {
1249 String pkg = allowPowerExceptIdle.valueAt(i);
1250 try {
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07001251 ApplicationInfo ai = pm.getApplicationInfo(pkg,
1252 PackageManager.MATCH_SYSTEM_ONLY);
1253 int appid = UserHandle.getAppId(ai.uid);
1254 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
1255 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001256 } catch (PackageManager.NameNotFoundException e) {
1257 }
1258 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001259 ArraySet<String> allowPower = sysConfig.getAllowInPowerSave();
1260 for (int i=0; i<allowPower.size(); i++) {
1261 String pkg = allowPower.valueAt(i);
1262 try {
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07001263 ApplicationInfo ai = pm.getApplicationInfo(pkg,
1264 PackageManager.MATCH_SYSTEM_ONLY);
1265 int appid = UserHandle.getAppId(ai.uid);
1266 // These apps are on both the whitelist-except-idle as well
1267 // as the full whitelist, so they apply in all cases.
1268 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
1269 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
1270 mPowerSaveWhitelistApps.put(ai.packageName, appid);
1271 mPowerSaveWhitelistSystemAppIds.put(appid, true);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001272 } catch (PackageManager.NameNotFoundException e) {
1273 }
1274 }
1275
Adam Lesinski31c05d12015-06-09 17:34:04 -07001276 mConstants = new Constants(mHandler, getContext().getContentResolver());
1277
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001278 readConfigFileLocked();
1279 updateWhitelistAppIdsLocked();
1280
1281 mScreenOn = true;
1282 // Start out assuming we are charging. If we aren't, we will at least get
1283 // a battery update the next time the level drops.
1284 mCharging = true;
1285 mState = STATE_ACTIVE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001286 mLightState = LIGHT_STATE_ACTIVE;
Adam Lesinski31c05d12015-06-09 17:34:04 -07001287 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001288 }
1289
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001290 mBinderService = new BinderService();
1291 publishBinderService(Context.DEVICE_IDLE_CONTROLLER, mBinderService);
Dianne Hackborna750a632015-06-16 17:18:23 -07001292 publishLocalService(LocalService.class, new LocalService());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001293 }
1294
1295 @Override
1296 public void onBootPhase(int phase) {
1297 if (phase == PHASE_SYSTEM_SERVICES_READY) {
1298 synchronized (this) {
1299 mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
1300 mBatteryStats = BatteryStatsService.getService();
1301 mLocalPowerManager = getLocalService(PowerManagerInternal.class);
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001302 mLocalAlarmManager = getLocalService(AlarmManagerService.LocalService.class);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001303 mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface(
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001304 ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001305 mDisplayManager = (DisplayManager) getContext().getSystemService(
1306 Context.DISPLAY_SERVICE);
1307 mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001308 int sigMotionSensorId = getContext().getResources().getInteger(
1309 com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor);
1310 if (sigMotionSensorId > 0) {
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001311 mMotionSensor = mSensorManager.getDefaultSensor(sigMotionSensorId, true);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001312 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001313 if (mMotionSensor == null && getContext().getResources().getBoolean(
Joe LaPenna23d681b2015-08-27 15:12:11 -07001314 com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) {
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001315 mMotionSensor = mSensorManager.getDefaultSensor(
1316 Sensor.TYPE_WRIST_TILT_GESTURE, true);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001317 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001318 if (mMotionSensor == null) {
Joe LaPenna23d681b2015-08-27 15:12:11 -07001319 // As a last ditch, fall back to SMD.
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001320 mMotionSensor = mSensorManager.getDefaultSensor(
1321 Sensor.TYPE_SIGNIFICANT_MOTION, true);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001322 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001323
Joe LaPenna23d681b2015-08-27 15:12:11 -07001324 if (getContext().getResources().getBoolean(
1325 com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) {
1326 mLocationManager = (LocationManager) getContext().getSystemService(
1327 Context.LOCATION_SERVICE);
1328 mLocationRequest = new LocationRequest()
1329 .setQuality(LocationRequest.ACCURACY_FINE)
1330 .setInterval(0)
1331 .setFastestInterval(0)
1332 .setNumUpdates(1);
1333 }
1334
1335 float angleThreshold = getContext().getResources().getInteger(
1336 com.android.internal.R.integer.config_autoPowerModeThresholdAngle) / 100f;
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001337 mAnyMotionDetector = new AnyMotionDetector(
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001338 (PowerManager) getContext().getSystemService(Context.POWER_SERVICE),
Joe LaPenna23d681b2015-08-27 15:12:11 -07001339 mHandler, mSensorManager, this, angleThreshold);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001340
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001341 mIdleIntent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001342 mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1343 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001344 mLightIdleIntent = new Intent(PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
1345 mLightIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1346 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001347
1348 IntentFilter filter = new IntentFilter();
1349 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001350 getContext().registerReceiver(mReceiver, filter);
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07001351 filter = new IntentFilter();
1352 filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
1353 filter.addDataScheme("package");
1354 getContext().registerReceiver(mReceiver, filter);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001355
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001356 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001357 mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001358 mDisplayManager.registerDisplayListener(mDisplayListener, null);
1359 updateDisplayLocked();
1360 }
1361 }
1362 }
1363
1364 public boolean addPowerSaveWhitelistAppInternal(String name) {
1365 synchronized (this) {
1366 try {
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07001367 ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name,
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07001368 PackageManager.MATCH_UNINSTALLED_PACKAGES);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001369 if (mPowerSaveWhitelistUserApps.put(name, UserHandle.getAppId(ai.uid)) == null) {
1370 reportPowerSaveWhitelistChangedLocked();
1371 updateWhitelistAppIdsLocked();
1372 writeConfigFileLocked();
1373 }
1374 return true;
1375 } catch (PackageManager.NameNotFoundException e) {
1376 return false;
1377 }
1378 }
1379 }
1380
1381 public boolean removePowerSaveWhitelistAppInternal(String name) {
1382 synchronized (this) {
1383 if (mPowerSaveWhitelistUserApps.remove(name) != null) {
1384 reportPowerSaveWhitelistChangedLocked();
1385 updateWhitelistAppIdsLocked();
1386 writeConfigFileLocked();
1387 return true;
1388 }
1389 }
1390 return false;
1391 }
1392
Felipe Lemef8a46232016-02-10 13:51:54 -08001393 public boolean getPowerSaveWhitelistAppInternal(String name) {
1394 synchronized (this) {
1395 return mPowerSaveWhitelistUserApps.containsKey(name);
1396 }
1397 }
1398
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001399 public String[] getSystemPowerWhitelistExceptIdleInternal() {
1400 synchronized (this) {
1401 int size = mPowerSaveWhitelistAppsExceptIdle.size();
1402 String[] apps = new String[size];
1403 for (int i = 0; i < size; i++) {
1404 apps[i] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i);
1405 }
1406 return apps;
1407 }
1408 }
1409
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001410 public String[] getSystemPowerWhitelistInternal() {
1411 synchronized (this) {
1412 int size = mPowerSaveWhitelistApps.size();
1413 String[] apps = new String[size];
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001414 for (int i = 0; i < size; i++) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001415 apps[i] = mPowerSaveWhitelistApps.keyAt(i);
1416 }
1417 return apps;
1418 }
1419 }
1420
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001421 public String[] getUserPowerWhitelistInternal() {
1422 synchronized (this) {
1423 int size = mPowerSaveWhitelistUserApps.size();
1424 String[] apps = new String[size];
1425 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
1426 apps[i] = mPowerSaveWhitelistUserApps.keyAt(i);
1427 }
1428 return apps;
1429 }
1430 }
1431
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001432 public String[] getFullPowerWhitelistExceptIdleInternal() {
1433 synchronized (this) {
1434 int size = mPowerSaveWhitelistAppsExceptIdle.size() + mPowerSaveWhitelistUserApps.size();
1435 String[] apps = new String[size];
1436 int cur = 0;
1437 for (int i = 0; i < mPowerSaveWhitelistAppsExceptIdle.size(); i++) {
1438 apps[cur] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i);
1439 cur++;
1440 }
1441 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
1442 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i);
1443 cur++;
1444 }
1445 return apps;
1446 }
1447 }
1448
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001449 public String[] getFullPowerWhitelistInternal() {
1450 synchronized (this) {
1451 int size = mPowerSaveWhitelistApps.size() + mPowerSaveWhitelistUserApps.size();
1452 String[] apps = new String[size];
1453 int cur = 0;
1454 for (int i = 0; i < mPowerSaveWhitelistApps.size(); i++) {
1455 apps[cur] = mPowerSaveWhitelistApps.keyAt(i);
1456 cur++;
1457 }
1458 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
1459 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i);
1460 cur++;
1461 }
1462 return apps;
1463 }
1464 }
1465
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001466 public boolean isPowerSaveWhitelistExceptIdleAppInternal(String packageName) {
1467 synchronized (this) {
1468 return mPowerSaveWhitelistAppsExceptIdle.containsKey(packageName)
1469 || mPowerSaveWhitelistUserApps.containsKey(packageName);
1470 }
1471 }
1472
Amith Yamasani06bf8242015-05-08 16:36:21 -07001473 public boolean isPowerSaveWhitelistAppInternal(String packageName) {
1474 synchronized (this) {
1475 return mPowerSaveWhitelistApps.containsKey(packageName)
1476 || mPowerSaveWhitelistUserApps.containsKey(packageName);
1477 }
1478 }
1479
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001480 public int[] getAppIdWhitelistExceptIdleInternal() {
1481 synchronized (this) {
1482 return mPowerSaveWhitelistExceptIdleAppIdArray;
1483 }
1484 }
1485
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001486 public int[] getAppIdWhitelistInternal() {
1487 synchronized (this) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001488 return mPowerSaveWhitelistAllAppIdArray;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001489 }
1490 }
1491
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001492 public int[] getAppIdUserWhitelistInternal() {
1493 synchronized (this) {
1494 return mPowerSaveWhitelistUserAppIdArray;
1495 }
1496 }
1497
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001498 public int[] getAppIdTempWhitelistInternal() {
1499 synchronized (this) {
1500 return mTempWhitelistAppIdArray;
1501 }
1502 }
1503
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001504 void addPowerSaveTempWhitelistAppChecked(String packageName, long duration,
1505 int userId, String reason) throws RemoteException {
1506 getContext().enforceCallingPermission(
1507 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
1508 "No permission to change device idle whitelist");
1509 final int callingUid = Binder.getCallingUid();
1510 userId = ActivityManagerNative.getDefault().handleIncomingUser(
1511 Binder.getCallingPid(),
1512 callingUid,
1513 userId,
1514 /*allowAll=*/ false,
1515 /*requireFull=*/ false,
1516 "addPowerSaveTempWhitelistApp", null);
1517 final long token = Binder.clearCallingIdentity();
1518 try {
1519 addPowerSaveTempWhitelistAppInternal(callingUid,
1520 packageName, duration, userId, true, reason);
1521 } finally {
1522 Binder.restoreCallingIdentity(token);
1523 }
1524 }
1525
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001526 /**
1527 * Adds an app to the temporary whitelist and resets the endTime for granting the
1528 * app an exemption to access network and acquire wakelocks.
1529 */
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001530 void addPowerSaveTempWhitelistAppInternal(int callingUid, String packageName,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001531 long duration, int userId, boolean sync, String reason) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001532 try {
Jeff Sharkeye06b4d12016-01-06 14:51:50 -07001533 int uid = getContext().getPackageManager().getPackageUidAsUser(packageName, userId);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001534 int appId = UserHandle.getAppId(uid);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001535 addPowerSaveTempWhitelistAppDirectInternal(callingUid, appId, duration, sync, reason);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001536 } catch (NameNotFoundException e) {
1537 }
1538 }
1539
Dianne Hackborna750a632015-06-16 17:18:23 -07001540 /**
1541 * Adds an app to the temporary whitelist and resets the endTime for granting the
1542 * app an exemption to access network and acquire wakelocks.
1543 */
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001544 void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int appId,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001545 long duration, boolean sync, String reason) {
Dianne Hackborna750a632015-06-16 17:18:23 -07001546 final long timeNow = SystemClock.elapsedRealtime();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001547 Runnable networkPolicyTempWhitelistCallback = null;
Dianne Hackborna750a632015-06-16 17:18:23 -07001548 synchronized (this) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001549 int callingAppId = UserHandle.getAppId(callingUid);
1550 if (callingAppId >= Process.FIRST_APPLICATION_UID) {
1551 if (!mPowerSaveWhitelistSystemAppIds.get(callingAppId)) {
1552 throw new SecurityException("Calling app " + UserHandle.formatUid(callingUid)
1553 + " is not on whitelist");
1554 }
1555 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001556 duration = Math.min(duration, mConstants.MAX_TEMP_APP_WHITELIST_DURATION);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001557 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId);
1558 final boolean newEntry = entry == null;
Dianne Hackborna750a632015-06-16 17:18:23 -07001559 // Set the new end time
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001560 if (newEntry) {
1561 entry = new Pair<>(new MutableLong(0), reason);
1562 mTempWhitelistAppIdEndTimes.put(appId, entry);
1563 }
1564 entry.first.value = timeNow + duration;
Dianne Hackborna750a632015-06-16 17:18:23 -07001565 if (DEBUG) {
1566 Slog.d(TAG, "Adding AppId " + appId + " to temp whitelist");
1567 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001568 if (newEntry) {
Dianne Hackborna750a632015-06-16 17:18:23 -07001569 // No pending timeout for the app id, post a delayed message
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001570 try {
1571 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_START,
1572 reason, appId);
1573 } catch (RemoteException e) {
1574 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001575 postTempActiveTimeoutMessage(appId, duration);
1576 updateTempWhitelistAppIdsLocked();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001577 if (mNetworkPolicyTempWhitelistCallback != null) {
1578 if (!sync) {
1579 mHandler.post(mNetworkPolicyTempWhitelistCallback);
1580 } else {
1581 networkPolicyTempWhitelistCallback = mNetworkPolicyTempWhitelistCallback;
1582 }
1583 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001584 reportTempWhitelistChangedLocked();
1585 }
1586 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001587 if (networkPolicyTempWhitelistCallback != null) {
1588 networkPolicyTempWhitelistCallback.run();
1589 }
1590 }
1591
1592 public void setNetworkPolicyTempWhitelistCallbackInternal(Runnable callback) {
1593 synchronized (this) {
1594 mNetworkPolicyTempWhitelistCallback = callback;
1595 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001596 }
1597
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001598 private void postTempActiveTimeoutMessage(int uid, long delay) {
1599 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, uid, 0),
1600 delay);
1601 }
1602
1603 void checkTempAppWhitelistTimeout(int uid) {
Dianne Hackborna750a632015-06-16 17:18:23 -07001604 final long timeNow = SystemClock.elapsedRealtime();
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001605 synchronized (this) {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001606 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(uid);
1607 if (entry == null) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001608 // Nothing to do
1609 return;
1610 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001611 if (timeNow >= entry.first.value) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001612 mTempWhitelistAppIdEndTimes.delete(uid);
1613 if (DEBUG) {
1614 Slog.d(TAG, "Removing UID " + uid + " from temp whitelist");
1615 }
1616 updateTempWhitelistAppIdsLocked();
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001617 if (mNetworkPolicyTempWhitelistCallback != null) {
1618 mHandler.post(mNetworkPolicyTempWhitelistCallback);
1619 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001620 reportTempWhitelistChangedLocked();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001621 try {
1622 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH,
1623 entry.second, uid);
1624 } catch (RemoteException e) {
1625 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001626 } else {
1627 // Need more time
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001628 postTempActiveTimeoutMessage(uid, entry.first.value - timeNow);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001629 }
1630 }
1631 }
1632
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001633 public void exitIdleInternal(String reason) {
1634 synchronized (this) {
1635 becomeActiveLocked(reason, Binder.getCallingUid());
1636 }
1637 }
1638
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001639 void updateDisplayLocked() {
1640 mCurDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
1641 // We consider any situation where the display is showing something to be it on,
1642 // because if there is anything shown we are going to be updating it at some
1643 // frequency so can't be allowed to go into deep sleeps.
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001644 boolean screenOn = mCurDisplay.getState() == Display.STATE_ON;
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001645 if (DEBUG) Slog.d(TAG, "updateDisplayLocked: screenOn=" + screenOn);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001646 if (!screenOn && mScreenOn) {
1647 mScreenOn = false;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001648 if (!mForceIdle) {
1649 becomeInactiveIfAppropriateLocked();
1650 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001651 } else if (screenOn) {
1652 mScreenOn = true;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001653 if (!mForceIdle) {
1654 becomeActiveLocked("screen", Process.myUid());
1655 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001656 }
1657 }
1658
1659 void updateChargingLocked(boolean charging) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001660 if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001661 if (!charging && mCharging) {
1662 mCharging = false;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001663 if (!mForceIdle) {
1664 becomeInactiveIfAppropriateLocked();
1665 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001666 } else if (charging) {
1667 mCharging = charging;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001668 if (!mForceIdle) {
1669 becomeActiveLocked("charging", Process.myUid());
1670 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001671 }
1672 }
1673
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001674 void scheduleReportActiveLocked(String activeReason, int activeUid) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001675 Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid, 0, activeReason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001676 mHandler.sendMessage(msg);
1677 }
1678
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001679 void becomeActiveLocked(String activeReason, int activeUid) {
1680 if (DEBUG) Slog.i(TAG, "becomeActiveLocked, reason = " + activeReason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001681 if (mState != STATE_ACTIVE || mLightState != STATE_ACTIVE) {
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001682 EventLogTags.writeDeviceIdle(STATE_ACTIVE, activeReason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001683 EventLogTags.writeDeviceIdleLight(LIGHT_STATE_ACTIVE, activeReason);
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001684 scheduleReportActiveLocked(activeReason, activeUid);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001685 mState = STATE_ACTIVE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001686 mLightState = LIGHT_STATE_ACTIVE;
Adam Lesinski31c05d12015-06-09 17:34:04 -07001687 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001688 mCurIdleBudget = 0;
1689 mMaintenanceStartTime = 0;
Dianne Hackborn953fc942016-03-29 15:36:24 -07001690 if (mMaintenanceMinCheckScheduled) {
1691 mAlarmManager.cancel(mMaintenanceMinCheckListener);
1692 mMaintenanceMinCheckScheduled = false;
1693 }
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001694 resetIdleManagementLocked();
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001695 resetLightIdleManagementLocked();
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001696 addEvent(EVENT_NORMAL);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001697 }
1698 }
1699
1700 void becomeInactiveIfAppropriateLocked() {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001701 if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()");
Dianne Hackbornb6843652016-02-22 12:20:13 -08001702 if ((!mScreenOn && !mCharging) || mForceIdle) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001703 // Screen has turned off; we are now going to become inactive and start
1704 // waiting to see if we will ultimately go idle.
Dianne Hackbornb6843652016-02-22 12:20:13 -08001705 if (mState == STATE_ACTIVE && mDeepEnabled) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001706 mState = STATE_INACTIVE;
1707 if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE");
1708 resetIdleManagementLocked();
1709 scheduleAlarmLocked(mInactiveTimeout, false);
1710 EventLogTags.writeDeviceIdle(mState, "no activity");
1711 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08001712 if (mLightState == LIGHT_STATE_ACTIVE && mLightEnabled) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001713 mLightState = LIGHT_STATE_INACTIVE;
1714 if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE");
1715 resetLightIdleManagementLocked();
Dianne Hackborn953fc942016-03-29 15:36:24 -07001716 scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001717 EventLogTags.writeDeviceIdleLight(mLightState, "no activity");
1718 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001719 }
1720 }
1721
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001722 void resetIdleManagementLocked() {
1723 mNextIdlePendingDelay = 0;
1724 mNextIdleDelay = 0;
Dianne Hackborn953fc942016-03-29 15:36:24 -07001725 mNextLightIdleDelay = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001726 cancelAlarmLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001727 cancelLocatingLocked();
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001728 stopMonitoringMotionLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001729 mAnyMotionDetector.stop();
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001730 }
1731
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001732 void resetLightIdleManagementLocked() {
1733 cancelLightAlarmLocked();
1734 }
1735
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001736 void exitForceIdleLocked() {
1737 if (mForceIdle) {
1738 mForceIdle = false;
1739 if (mScreenOn || mCharging) {
1740 becomeActiveLocked("exit-force-idle", Process.myUid());
1741 }
1742 }
1743 }
1744
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001745 void stepLightIdleStateLocked(String reason) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001746 if (mLightState == LIGHT_STATE_OVERRIDE) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08001747 // If we are already in deep device idle mode, then
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001748 // there is nothing left to do for light mode.
1749 return;
1750 }
1751
1752 if (DEBUG) Slog.d(TAG, "stepLightIdleStateLocked: mLightState=" + mLightState);
1753 EventLogTags.writeDeviceIdleLightStep();
1754
1755 switch (mLightState) {
1756 case LIGHT_STATE_INACTIVE:
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001757 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
Dianne Hackborn953fc942016-03-29 15:36:24 -07001758 // Reset the upcoming idle delays.
1759 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001760 mMaintenanceStartTime = 0;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001761 case LIGHT_STATE_IDLE_MAINTENANCE:
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001762 if (mMaintenanceStartTime != 0) {
1763 long duration = SystemClock.elapsedRealtime() - mMaintenanceStartTime;
1764 if (duration < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
1765 // We didn't use up all of our minimum budget; add this to the reserve.
1766 mCurIdleBudget += (mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET-duration);
1767 } else {
1768 // We used more than our minimum budget; this comes out of the reserve.
1769 mCurIdleBudget -= (duration-mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET);
1770 }
1771 }
1772 mMaintenanceStartTime = 0;
Dianne Hackborn953fc942016-03-29 15:36:24 -07001773 scheduleLightAlarmLocked(mNextLightIdleDelay);
1774 mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT,
1775 (long)(mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR));
1776 if (mNextLightIdleDelay < mConstants.LIGHT_IDLE_TIMEOUT) {
1777 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT;
1778 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001779 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_STATE_IDLE.");
1780 mLightState = LIGHT_STATE_IDLE;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001781 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001782 addEvent(EVENT_LIGHT_IDLE);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001783 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON_LIGHT);
Dianne Hackborn953fc942016-03-29 15:36:24 -07001784 if (mMaintenanceMinCheckScheduled) {
1785 mAlarmManager.cancel(mMaintenanceMinCheckListener);
1786 mMaintenanceMinCheckScheduled = false;
1787 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001788 break;
1789 case LIGHT_STATE_IDLE:
1790 // We have been idling long enough, now it is time to do some work.
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001791 mActiveIdleOpCount = 1;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001792 mMaintenanceStartTime = SystemClock.elapsedRealtime();
1793 if (mCurIdleBudget < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
1794 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
1795 } else if (mCurIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) {
1796 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
1797 }
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001798 scheduleLightAlarmLocked(mCurIdleBudget);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001799 if (DEBUG) Slog.d(TAG,
1800 "Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE.");
1801 mLightState = LIGHT_STATE_IDLE_MAINTENANCE;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001802 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001803 addEvent(EVENT_LIGHT_MAINTENANCE);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001804 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001805 mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME,
1806 mMaintenanceStartTime + mConstants.MIN_LIGHT_MAINTENANCE_TIME,
1807 "DeviceIdleController.maint-check", mMaintenanceMinCheckListener, mHandler);
Dianne Hackborn953fc942016-03-29 15:36:24 -07001808 mMaintenanceMinCheckScheduled = true;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001809 break;
1810 }
1811 }
1812
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001813 void stepIdleStateLocked(String reason) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001814 if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001815 EventLogTags.writeDeviceIdleStep();
1816
1817 final long now = SystemClock.elapsedRealtime();
Adam Lesinski31c05d12015-06-09 17:34:04 -07001818 if ((now+mConstants.MIN_TIME_TO_ALARM) > mAlarmManager.getNextWakeFromIdleTime()) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001819 // Whoops, there is an upcoming alarm. We don't actually want to go idle.
1820 if (mState != STATE_ACTIVE) {
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001821 becomeActiveLocked("alarm", Process.myUid());
Koji Fukui27b33302015-12-16 19:43:01 +09001822 becomeInactiveIfAppropriateLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001823 }
1824 return;
1825 }
1826
1827 switch (mState) {
1828 case STATE_INACTIVE:
1829 // We have now been inactive long enough, it is time to start looking
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001830 // for motion and sleep some more while doing so.
1831 startMonitoringMotionLocked();
Adam Lesinski31c05d12015-06-09 17:34:04 -07001832 scheduleAlarmLocked(mConstants.IDLE_AFTER_INACTIVE_TIMEOUT, false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001833 // Reset the upcoming idle delays.
Adam Lesinski31c05d12015-06-09 17:34:04 -07001834 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
1835 mNextIdleDelay = mConstants.IDLE_TIMEOUT;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001836 mState = STATE_IDLE_PENDING;
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001837 if (DEBUG) Slog.d(TAG, "Moved from STATE_INACTIVE to STATE_IDLE_PENDING.");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001838 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001839 break;
1840 case STATE_IDLE_PENDING:
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001841 mState = STATE_SENSING;
1842 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING.");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001843 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackborn18acb552015-10-26 14:31:07 -07001844 scheduleAlarmLocked(mConstants.SENSING_TIMEOUT, false);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001845 cancelLocatingLocked();
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001846 mAnyMotionDetector.checkForAnyMotion();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001847 mNotMoving = false;
1848 mLocated = false;
1849 mLastGenericLocation = null;
1850 mLastGpsLocation = null;
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001851 break;
1852 case STATE_SENSING:
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001853 mState = STATE_LOCATING;
1854 if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING.");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001855 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001856 scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT, false);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001857 if (mLocationManager != null
1858 && mLocationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
1859 mLocationManager.requestLocationUpdates(mLocationRequest,
1860 mGenericLocationListener, mHandler.getLooper());
1861 mLocating = true;
1862 } else {
1863 mHasNetworkLocation = false;
1864 }
1865 if (mLocationManager != null
1866 && mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
1867 mHasGps = true;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001868 mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5,
1869 mGpsLocationListener, mHandler.getLooper());
Joe LaPenna23d681b2015-08-27 15:12:11 -07001870 mLocating = true;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001871 } else {
Joe LaPenna23d681b2015-08-27 15:12:11 -07001872 mHasGps = false;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001873 }
Joe LaPenna23d681b2015-08-27 15:12:11 -07001874 // If we have a location provider, we're all set, the listeners will move state
1875 // forward.
1876 if (mLocating) {
1877 break;
1878 }
1879
1880 // Otherwise, we have to move from locating into idle maintenance.
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001881 case STATE_LOCATING:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001882 cancelAlarmLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001883 cancelLocatingLocked();
1884 mAnyMotionDetector.stop();
Dianne Hackborn953fc942016-03-29 15:36:24 -07001885
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001886 case STATE_IDLE_MAINTENANCE:
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001887 scheduleAlarmLocked(mNextIdleDelay, true);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001888 if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay +
1889 " ms.");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001890 mNextIdleDelay = (long)(mNextIdleDelay * mConstants.IDLE_FACTOR);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001891 if (DEBUG) Slog.d(TAG, "Setting mNextIdleDelay = " + mNextIdleDelay);
Adam Lesinski31c05d12015-06-09 17:34:04 -07001892 mNextIdleDelay = Math.min(mNextIdleDelay, mConstants.MAX_IDLE_TIMEOUT);
Dianne Hackborn953fc942016-03-29 15:36:24 -07001893 if (mNextIdleDelay < mConstants.IDLE_TIMEOUT) {
1894 mNextIdleDelay = mConstants.IDLE_TIMEOUT;
1895 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001896 mState = STATE_IDLE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001897 if (mLightState != LIGHT_STATE_OVERRIDE) {
1898 mLightState = LIGHT_STATE_OVERRIDE;
1899 cancelLightAlarmLocked();
1900 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001901 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackbornb6843652016-02-22 12:20:13 -08001902 addEvent(EVENT_DEEP_IDLE);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001903 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON);
Dianne Hackborn953fc942016-03-29 15:36:24 -07001904 if (mMaintenanceMinCheckScheduled) {
1905 mAlarmManager.cancel(mMaintenanceMinCheckListener);
1906 mMaintenanceMinCheckScheduled = false;
1907 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001908 break;
1909 case STATE_IDLE:
1910 // We have been idling long enough, now it is time to do some work.
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001911 mActiveIdleOpCount = 1;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001912 scheduleAlarmLocked(mNextIdlePendingDelay, false);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001913 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE to STATE_IDLE_MAINTENANCE. " +
1914 "Next alarm in " + mNextIdlePendingDelay + " ms.");
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001915 mMaintenanceStartTime = SystemClock.elapsedRealtime();
Adam Lesinski31c05d12015-06-09 17:34:04 -07001916 mNextIdlePendingDelay = Math.min(mConstants.MAX_IDLE_PENDING_TIMEOUT,
1917 (long)(mNextIdlePendingDelay * mConstants.IDLE_PENDING_FACTOR));
Dianne Hackborn953fc942016-03-29 15:36:24 -07001918 if (mNextIdlePendingDelay < mConstants.IDLE_PENDING_TIMEOUT) {
1919 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
1920 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001921 mState = STATE_IDLE_MAINTENANCE;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001922 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackbornb6843652016-02-22 12:20:13 -08001923 addEvent(EVENT_DEEP_MAINTENANCE);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001924 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001925 mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME,
1926 mMaintenanceStartTime + mConstants.MIN_DEEP_MAINTENANCE_TIME,
1927 "DeviceIdleController.maint-check", mMaintenanceMinCheckListener, mHandler);
Dianne Hackborn953fc942016-03-29 15:36:24 -07001928 mMaintenanceMinCheckScheduled = true;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001929 break;
1930 }
1931 }
1932
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001933 void incActiveIdleOps() {
1934 synchronized (this) {
1935 mActiveIdleOpCount++;
1936 }
1937 }
1938
1939 void decActiveIdleOps() {
1940 synchronized (this) {
1941 mActiveIdleOpCount--;
1942 if (mActiveIdleOpCount <= 0) {
1943 exitMaintenanceEarlyIfNeededLocked();
1944 }
1945 }
1946 }
1947
1948 void downloadServiceActive(IBinder token) {
1949 synchronized (this) {
1950 mDownloadServiceActive = token;
Yao Chenca5edbb2016-01-13 14:44:36 -08001951 reportMaintenanceActivityIfNeededLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001952 try {
1953 token.linkToDeath(new IBinder.DeathRecipient() {
1954 @Override public void binderDied() {
1955 downloadServiceInactive();
1956 }
1957 }, 0);
1958 } catch (RemoteException e) {
1959 mDownloadServiceActive = null;
1960 }
1961 }
1962 }
1963
1964 void downloadServiceInactive() {
1965 synchronized (this) {
1966 mDownloadServiceActive = null;
Yao Chenca5edbb2016-01-13 14:44:36 -08001967 reportMaintenanceActivityIfNeededLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001968 exitMaintenanceEarlyIfNeededLocked();
1969 }
1970 }
1971
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001972 void setJobsActive(boolean active) {
1973 synchronized (this) {
1974 mJobsActive = active;
Yao Chenca5edbb2016-01-13 14:44:36 -08001975 reportMaintenanceActivityIfNeededLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001976 if (!active) {
1977 exitMaintenanceEarlyIfNeededLocked();
1978 }
1979 }
1980 }
1981
1982 void setAlarmsActive(boolean active) {
1983 synchronized (this) {
1984 mAlarmsActive = active;
1985 if (!active) {
1986 exitMaintenanceEarlyIfNeededLocked();
1987 }
1988 }
1989 }
1990
Yao Chenca5edbb2016-01-13 14:44:36 -08001991 boolean registerMaintenanceActivityListener(IMaintenanceActivityListener listener) {
1992 synchronized (this) {
1993 mMaintenanceActivityListeners.register(listener);
1994 return mReportedMaintenanceActivity;
1995 }
1996 }
1997
1998 void unregisterMaintenanceActivityListener(IMaintenanceActivityListener listener) {
1999 synchronized (this) {
2000 mMaintenanceActivityListeners.unregister(listener);
2001 }
2002 }
2003
2004 void reportMaintenanceActivityIfNeededLocked() {
Amith Yamasanicb926fc2016-03-14 17:15:20 -07002005 boolean active = mJobsActive | (mDownloadServiceActive != null);
Yao Chenca5edbb2016-01-13 14:44:36 -08002006 if (active == mReportedMaintenanceActivity) {
2007 return;
2008 }
2009 mReportedMaintenanceActivity = active;
2010 Message msg = mHandler.obtainMessage(MSG_REPORT_MAINTENANCE_ACTIVITY,
2011 mReportedMaintenanceActivity ? 1 : 0, 0);
2012 mHandler.sendMessage(msg);
2013 }
2014
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002015 void exitMaintenanceEarlyIfNeededLocked() {
2016 if (mState == STATE_IDLE_MAINTENANCE || mLightState == LIGHT_STATE_IDLE_MAINTENANCE) {
2017 if (mActiveIdleOpCount <= 0 && mDownloadServiceActive == null
Amith Yamasanicb926fc2016-03-14 17:15:20 -07002018 && !mJobsActive && !mAlarmsActive) {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002019 final long now = SystemClock.elapsedRealtime();
2020 if (DEBUG) {
2021 StringBuilder sb = new StringBuilder();
2022 sb.append("Exit: start=");
2023 TimeUtils.formatDuration(mMaintenanceStartTime, sb);
2024 sb.append(" now=");
2025 TimeUtils.formatDuration(now, sb);
2026 Slog.d(TAG, sb.toString());
2027 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002028 if (mState == STATE_IDLE_MAINTENANCE) {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002029 if (now >= (mMaintenanceStartTime + mConstants.MIN_DEEP_MAINTENANCE_TIME)) {
2030 stepIdleStateLocked("s:early");
2031 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002032 } else {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002033 if (now >= (mMaintenanceStartTime + mConstants.MIN_LIGHT_MAINTENANCE_TIME)) {
2034 stepLightIdleStateLocked("s:early");
2035 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002036 }
2037 }
2038 }
2039 }
2040
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002041 void motionLocked() {
2042 if (DEBUG) Slog.d(TAG, "motionLocked()");
2043 // The motion sensor will have been disabled at this point
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002044 handleMotionDetectedLocked(mConstants.MOTION_INACTIVE_TIMEOUT, "motion");
2045 }
2046
2047 void handleMotionDetectedLocked(long timeout, String type) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002048 // The device is not yet active, so we want to go back to the pending idle
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002049 // state to wait again for no motion. Note that we only monitor for motion
2050 // after moving out of the inactive state, so no need to worry about that.
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002051 boolean becomeInactive = false;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002052 if (mState != STATE_ACTIVE) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002053 scheduleReportActiveLocked(type, Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002054 mState = STATE_ACTIVE;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002055 mInactiveTimeout = timeout;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002056 mCurIdleBudget = 0;
2057 mMaintenanceStartTime = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002058 EventLogTags.writeDeviceIdle(mState, type);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002059 addEvent(EVENT_NORMAL);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002060 becomeInactive = true;
2061 }
2062 if (mLightState == LIGHT_STATE_OVERRIDE) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08002063 // We went out of light idle mode because we had started deep idle mode... let's
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002064 // now go back and reset things so we resume light idling if appropriate.
2065 mLightState = STATE_ACTIVE;
2066 EventLogTags.writeDeviceIdleLight(mLightState, type);
2067 becomeInactive = true;
2068 }
2069 if (becomeInactive) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002070 becomeInactiveIfAppropriateLocked();
2071 }
2072 }
2073
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002074 void receivedGenericLocationLocked(Location location) {
2075 if (mState != STATE_LOCATING) {
2076 cancelLocatingLocked();
2077 return;
2078 }
2079 if (DEBUG) Slog.d(TAG, "Generic location: " + location);
2080 mLastGenericLocation = new Location(location);
Joe LaPenna23d681b2015-08-27 15:12:11 -07002081 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHasGps) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002082 return;
2083 }
2084 mLocated = true;
2085 if (mNotMoving) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002086 stepIdleStateLocked("s:location");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002087 }
2088 }
2089
2090 void receivedGpsLocationLocked(Location location) {
2091 if (mState != STATE_LOCATING) {
2092 cancelLocatingLocked();
2093 return;
2094 }
2095 if (DEBUG) Slog.d(TAG, "GPS location: " + location);
2096 mLastGpsLocation = new Location(location);
2097 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY) {
2098 return;
2099 }
2100 mLocated = true;
2101 if (mNotMoving) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002102 stepIdleStateLocked("s:gps");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002103 }
2104 }
2105
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002106 void startMonitoringMotionLocked() {
2107 if (DEBUG) Slog.d(TAG, "startMonitoringMotionLocked()");
2108 if (mMotionSensor != null && !mMotionListener.active) {
2109 mMotionListener.registerLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002110 }
2111 }
2112
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002113 void stopMonitoringMotionLocked() {
2114 if (DEBUG) Slog.d(TAG, "stopMonitoringMotionLocked()");
2115 if (mMotionSensor != null && mMotionListener.active) {
2116 mMotionListener.unregisterLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002117 }
2118 }
2119
2120 void cancelAlarmLocked() {
2121 if (mNextAlarmTime != 0) {
2122 mNextAlarmTime = 0;
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002123 mAlarmManager.cancel(mDeepAlarmListener);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002124 }
2125 }
2126
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002127 void cancelLightAlarmLocked() {
2128 if (mNextLightAlarmTime != 0) {
2129 mNextLightAlarmTime = 0;
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002130 mAlarmManager.cancel(mLightAlarmListener);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002131 }
2132 }
2133
2134 void cancelLocatingLocked() {
2135 if (mLocating) {
2136 mLocationManager.removeUpdates(mGenericLocationListener);
2137 mLocationManager.removeUpdates(mGpsLocationListener);
2138 mLocating = false;
2139 }
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002140 }
2141
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002142 void scheduleAlarmLocked(long delay, boolean idleUntil) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002143 if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")");
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002144 if (mMotionSensor == null) {
Joe LaPenna23d681b2015-08-27 15:12:11 -07002145 // If there is no motion sensor on this device, then we won't schedule
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002146 // alarms, because we can't determine if the device is not moving. This effectively
Joe LaPenna23d681b2015-08-27 15:12:11 -07002147 // turns off normal execution of device idling, although it is still possible to
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002148 // manually poke it by pretending like the alarm is going off.
2149 return;
2150 }
2151 mNextAlarmTime = SystemClock.elapsedRealtime() + delay;
2152 if (idleUntil) {
2153 mAlarmManager.setIdleUntil(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002154 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002155 } else {
2156 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002157 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002158 }
2159 }
2160
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002161 void scheduleLightAlarmLocked(long delay) {
2162 if (DEBUG) Slog.d(TAG, "scheduleLightAlarmLocked(" + delay + ")");
2163 if (mMotionSensor == null) {
2164 // If there is no motion sensor on this device, then we won't schedule
2165 // alarms, because we can't determine if the device is not moving. This effectively
2166 // turns off normal execution of device idling, although it is still possible to
2167 // manually poke it by pretending like the alarm is going off.
2168 return;
2169 }
2170 mNextLightAlarmTime = SystemClock.elapsedRealtime() + delay;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002171 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002172 mNextLightAlarmTime, "DeviceIdleController.light", mLightAlarmListener, mHandler);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002173 }
2174
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002175 private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps,
2176 ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds) {
2177 outAppIds.clear();
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002178 if (systemApps != null) {
2179 for (int i = 0; i < systemApps.size(); i++) {
2180 outAppIds.put(systemApps.valueAt(i), true);
2181 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002182 }
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002183 if (userApps != null) {
2184 for (int i = 0; i < userApps.size(); i++) {
2185 outAppIds.put(userApps.valueAt(i), true);
2186 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002187 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002188 int size = outAppIds.size();
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002189 int[] appids = new int[size];
2190 for (int i = 0; i < size; i++) {
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002191 appids[i] = outAppIds.keyAt(i);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002192 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002193 return appids;
2194 }
2195
2196 private void updateWhitelistAppIdsLocked() {
2197 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(mPowerSaveWhitelistAppsExceptIdle,
2198 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistExceptIdleAppIds);
2199 mPowerSaveWhitelistAllAppIdArray = buildAppIdArray(mPowerSaveWhitelistApps,
2200 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistAllAppIds);
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002201 mPowerSaveWhitelistUserAppIdArray = buildAppIdArray(null,
2202 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistUserAppIds);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002203 if (mLocalPowerManager != null) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002204 if (DEBUG) {
2205 Slog.d(TAG, "Setting wakelock whitelist to "
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002206 + Arrays.toString(mPowerSaveWhitelistAllAppIdArray));
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002207 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002208 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002209 }
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002210 if (mLocalAlarmManager != null) {
2211 if (DEBUG) {
2212 Slog.d(TAG, "Setting alarm whitelist to "
2213 + Arrays.toString(mPowerSaveWhitelistUserAppIdArray));
2214 }
2215 mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray);
2216 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002217 }
2218
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002219 private void updateTempWhitelistAppIdsLocked() {
2220 final int size = mTempWhitelistAppIdEndTimes.size();
2221 if (mTempWhitelistAppIdArray.length != size) {
2222 mTempWhitelistAppIdArray = new int[size];
2223 }
2224 for (int i = 0; i < size; i++) {
2225 mTempWhitelistAppIdArray[i] = mTempWhitelistAppIdEndTimes.keyAt(i);
2226 }
2227 if (mLocalPowerManager != null) {
2228 if (DEBUG) {
2229 Slog.d(TAG, "Setting wakelock temp whitelist to "
2230 + Arrays.toString(mTempWhitelistAppIdArray));
2231 }
2232 mLocalPowerManager.setDeviceIdleTempWhitelist(mTempWhitelistAppIdArray);
2233 }
2234 }
2235
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002236 private void reportPowerSaveWhitelistChangedLocked() {
2237 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
2238 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Xiaohui Chene4de5a02015-09-22 15:33:31 -07002239 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002240 }
2241
2242 private void reportTempWhitelistChangedLocked() {
2243 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED);
2244 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Xiaohui Chene4de5a02015-09-22 15:33:31 -07002245 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002246 }
2247
2248 void readConfigFileLocked() {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002249 if (DEBUG) Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002250 mPowerSaveWhitelistUserApps.clear();
2251 FileInputStream stream;
2252 try {
2253 stream = mConfigFile.openRead();
2254 } catch (FileNotFoundException e) {
2255 return;
2256 }
2257 try {
2258 XmlPullParser parser = Xml.newPullParser();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01002259 parser.setInput(stream, StandardCharsets.UTF_8.name());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002260 readConfigFileLocked(parser);
2261 } catch (XmlPullParserException e) {
2262 } finally {
2263 try {
2264 stream.close();
2265 } catch (IOException e) {
2266 }
2267 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002268 }
2269
2270 private void readConfigFileLocked(XmlPullParser parser) {
2271 final PackageManager pm = getContext().getPackageManager();
2272
2273 try {
2274 int type;
2275 while ((type = parser.next()) != XmlPullParser.START_TAG
2276 && type != XmlPullParser.END_DOCUMENT) {
2277 ;
2278 }
2279
2280 if (type != XmlPullParser.START_TAG) {
2281 throw new IllegalStateException("no start tag found");
2282 }
2283
2284 int outerDepth = parser.getDepth();
2285 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2286 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2287 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2288 continue;
2289 }
2290
2291 String tagName = parser.getName();
2292 if (tagName.equals("wl")) {
2293 String name = parser.getAttributeValue(null, "n");
2294 if (name != null) {
2295 try {
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07002296 ApplicationInfo ai = pm.getApplicationInfo(name,
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07002297 PackageManager.MATCH_UNINSTALLED_PACKAGES);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002298 mPowerSaveWhitelistUserApps.put(ai.packageName,
2299 UserHandle.getAppId(ai.uid));
2300 } catch (PackageManager.NameNotFoundException e) {
2301 }
2302 }
2303 } else {
2304 Slog.w(TAG, "Unknown element under <config>: "
2305 + parser.getName());
2306 XmlUtils.skipCurrentTag(parser);
2307 }
2308 }
2309
2310 } catch (IllegalStateException e) {
2311 Slog.w(TAG, "Failed parsing config " + e);
2312 } catch (NullPointerException e) {
2313 Slog.w(TAG, "Failed parsing config " + e);
2314 } catch (NumberFormatException e) {
2315 Slog.w(TAG, "Failed parsing config " + e);
2316 } catch (XmlPullParserException e) {
2317 Slog.w(TAG, "Failed parsing config " + e);
2318 } catch (IOException e) {
2319 Slog.w(TAG, "Failed parsing config " + e);
2320 } catch (IndexOutOfBoundsException e) {
2321 Slog.w(TAG, "Failed parsing config " + e);
2322 }
2323 }
2324
2325 void writeConfigFileLocked() {
2326 mHandler.removeMessages(MSG_WRITE_CONFIG);
2327 mHandler.sendEmptyMessageDelayed(MSG_WRITE_CONFIG, 5000);
2328 }
2329
2330 void handleWriteConfigFile() {
2331 final ByteArrayOutputStream memStream = new ByteArrayOutputStream();
2332
2333 try {
2334 synchronized (this) {
2335 XmlSerializer out = new FastXmlSerializer();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01002336 out.setOutput(memStream, StandardCharsets.UTF_8.name());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002337 writeConfigFileLocked(out);
2338 }
2339 } catch (IOException e) {
2340 }
2341
2342 synchronized (mConfigFile) {
2343 FileOutputStream stream = null;
2344 try {
2345 stream = mConfigFile.startWrite();
2346 memStream.writeTo(stream);
2347 stream.flush();
2348 FileUtils.sync(stream);
2349 stream.close();
2350 mConfigFile.finishWrite(stream);
2351 } catch (IOException e) {
2352 Slog.w(TAG, "Error writing config file", e);
2353 mConfigFile.failWrite(stream);
2354 }
2355 }
2356 }
2357
2358 void writeConfigFileLocked(XmlSerializer out) throws IOException {
2359 out.startDocument(null, true);
2360 out.startTag(null, "config");
2361 for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) {
2362 String name = mPowerSaveWhitelistUserApps.keyAt(i);
2363 out.startTag(null, "wl");
2364 out.attribute(null, "n", name);
2365 out.endTag(null, "wl");
2366 }
2367 out.endTag(null, "config");
2368 out.endDocument();
2369 }
2370
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002371 static void dumpHelp(PrintWriter pw) {
2372 pw.println("Device idle controller (deviceidle) commands:");
2373 pw.println(" help");
2374 pw.println(" Print this help text.");
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002375 pw.println(" step [light|deep]");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002376 pw.println(" Immediately step to next state, without waiting for alarm.");
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002377 pw.println(" force-idle");
2378 pw.println(" Force directly into idle mode, regardless of other device state.");
2379 pw.println(" Use \"step\" to get out.");
Dianne Hackbornb6843652016-02-22 12:20:13 -08002380 pw.println(" disable [light|deep|all]");
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002381 pw.println(" Completely disable device idle mode.");
Dianne Hackbornb6843652016-02-22 12:20:13 -08002382 pw.println(" enable [light|deep|all]");
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002383 pw.println(" Re-enable device idle mode after it had previously been disabled.");
Dianne Hackbornb6843652016-02-22 12:20:13 -08002384 pw.println(" enabled [light|deep|all]");
Dianne Hackborn92617032015-06-19 15:32:19 -07002385 pw.println(" Print 1 if device idle mode is currently enabled, else 0.");
Dianne Hackborn1b139682015-07-06 15:13:37 -07002386 pw.println(" whitelist");
2387 pw.println(" Print currently whitelisted apps.");
Dianne Hackborn92617032015-06-19 15:32:19 -07002388 pw.println(" whitelist [package ...]");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002389 pw.println(" Add (prefix with +) or remove (prefix with -) packages.");
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002390 pw.println(" tempwhitelist [-u] [package ..]");
Dianne Hackborn92617032015-06-19 15:32:19 -07002391 pw.println(" Temporarily place packages in whitelist for 10 seconds.");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002392 }
2393
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002394 class Shell extends ShellCommand {
2395 int userId = UserHandle.USER_SYSTEM;
2396
2397 @Override
2398 public int onCommand(String cmd) {
2399 return onShellCommand(this, cmd);
2400 }
2401
2402 @Override
2403 public void onHelp() {
2404 PrintWriter pw = getOutPrintWriter();
2405 dumpHelp(pw);
2406 }
2407 }
2408
2409 int onShellCommand(Shell shell, String cmd) {
2410 PrintWriter pw = shell.getOutPrintWriter();
2411 if ("step".equals(cmd)) {
2412 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
2413 null);
2414 synchronized (this) {
2415 long token = Binder.clearCallingIdentity();
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002416 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002417 try {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002418 if (arg == null || "deep".equals(arg)) {
2419 exitForceIdleLocked();
2420 stepIdleStateLocked("s:shell");
2421 pw.print("Stepped to deep: ");
2422 pw.println(stateToString(mState));
2423 } else if ("light".equals(arg)) {
2424 exitForceIdleLocked();
2425 stepLightIdleStateLocked("s:shell");
2426 pw.print("Stepped to light: "); pw.println(lightStateToString(mLightState));
2427 } else {
2428 pw.println("Unknown idle mode: " + arg);
2429 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002430 } finally {
2431 Binder.restoreCallingIdentity(token);
2432 }
2433 }
2434 } else if ("force-idle".equals(cmd)) {
2435 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
2436 null);
2437 synchronized (this) {
2438 long token = Binder.clearCallingIdentity();
2439 try {
Dianne Hackbornb6843652016-02-22 12:20:13 -08002440 if (!mDeepEnabled) {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002441 pw.println("Unable to go idle; not enabled");
2442 return -1;
2443 }
2444 mForceIdle = true;
2445 becomeInactiveIfAppropriateLocked();
2446 int curState = mState;
2447 while (curState != STATE_IDLE) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002448 stepIdleStateLocked("s:shell");
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002449 if (curState == mState) {
2450 pw.print("Unable to go idle; stopped at ");
2451 pw.println(stateToString(mState));
2452 exitForceIdleLocked();
2453 return -1;
2454 }
2455 curState = mState;
2456 }
2457 pw.println("Now forced in to idle mode");
2458 } finally {
2459 Binder.restoreCallingIdentity(token);
2460 }
2461 }
2462 } else if ("disable".equals(cmd)) {
2463 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
2464 null);
2465 synchronized (this) {
2466 long token = Binder.clearCallingIdentity();
Dianne Hackbornb6843652016-02-22 12:20:13 -08002467 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002468 try {
Dianne Hackbornb6843652016-02-22 12:20:13 -08002469 boolean becomeActive = false;
2470 boolean valid = false;
2471 if (arg == null || "deep".equals(arg) || "all".equals(arg)) {
2472 valid = true;
2473 if (mDeepEnabled) {
2474 mDeepEnabled = false;
2475 becomeActive = true;
2476 pw.println("Deep idle mode disabled");
2477 }
2478 }
2479 if (arg == null || "light".equals(arg) || "all".equals(arg)) {
2480 valid = true;
2481 if (mLightEnabled) {
2482 mLightEnabled = false;
2483 becomeActive = true;
2484 pw.println("Light idle mode disabled");
2485 }
2486 }
2487 if (becomeActive) {
2488 becomeActiveLocked((arg == null ? "all" : arg) + "-disabled",
2489 Process.myUid());
2490 }
2491 if (!valid) {
2492 pw.println("Unknown idle mode: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002493 }
2494 } finally {
2495 Binder.restoreCallingIdentity(token);
2496 }
2497 }
2498 } else if ("enable".equals(cmd)) {
2499 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
2500 null);
2501 synchronized (this) {
2502 long token = Binder.clearCallingIdentity();
Dianne Hackbornb6843652016-02-22 12:20:13 -08002503 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002504 try {
Dianne Hackbornb6843652016-02-22 12:20:13 -08002505 boolean becomeInactive = false;
2506 boolean valid = false;
2507 if (arg == null || "deep".equals(arg) || "all".equals(arg)) {
2508 valid = true;
2509 if (!mDeepEnabled) {
2510 mDeepEnabled = true;
2511 becomeInactive = true;
2512 pw.println("Deep idle mode enabled");
2513 }
2514 }
2515 if (arg == null || "light".equals(arg) || "all".equals(arg)) {
2516 valid = true;
2517 if (!mLightEnabled) {
2518 mLightEnabled = true;
2519 becomeInactive = true;
2520 pw.println("Light idle mode enable");
2521 }
2522 }
2523 if (becomeInactive) {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002524 becomeInactiveIfAppropriateLocked();
Dianne Hackbornb6843652016-02-22 12:20:13 -08002525 }
2526 if (!valid) {
2527 pw.println("Unknown idle mode: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002528 }
2529 } finally {
2530 Binder.restoreCallingIdentity(token);
2531 }
2532 }
2533 } else if ("enabled".equals(cmd)) {
2534 synchronized (this) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08002535 String arg = shell.getNextArg();
2536 if (arg == null || "all".equals(arg)) {
2537 pw.println(mDeepEnabled && mLightEnabled ? "1" : 0);
2538 } else if ("deep".equals(arg)) {
2539 pw.println(mDeepEnabled ? "1" : 0);
2540 } else if ("light".equals(arg)) {
2541 pw.println(mLightEnabled ? "1" : 0);
2542 } else {
2543 pw.println("Unknown idle mode: " + arg);
2544 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002545 }
2546 } else if ("whitelist".equals(cmd)) {
2547 long token = Binder.clearCallingIdentity();
2548 try {
2549 String arg = shell.getNextArg();
2550 if (arg != null) {
2551 getContext().enforceCallingOrSelfPermission(
2552 android.Manifest.permission.DEVICE_POWER, null);
2553 do {
2554 if (arg.length() < 1 || (arg.charAt(0) != '-'
Felipe Lemef8a46232016-02-10 13:51:54 -08002555 && arg.charAt(0) != '+' && arg.charAt(0) != '=')) {
2556 pw.println("Package must be prefixed with +, -, or =: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002557 return -1;
2558 }
2559 char op = arg.charAt(0);
2560 String pkg = arg.substring(1);
2561 if (op == '+') {
2562 if (addPowerSaveWhitelistAppInternal(pkg)) {
2563 pw.println("Added: " + pkg);
2564 } else {
2565 pw.println("Unknown package: " + pkg);
2566 }
Felipe Lemef8a46232016-02-10 13:51:54 -08002567 } else if (op == '-') {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002568 if (removePowerSaveWhitelistAppInternal(pkg)) {
2569 pw.println("Removed: " + pkg);
2570 }
Felipe Lemef8a46232016-02-10 13:51:54 -08002571 } else {
2572 pw.println(getPowerSaveWhitelistAppInternal(pkg));
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002573 }
2574 } while ((arg=shell.getNextArg()) != null);
2575 } else {
2576 synchronized (this) {
2577 for (int j=0; j<mPowerSaveWhitelistAppsExceptIdle.size(); j++) {
2578 pw.print("system-excidle,");
2579 pw.print(mPowerSaveWhitelistAppsExceptIdle.keyAt(j));
2580 pw.print(",");
2581 pw.println(mPowerSaveWhitelistAppsExceptIdle.valueAt(j));
2582 }
2583 for (int j=0; j<mPowerSaveWhitelistApps.size(); j++) {
2584 pw.print("system,");
2585 pw.print(mPowerSaveWhitelistApps.keyAt(j));
2586 pw.print(",");
2587 pw.println(mPowerSaveWhitelistApps.valueAt(j));
2588 }
2589 for (int j=0; j<mPowerSaveWhitelistUserApps.size(); j++) {
2590 pw.print("user,");
2591 pw.print(mPowerSaveWhitelistUserApps.keyAt(j));
2592 pw.print(",");
2593 pw.println(mPowerSaveWhitelistUserApps.valueAt(j));
2594 }
2595 }
2596 }
2597 } finally {
2598 Binder.restoreCallingIdentity(token);
2599 }
2600 } else if ("tempwhitelist".equals(cmd)) {
2601 String opt;
2602 while ((opt=shell.getNextOption()) != null) {
2603 if ("-u".equals(opt)) {
2604 opt = shell.getNextArg();
2605 if (opt == null) {
2606 pw.println("-u requires a user number");
2607 return -1;
2608 }
2609 shell.userId = Integer.parseInt(opt);
2610 }
2611 }
2612 String arg = shell.getNextArg();
2613 if (arg != null) {
2614 try {
2615 addPowerSaveTempWhitelistAppChecked(arg, 10000L, shell.userId, "shell");
2616 } catch (RemoteException re) {
2617 pw.println("Failed: " + re);
2618 }
2619 } else {
2620 pw.println("At least one package name must be specified");
2621 return -1;
2622 }
2623 } else {
2624 return shell.handleDefaultCommands(cmd);
2625 }
2626 return 0;
2627 }
2628
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002629 void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2630 if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
2631 != PackageManager.PERMISSION_GRANTED) {
2632 pw.println("Permission Denial: can't dump DeviceIdleController from from pid="
2633 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2634 + " without permission " + android.Manifest.permission.DUMP);
2635 return;
2636 }
2637
2638 if (args != null) {
Xiaohui Chen7c696362015-09-16 09:56:14 -07002639 int userId = UserHandle.USER_SYSTEM;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002640 for (int i=0; i<args.length; i++) {
2641 String arg = args[i];
2642 if ("-h".equals(arg)) {
2643 dumpHelp(pw);
2644 return;
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002645 } else if ("-u".equals(arg)) {
2646 i++;
2647 if (i < args.length) {
2648 arg = args[i];
2649 userId = Integer.parseInt(arg);
2650 }
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002651 } else if ("-a".equals(arg)) {
2652 // Ignore, we always dump all.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002653 } else if (arg.length() > 0 && arg.charAt(0) == '-'){
2654 pw.println("Unknown option: " + arg);
2655 return;
2656 } else {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002657 Shell shell = new Shell();
2658 shell.userId = userId;
2659 String[] newArgs = new String[args.length-i];
2660 System.arraycopy(args, i, newArgs, 0, args.length-i);
2661 shell.exec(mBinderService, null, fd, null, newArgs, new ResultReceiver(null));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002662 return;
2663 }
2664 }
2665 }
2666
2667 synchronized (this) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002668 mConstants.dump(pw);
2669
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002670 if (mEventCmds[0] != EVENT_NULL) {
2671 pw.println(" Idling history:");
2672 long now = SystemClock.elapsedRealtime();
2673 for (int i=EVENT_BUFFER_SIZE-1; i>=0; i--) {
2674 int cmd = mEventCmds[i];
2675 if (cmd == EVENT_NULL) {
2676 continue;
2677 }
2678 String label;
2679 switch (mEventCmds[i]) {
2680 case EVENT_NORMAL: label = " normal"; break;
2681 case EVENT_LIGHT_IDLE: label = " light-idle"; break;
2682 case EVENT_LIGHT_MAINTENANCE: label = "light-maint"; break;
Dianne Hackbornb6843652016-02-22 12:20:13 -08002683 case EVENT_DEEP_IDLE: label = " deep-idle"; break;
2684 case EVENT_DEEP_MAINTENANCE: label = " deep-maint"; break;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002685 default: label = " ??"; break;
2686 }
2687 pw.print(" ");
2688 pw.print(label);
2689 pw.print(": ");
2690 TimeUtils.formatDuration(mEventTimes[i], now, pw);;
2691 pw.println();
2692 }
2693 }
2694
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002695 int size = mPowerSaveWhitelistAppsExceptIdle.size();
2696 if (size > 0) {
2697 pw.println(" Whitelist (except idle) system apps:");
2698 for (int i = 0; i < size; i++) {
2699 pw.print(" ");
2700 pw.println(mPowerSaveWhitelistAppsExceptIdle.keyAt(i));
2701 }
2702 }
2703 size = mPowerSaveWhitelistApps.size();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002704 if (size > 0) {
2705 pw.println(" Whitelist system apps:");
2706 for (int i = 0; i < size; i++) {
2707 pw.print(" ");
2708 pw.println(mPowerSaveWhitelistApps.keyAt(i));
2709 }
2710 }
2711 size = mPowerSaveWhitelistUserApps.size();
2712 if (size > 0) {
2713 pw.println(" Whitelist user apps:");
2714 for (int i = 0; i < size; i++) {
2715 pw.print(" ");
2716 pw.println(mPowerSaveWhitelistUserApps.keyAt(i));
2717 }
2718 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002719 size = mPowerSaveWhitelistExceptIdleAppIds.size();
2720 if (size > 0) {
2721 pw.println(" Whitelist (except idle) all app ids:");
2722 for (int i = 0; i < size; i++) {
2723 pw.print(" ");
2724 pw.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
2725 pw.println();
2726 }
2727 }
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002728 size = mPowerSaveWhitelistUserAppIds.size();
2729 if (size > 0) {
2730 pw.println(" Whitelist user app ids:");
2731 for (int i = 0; i < size; i++) {
2732 pw.print(" ");
2733 pw.print(mPowerSaveWhitelistUserAppIds.keyAt(i));
2734 pw.println();
2735 }
2736 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002737 size = mPowerSaveWhitelistAllAppIds.size();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002738 if (size > 0) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002739 pw.println(" Whitelist all app ids:");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002740 for (int i = 0; i < size; i++) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002741 pw.print(" ");
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002742 pw.print(mPowerSaveWhitelistAllAppIds.keyAt(i));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002743 pw.println();
2744 }
2745 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002746 size = mTempWhitelistAppIdEndTimes.size();
2747 if (size > 0) {
2748 pw.println(" Temp whitelist schedule:");
2749 final long timeNow = SystemClock.elapsedRealtime();
2750 for (int i = 0; i < size; i++) {
2751 pw.print(" UID=");
2752 pw.print(mTempWhitelistAppIdEndTimes.keyAt(i));
2753 pw.print(": ");
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002754 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.valueAt(i);
2755 TimeUtils.formatDuration(entry.first.value, timeNow, pw);
2756 pw.print(" - ");
2757 pw.println(entry.second);
Dianne Hackborna750a632015-06-16 17:18:23 -07002758 }
2759 }
2760 size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0;
2761 if (size > 0) {
2762 pw.println(" Temp whitelist app ids:");
2763 for (int i = 0; i < size; i++) {
2764 pw.print(" ");
2765 pw.print(mTempWhitelistAppIdArray[i]);
2766 pw.println();
2767 }
2768 }
Adam Lesinski31c05d12015-06-09 17:34:04 -07002769
Dianne Hackbornb6843652016-02-22 12:20:13 -08002770 pw.print(" mLightEnabled="); pw.print(mLightEnabled);
2771 pw.print(" mDeepEnabled="); pw.println(mDeepEnabled);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002772 pw.print(" mForceIdle="); pw.println(mForceIdle);
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002773 pw.print(" mMotionSensor="); pw.println(mMotionSensor);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002774 pw.print(" mCurDisplay="); pw.println(mCurDisplay);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002775 pw.print(" mScreenOn="); pw.println(mScreenOn);
2776 pw.print(" mCharging="); pw.println(mCharging);
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002777 pw.print(" mMotionActive="); pw.println(mMotionListener.active);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002778 pw.print(" mNotMoving="); pw.println(mNotMoving);
Joe LaPenna23d681b2015-08-27 15:12:11 -07002779 pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHasGps=");
2780 pw.print(mHasGps); pw.print(" mHasNetwork=");
2781 pw.print(mHasNetworkLocation); pw.print(" mLocated="); pw.println(mLocated);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002782 if (mLastGenericLocation != null) {
2783 pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation);
2784 }
2785 if (mLastGpsLocation != null) {
2786 pw.print(" mLastGpsLocation="); pw.println(mLastGpsLocation);
2787 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002788 pw.print(" mState="); pw.print(stateToString(mState));
2789 pw.print(" mLightState=");
2790 pw.println(lightStateToString(mLightState));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002791 pw.print(" mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw);
2792 pw.println();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002793 if (mActiveIdleOpCount != 0) {
2794 pw.print(" mActiveIdleOpCount="); pw.println(mActiveIdleOpCount);
2795 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002796 if (mNextAlarmTime != 0) {
2797 pw.print(" mNextAlarmTime=");
2798 TimeUtils.formatDuration(mNextAlarmTime, SystemClock.elapsedRealtime(), pw);
2799 pw.println();
2800 }
2801 if (mNextIdlePendingDelay != 0) {
2802 pw.print(" mNextIdlePendingDelay=");
2803 TimeUtils.formatDuration(mNextIdlePendingDelay, pw);
2804 pw.println();
2805 }
2806 if (mNextIdleDelay != 0) {
2807 pw.print(" mNextIdleDelay=");
2808 TimeUtils.formatDuration(mNextIdleDelay, pw);
2809 pw.println();
2810 }
Dianne Hackborn953fc942016-03-29 15:36:24 -07002811 if (mNextLightIdleDelay != 0) {
2812 pw.print(" mNextIdleDelay=");
2813 TimeUtils.formatDuration(mNextLightIdleDelay, pw);
2814 pw.println();
2815 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002816 if (mNextLightAlarmTime != 0) {
2817 pw.print(" mNextLightAlarmTime=");
2818 TimeUtils.formatDuration(mNextLightAlarmTime, SystemClock.elapsedRealtime(), pw);
2819 pw.println();
2820 }
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002821 if (mCurIdleBudget != 0) {
2822 pw.print(" mCurIdleBudget=");
2823 TimeUtils.formatDuration(mCurIdleBudget, pw);
2824 pw.println();
2825 }
2826 if (mMaintenanceStartTime != 0) {
2827 pw.print(" mMaintenanceStartTime=");
2828 TimeUtils.formatDuration(mMaintenanceStartTime, SystemClock.elapsedRealtime(), pw);
2829 pw.println();
2830 }
Dianne Hackborn953fc942016-03-29 15:36:24 -07002831 if (mMaintenanceMinCheckScheduled) {
2832 pw.print(" mMaintenanceMinCheckScheduled=");
2833 pw.println(mMaintenanceMinCheckScheduled);
2834 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002835 if (mJobsActive) {
2836 pw.print(" mJobsActive="); pw.println(mJobsActive);
2837 }
2838 if (mAlarmsActive) {
2839 pw.print(" mAlarmsActive="); pw.println(mAlarmsActive);
2840 }
2841 if (mDownloadServiceActive != null) {
2842 pw.print(" mDownloadServiceActive="); pw.println(mDownloadServiceActive);
2843 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002844 }
2845 }
2846}