blob: 6c19c3845bfb44956629055167d36caff32563dc [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;
22import android.app.PendingIntent;
23import android.content.BroadcastReceiver;
Adam Lesinski31c05d12015-06-09 17:34:04 -070024import android.content.ContentResolver;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070025import android.content.Context;
26import android.content.Intent;
27import android.content.IntentFilter;
28import android.content.pm.ApplicationInfo;
29import android.content.pm.PackageManager;
Amith Yamasaniaf575b92015-05-29 15:35:26 -070030import android.content.pm.PackageManager.NameNotFoundException;
Adam Lesinski31c05d12015-06-09 17:34:04 -070031import android.database.ContentObserver;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070032import android.hardware.Sensor;
33import android.hardware.SensorManager;
Nick Vaccaro20feaea2015-09-17 17:22:44 -070034import android.hardware.SensorEvent;
35import android.hardware.SensorEventListener;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070036import android.hardware.TriggerEvent;
37import android.hardware.TriggerEventListener;
38import android.hardware.display.DisplayManager;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -070039import android.location.LocationRequest;
40import android.location.Location;
41import android.location.LocationListener;
42import android.location.LocationManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070043import android.net.INetworkPolicyManager;
Adam Lesinski31c05d12015-06-09 17:34:04 -070044import android.net.Uri;
Dianne Hackbornfd854ee2015-07-13 18:00:37 -070045import android.os.BatteryStats;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070046import android.os.Binder;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -070047import android.os.Bundle;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070048import android.os.Environment;
49import android.os.FileUtils;
50import android.os.Handler;
Dianne Hackborn627dfa12015-11-11 18:10:30 -080051import android.os.IBinder;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070052import android.os.IDeviceIdleController;
Yao Chenca5edbb2016-01-13 14:44:36 -080053import android.os.IMaintenanceActivityListener;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070054import android.os.Looper;
55import android.os.Message;
56import android.os.PowerManager;
57import android.os.PowerManagerInternal;
Dianne Hackbornb6683c42015-06-18 17:40:33 -070058import android.os.Process;
Yao Chenca5edbb2016-01-13 14:44:36 -080059import android.os.RemoteCallbackList;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070060import android.os.RemoteException;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070061import android.os.ResultReceiver;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070062import android.os.ServiceManager;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070063import android.os.ShellCommand;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070064import android.os.SystemClock;
65import android.os.UserHandle;
Adam Lesinski31c05d12015-06-09 17:34:04 -070066import android.provider.Settings;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070067import android.util.ArrayMap;
68import android.util.ArraySet;
Adam Lesinski31c05d12015-06-09 17:34:04 -070069import android.util.KeyValueListParser;
Dianne Hackbornfd854ee2015-07-13 18:00:37 -070070import android.util.MutableLong;
71import android.util.Pair;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070072import android.util.Slog;
Dianne Hackbornfd854ee2015-07-13 18:00:37 -070073import android.util.SparseArray;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070074import android.util.SparseBooleanArray;
75import android.util.TimeUtils;
76import android.util.Xml;
77import android.view.Display;
Amith Yamasani520d8f22015-05-08 16:36:21 -070078
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070079import com.android.internal.app.IBatteryStats;
80import com.android.internal.os.AtomicFile;
81import com.android.internal.os.BackgroundThread;
82import com.android.internal.util.FastXmlSerializer;
83import com.android.internal.util.XmlUtils;
84import com.android.server.am.BatteryStatsService;
Amith Yamasani520d8f22015-05-08 16:36:21 -070085
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070086import org.xmlpull.v1.XmlPullParser;
87import org.xmlpull.v1.XmlPullParserException;
88import org.xmlpull.v1.XmlSerializer;
89
90import java.io.ByteArrayOutputStream;
91import java.io.File;
92import java.io.FileDescriptor;
93import java.io.FileInputStream;
94import java.io.FileNotFoundException;
95import java.io.FileOutputStream;
96import java.io.IOException;
97import java.io.PrintWriter;
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +010098import java.nio.charset.StandardCharsets;
Amith Yamasaniaf575b92015-05-29 15:35:26 -070099import java.util.Arrays;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700100
101/**
102 * Keeps track of device idleness and drives low power mode based on that.
103 */
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700104public class DeviceIdleController extends SystemService
105 implements AnyMotionDetector.DeviceIdleCallback {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700106 private static final String TAG = "DeviceIdleController";
107
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700108 private static final boolean DEBUG = false;
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700109
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700110 private static final boolean COMPRESS_TIME = false;
Amith Yamasani520d8f22015-05-08 16:36:21 -0700111
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800112 private static final int EVENT_BUFFER_SIZE = 40;
113
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700114 private static final String ACTION_STEP_IDLE_STATE =
115 "com.android.server.device_idle.STEP_IDLE_STATE";
116
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700117 private static final String ACTION_STEP_LIGHT_IDLE_STATE =
118 "com.android.server.device_idle.STEP_LIGHT_IDLE_STATE";
119
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700120 private AlarmManager mAlarmManager;
121 private IBatteryStats mBatteryStats;
122 private PowerManagerInternal mLocalPowerManager;
123 private INetworkPolicyManager mNetworkPolicyManager;
124 private DisplayManager mDisplayManager;
125 private SensorManager mSensorManager;
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700126 private Sensor mMotionSensor;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700127 private LocationManager mLocationManager;
128 private LocationRequest mLocationRequest;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700129 private PendingIntent mAlarmIntent;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700130 private PendingIntent mLightAlarmIntent;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700131 private Intent mIdleIntent;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700132 private Intent mLightIdleIntent;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700133 private Display mCurDisplay;
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700134 private AnyMotionDetector mAnyMotionDetector;
Dianne Hackborn92617032015-06-19 15:32:19 -0700135 private boolean mEnabled;
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700136 private boolean mForceIdle;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700137 private boolean mScreenOn;
138 private boolean mCharging;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700139 private boolean mNotMoving;
140 private boolean mLocating;
141 private boolean mLocated;
Joe LaPenna23d681b2015-08-27 15:12:11 -0700142 private boolean mHasGps;
143 private boolean mHasNetworkLocation;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700144 private Location mLastGenericLocation;
145 private Location mLastGpsLocation;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700146
147 /** Device is currently active. */
148 private static final int STATE_ACTIVE = 0;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700149 /** Device is inactive (screen off, no motion) and we are waiting to for idle. */
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700150 private static final int STATE_INACTIVE = 1;
151 /** Device is past the initial inactive period, and waiting for the next idle period. */
152 private static final int STATE_IDLE_PENDING = 2;
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700153 /** Device is currently sensing motion. */
154 private static final int STATE_SENSING = 3;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700155 /** Device is currently finding location (and may still be sensing). */
156 private static final int STATE_LOCATING = 4;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700157 /** Device is in the idle state, trying to stay asleep as much as possible. */
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700158 private static final int STATE_IDLE = 5;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700159 /** Device is in the idle state, but temporarily out of idle to do regular maintenance. */
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700160 private static final int STATE_IDLE_MAINTENANCE = 6;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700161 private static String stateToString(int state) {
162 switch (state) {
163 case STATE_ACTIVE: return "ACTIVE";
164 case STATE_INACTIVE: return "INACTIVE";
165 case STATE_IDLE_PENDING: return "IDLE_PENDING";
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700166 case STATE_SENSING: return "SENSING";
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700167 case STATE_LOCATING: return "LOCATING";
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700168 case STATE_IDLE: return "IDLE";
169 case STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE";
170 default: return Integer.toString(state);
171 }
172 }
173
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700174 /** Device is currently active. */
175 private static final int LIGHT_STATE_ACTIVE = 0;
176 /** Device is inactive (screen off) and we are waiting to for the first light idle. */
177 private static final int LIGHT_STATE_INACTIVE = 1;
178 /** Device is in the light idle state, trying to stay asleep as much as possible. */
179 private static final int LIGHT_STATE_IDLE = 2;
180 /** Device is in the light idle state, but temporarily out of idle to do regular maintenance. */
181 private static final int LIGHT_STATE_IDLE_MAINTENANCE = 3;
182 /** Device light idle state is overriden, now applying full doze state. */
183 private static final int LIGHT_STATE_OVERRIDE = 4;
184 private static String lightStateToString(int state) {
185 switch (state) {
186 case LIGHT_STATE_ACTIVE: return "ACTIVE";
187 case LIGHT_STATE_INACTIVE: return "INACTIVE";
188 case LIGHT_STATE_IDLE: return "IDLE";
189 case LIGHT_STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE";
190 case LIGHT_STATE_OVERRIDE: return "OVERRIDE";
191 default: return Integer.toString(state);
192 }
193 }
194
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700195 private int mState;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700196 private int mLightState;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700197
198 private long mInactiveTimeout;
199 private long mNextAlarmTime;
200 private long mNextIdlePendingDelay;
201 private long mNextIdleDelay;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700202 private long mNextLightAlarmTime;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800203 private long mCurIdleBudget;
204 private long mMaintenanceStartTime;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700205
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800206 private int mActiveIdleOpCount;
207 private IBinder mDownloadServiceActive;
208 private boolean mSyncActive;
209 private boolean mJobsActive;
210 private boolean mAlarmsActive;
Yao Chenca5edbb2016-01-13 14:44:36 -0800211 private boolean mReportedMaintenanceActivity;
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800212
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700213 public final AtomicFile mConfigFile;
214
Yao Chenca5edbb2016-01-13 14:44:36 -0800215 private final RemoteCallbackList<IMaintenanceActivityListener> mMaintenanceActivityListeners =
216 new RemoteCallbackList<IMaintenanceActivityListener>();
217
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700218 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700219 * Package names the system has white-listed to opt out of power save restrictions,
220 * except for device idle mode.
221 */
222 private final ArrayMap<String, Integer> mPowerSaveWhitelistAppsExceptIdle = new ArrayMap<>();
223
224 /**
225 * Package names the system has white-listed to opt out of power save restrictions for
226 * all modes.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700227 */
228 private final ArrayMap<String, Integer> mPowerSaveWhitelistApps = new ArrayMap<>();
229
230 /**
231 * Package names the user has white-listed to opt out of power save restrictions.
232 */
233 private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>();
234
235 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700236 * App IDs of built-in system apps that have been white-listed except for idle modes.
237 */
238 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIdsExceptIdle
239 = new SparseBooleanArray();
240
241 /**
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700242 * App IDs of built-in system apps that have been white-listed.
243 */
244 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray();
245
246 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700247 * App IDs that have been white-listed to opt out of power save restrictions, except
248 * for device idle modes.
249 */
250 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
251
252 /**
253 * Current app IDs that are in the complete power save white list, but shouldn't be
254 * excluded from idle modes. This array can be shared with others because it will not be
255 * modified once set.
256 */
257 private int[] mPowerSaveWhitelistExceptIdleAppIdArray = new int[0];
258
259 /**
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700260 * App IDs that have been white-listed to opt out of power save restrictions.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700261 */
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700262 private final SparseBooleanArray mPowerSaveWhitelistAllAppIds = new SparseBooleanArray();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700263
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700264 /**
265 * Current app IDs that are in the complete power save white list. This array can
266 * be shared with others because it will not be modified once set.
267 */
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700268 private int[] mPowerSaveWhitelistAllAppIdArray = new int[0];
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700269
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700270 /**
271 * List of end times for UIDs that are temporarily marked as being allowed to access
272 * the network and acquire wakelocks. Times are in milliseconds.
273 */
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700274 private final SparseArray<Pair<MutableLong, String>> mTempWhitelistAppIdEndTimes
275 = new SparseArray<>();
276
277 /**
278 * Callback to the NetworkPolicyManagerService to tell it that the temp whitelist has changed.
279 */
280 Runnable mNetworkPolicyTempWhitelistCallback;
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700281
282 /**
283 * Current app IDs of temporarily whitelist apps for high-priority messages.
284 */
285 private int[] mTempWhitelistAppIdArray = new int[0];
286
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800287 private static final int EVENT_NULL = 0;
288 private static final int EVENT_NORMAL = 1;
289 private static final int EVENT_LIGHT_IDLE = 2;
290 private static final int EVENT_LIGHT_MAINTENANCE = 3;
291 private static final int EVENT_FULL_IDLE = 4;
292 private static final int EVENT_FULL_MAINTENANCE = 5;
293
294 private int[] mEventCmds = new int[EVENT_BUFFER_SIZE];
295 private long[] mEventTimes = new long[EVENT_BUFFER_SIZE];
296
297 private void addEvent(int cmd) {
298 if (mEventCmds[0] != cmd) {
299 System.arraycopy(mEventCmds, 0, mEventCmds, 1, EVENT_BUFFER_SIZE - 1);
300 System.arraycopy(mEventTimes, 0, mEventTimes, 1, EVENT_BUFFER_SIZE - 1);
301 mEventCmds[0] = cmd;
302 mEventTimes[0] = SystemClock.elapsedRealtime();
303 }
304 }
305
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700306 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
307 @Override public void onReceive(Context context, Intent intent) {
308 if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
309 int plugged = intent.getIntExtra("plugged", 0);
310 updateChargingLocked(plugged != 0);
Dianne Hackborn1b79ad72015-10-12 10:59:47 -0700311 } else if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
312 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
313 Uri data = intent.getData();
314 String ssp;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700315 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
Dianne Hackborn1b79ad72015-10-12 10:59:47 -0700316 removePowerSaveWhitelistAppInternal(ssp);
317 }
318 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700319 } else if (ACTION_STEP_LIGHT_IDLE_STATE.equals(intent.getAction())) {
320 synchronized (DeviceIdleController.this) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800321 stepLightIdleStateLocked("s:alarm");
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700322 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700323 } else if (ACTION_STEP_IDLE_STATE.equals(intent.getAction())) {
324 synchronized (DeviceIdleController.this) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800325 stepIdleStateLocked("s:alarm");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700326 }
327 }
328 }
329 };
330
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800331 private final BroadcastReceiver mIdleStartedDoneReceiver = new BroadcastReceiver() {
332 @Override public void onReceive(Context context, Intent intent) {
333 decActiveIdleOps();
334 }
335 };
336
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700337 private final DisplayManager.DisplayListener mDisplayListener
338 = new DisplayManager.DisplayListener() {
339 @Override public void onDisplayAdded(int displayId) {
340 }
341
342 @Override public void onDisplayRemoved(int displayId) {
343 }
344
345 @Override public void onDisplayChanged(int displayId) {
346 if (displayId == Display.DEFAULT_DISPLAY) {
347 synchronized (DeviceIdleController.this) {
348 updateDisplayLocked();
349 }
350 }
351 }
352 };
353
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700354 private final class MotionListener extends TriggerEventListener
355 implements SensorEventListener {
356
357 boolean active = false;
358
359 @Override
360 public void onTrigger(TriggerEvent event) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700361 synchronized (DeviceIdleController.this) {
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700362 active = false;
363 motionLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700364 }
365 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700366
367 @Override
368 public void onSensorChanged(SensorEvent event) {
369 synchronized (DeviceIdleController.this) {
370 mSensorManager.unregisterListener(this, mMotionSensor);
371 active = false;
372 motionLocked();
373 }
374 }
375
376 @Override
377 public void onAccuracyChanged(Sensor sensor, int accuracy) {}
378
379 public boolean registerLocked() {
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700380 boolean success;
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700381 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
382 success = mSensorManager.requestTriggerSensor(mMotionListener, mMotionSensor);
383 } else {
384 success = mSensorManager.registerListener(
385 mMotionListener, mMotionSensor, SensorManager.SENSOR_DELAY_NORMAL);
386 }
387 if (success) {
388 active = true;
389 } else {
390 Slog.e(TAG, "Unable to register for " + mMotionSensor);
391 }
392 return success;
393 }
394
395 public void unregisterLocked() {
396 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
397 mSensorManager.cancelTriggerSensor(mMotionListener, mMotionSensor);
398 } else {
399 mSensorManager.unregisterListener(mMotionListener);
400 }
401 active = false;
402 }
403 }
404 private final MotionListener mMotionListener = new MotionListener();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700405
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700406 private final LocationListener mGenericLocationListener = new LocationListener() {
407 @Override
408 public void onLocationChanged(Location location) {
409 synchronized (DeviceIdleController.this) {
410 receivedGenericLocationLocked(location);
411 }
412 }
413
414 @Override
415 public void onStatusChanged(String provider, int status, Bundle extras) {
416 }
417
418 @Override
419 public void onProviderEnabled(String provider) {
420 }
421
422 @Override
423 public void onProviderDisabled(String provider) {
424 }
425 };
426
427 private final LocationListener mGpsLocationListener = new LocationListener() {
428 @Override
429 public void onLocationChanged(Location location) {
430 synchronized (DeviceIdleController.this) {
431 receivedGpsLocationLocked(location);
432 }
433 }
434
435 @Override
436 public void onStatusChanged(String provider, int status, Bundle extras) {
437 }
438
439 @Override
440 public void onProviderEnabled(String provider) {
441 }
442
443 @Override
444 public void onProviderDisabled(String provider) {
445 }
446 };
447
Adam Lesinski31c05d12015-06-09 17:34:04 -0700448 /**
449 * All times are in milliseconds. These constants are kept synchronized with the system
450 * global Settings. Any access to this class or its fields should be done while
451 * holding the DeviceIdleController lock.
452 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700453 private final class Constants extends ContentObserver {
Adam Lesinski31c05d12015-06-09 17:34:04 -0700454 // Key names stored in the settings value.
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700455 private static final String KEY_LIGHT_IDLE_TIMEOUT = "light_idle_to";
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800456 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET
457 = "light_idle_maintenance_min_budget";
458 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET
459 = "light_idle_maintenance_max_budget";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700460 private static final String KEY_INACTIVE_TIMEOUT = "inactive_to";
461 private static final String KEY_SENSING_TIMEOUT = "sensing_to";
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700462 private static final String KEY_LOCATING_TIMEOUT = "locating_to";
463 private static final String KEY_LOCATION_ACCURACY = "location_accuracy";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700464 private static final String KEY_MOTION_INACTIVE_TIMEOUT = "motion_inactive_to";
465 private static final String KEY_IDLE_AFTER_INACTIVE_TIMEOUT = "idle_after_inactive_to";
466 private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to";
467 private static final String KEY_MAX_IDLE_PENDING_TIMEOUT = "max_idle_pending_to";
468 private static final String KEY_IDLE_PENDING_FACTOR = "idle_pending_factor";
469 private static final String KEY_IDLE_TIMEOUT = "idle_to";
470 private static final String KEY_MAX_IDLE_TIMEOUT = "max_idle_to";
471 private static final String KEY_IDLE_FACTOR = "idle_factor";
472 private static final String KEY_MIN_TIME_TO_ALARM = "min_time_to_alarm";
473 private static final String KEY_MAX_TEMP_APP_WHITELIST_DURATION =
474 "max_temp_app_whitelist_duration";
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700475 private static final String KEY_MMS_TEMP_APP_WHITELIST_DURATION =
476 "mms_temp_app_whitelist_duration";
Dianne Hackborn451c3462015-07-21 17:39:46 -0700477 private static final String KEY_SMS_TEMP_APP_WHITELIST_DURATION =
478 "sms_temp_app_whitelist_duration";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700479
480 /**
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700481 * This is the time, after becoming inactive, that we will start going
482 * in to light-weight idle mode.
483 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
484 * @see #KEY_LIGHT_IDLE_TIMEOUT
485 */
486 public long LIGHT_IDLE_TIMEOUT;
487
488 /**
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800489 * This is the minimum amount of time we want to make available for maintenance mode
490 * when lightly idling. That is, we will always have at least this amount of time
491 * available maintenance before timing out and cutting off maintenance mode.
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700492 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800493 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700494 */
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800495 public long LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
496
497 /**
498 * This is the maximum amount of time we want to make available for maintenance mode
499 * when lightly idling. That is, if the system isn't using up its minimum maintenance
500 * budget and this time is being added to the budget reserve, this is the maximum
501 * reserve size we will allow to grow and thus the maximum amount of time we will
502 * allow for the maintenance window.
503 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
504 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET
505 */
506 public long LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700507
508 /**
Adam Lesinski31c05d12015-06-09 17:34:04 -0700509 * This is the time, after becoming inactive, at which we start looking at the
510 * motion sensor to determine if the device is being left alone. We don't do this
511 * immediately after going inactive just because we don't want to be continually running
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700512 * the motion sensor whenever the screen is off.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700513 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
514 * @see #KEY_INACTIVE_TIMEOUT
515 */
516 public long INACTIVE_TIMEOUT;
517
518 /**
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700519 * If we don't receive a callback from AnyMotion in this amount of time +
520 * {@link #LOCATING_TIMEOUT}, we will change from
Adam Lesinski31c05d12015-06-09 17:34:04 -0700521 * STATE_SENSING to STATE_INACTIVE, and any AnyMotion callbacks while not in STATE_SENSING
522 * will be ignored.
523 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
524 * @see #KEY_SENSING_TIMEOUT
525 */
526 public long SENSING_TIMEOUT;
527
528 /**
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700529 * This is how long we will wait to try to get a good location fix before going in to
530 * idle mode.
531 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
532 * @see #KEY_LOCATING_TIMEOUT
533 */
534 public long LOCATING_TIMEOUT;
535
536 /**
537 * The desired maximum accuracy (in meters) we consider the location to be good enough to go
538 * on to idle. We will be trying to get an accuracy fix at least this good or until
539 * {@link #LOCATING_TIMEOUT} expires.
540 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
541 * @see #KEY_LOCATION_ACCURACY
542 */
543 public float LOCATION_ACCURACY;
544
545 /**
Adam Lesinski31c05d12015-06-09 17:34:04 -0700546 * This is the time, after seeing motion, that we wait after becoming inactive from
547 * that until we start looking for motion again.
548 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
549 * @see #KEY_MOTION_INACTIVE_TIMEOUT
550 */
551 public long MOTION_INACTIVE_TIMEOUT;
552
553 /**
554 * This is the time, after the inactive timeout elapses, that we will wait looking
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700555 * for motion until we truly consider the device to be idle.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700556 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
557 * @see #KEY_IDLE_AFTER_INACTIVE_TIMEOUT
558 */
559 public long IDLE_AFTER_INACTIVE_TIMEOUT;
560
561 /**
562 * This is the initial time, after being idle, that we will allow ourself to be back
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700563 * in the IDLE_MAINTENANCE state allowing the system to run normally until we return to
564 * idle.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700565 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
566 * @see #KEY_IDLE_PENDING_TIMEOUT
567 */
568 public long IDLE_PENDING_TIMEOUT;
569
570 /**
571 * Maximum pending idle timeout (time spent running) we will be allowed to use.
572 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
573 * @see #KEY_MAX_IDLE_PENDING_TIMEOUT
574 */
575 public long MAX_IDLE_PENDING_TIMEOUT;
576
577 /**
578 * Scaling factor to apply to current pending idle timeout each time we cycle through
579 * that state.
580 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
581 * @see #KEY_IDLE_PENDING_FACTOR
582 */
583 public float IDLE_PENDING_FACTOR;
584
585 /**
586 * This is the initial time that we want to sit in the idle state before waking up
587 * again to return to pending idle and allowing normal work to run.
588 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
589 * @see #KEY_IDLE_TIMEOUT
590 */
591 public long IDLE_TIMEOUT;
592
593 /**
594 * Maximum idle duration we will be allowed to use.
595 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
596 * @see #KEY_MAX_IDLE_TIMEOUT
597 */
598 public long MAX_IDLE_TIMEOUT;
599
600 /**
601 * Scaling factor to apply to current idle timeout each time we cycle through that state.
602 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
603 * @see #KEY_IDLE_FACTOR
604 */
605 public float IDLE_FACTOR;
606
607 /**
608 * This is the minimum time we will allow until the next upcoming alarm for us to
609 * actually go in to idle mode.
610 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
611 * @see #KEY_MIN_TIME_TO_ALARM
612 */
613 public long MIN_TIME_TO_ALARM;
614
615 /**
616 * Max amount of time to temporarily whitelist an app when it receives a high priority
617 * tickle.
618 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
619 * @see #KEY_MAX_TEMP_APP_WHITELIST_DURATION
620 */
621 public long MAX_TEMP_APP_WHITELIST_DURATION;
622
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700623 /**
624 * Amount of time we would like to whitelist an app that is receiving an MMS.
625 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
626 * @see #KEY_MMS_TEMP_APP_WHITELIST_DURATION
627 */
628 public long MMS_TEMP_APP_WHITELIST_DURATION;
629
Dianne Hackborn451c3462015-07-21 17:39:46 -0700630 /**
631 * Amount of time we would like to whitelist an app that is receiving an SMS.
632 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
633 * @see #KEY_SMS_TEMP_APP_WHITELIST_DURATION
634 */
635 public long SMS_TEMP_APP_WHITELIST_DURATION;
636
Adam Lesinski31c05d12015-06-09 17:34:04 -0700637 private final ContentResolver mResolver;
638 private final KeyValueListParser mParser = new KeyValueListParser(',');
639
640 public Constants(Handler handler, ContentResolver resolver) {
641 super(handler);
642 mResolver = resolver;
643 mResolver.registerContentObserver(
644 Settings.Global.getUriFor(Settings.Global.DEVICE_IDLE_CONSTANTS), false, this);
645 updateConstants();
646 }
647
648 @Override
649 public void onChange(boolean selfChange, Uri uri) {
650 updateConstants();
651 }
652
653 private void updateConstants() {
654 synchronized (DeviceIdleController.this) {
655 try {
656 mParser.setString(Settings.Global.getString(mResolver,
657 Settings.Global.DEVICE_IDLE_CONSTANTS));
658 } catch (IllegalArgumentException e) {
659 // Failed to parse the settings string, log this and move on
660 // with defaults.
661 Slog.e(TAG, "Bad device idle settings", e);
662 }
663
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700664 LIGHT_IDLE_TIMEOUT = mParser.getLong(KEY_LIGHT_IDLE_TIMEOUT,
665 !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800666 LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = mParser.getLong(
667 KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET,
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700668 !COMPRESS_TIME ? 1 * 60 * 1000L : 15 * 1000L);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800669 LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = mParser.getLong(
670 KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET,
671 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L);
Adam Lesinski31c05d12015-06-09 17:34:04 -0700672 INACTIVE_TIMEOUT = mParser.getLong(KEY_INACTIVE_TIMEOUT,
673 !COMPRESS_TIME ? 30 * 60 * 1000L : 3 * 60 * 1000L);
674 SENSING_TIMEOUT = mParser.getLong(KEY_SENSING_TIMEOUT,
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700675 !DEBUG ? 4 * 60 * 1000L : 60 * 1000L);
676 LOCATING_TIMEOUT = mParser.getLong(KEY_LOCATING_TIMEOUT,
677 !DEBUG ? 30 * 1000L : 15 * 1000L);
678 LOCATION_ACCURACY = mParser.getFloat(KEY_LOCATION_ACCURACY, 20);
Adam Lesinski31c05d12015-06-09 17:34:04 -0700679 MOTION_INACTIVE_TIMEOUT = mParser.getLong(KEY_MOTION_INACTIVE_TIMEOUT,
680 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
681 IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getLong(KEY_IDLE_AFTER_INACTIVE_TIMEOUT,
682 !COMPRESS_TIME ? 30 * 60 * 1000L : 3 * 60 * 1000L);
683 IDLE_PENDING_TIMEOUT = mParser.getLong(KEY_IDLE_PENDING_TIMEOUT,
684 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L);
685 MAX_IDLE_PENDING_TIMEOUT = mParser.getLong(KEY_MAX_IDLE_PENDING_TIMEOUT,
686 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
687 IDLE_PENDING_FACTOR = mParser.getFloat(KEY_IDLE_PENDING_FACTOR,
688 2f);
689 IDLE_TIMEOUT = mParser.getLong(KEY_IDLE_TIMEOUT,
690 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
691 MAX_IDLE_TIMEOUT = mParser.getLong(KEY_MAX_IDLE_TIMEOUT,
692 !COMPRESS_TIME ? 6 * 60 * 60 * 1000L : 30 * 60 * 1000L);
693 IDLE_FACTOR = mParser.getFloat(KEY_IDLE_FACTOR,
694 2f);
695 MIN_TIME_TO_ALARM = mParser.getLong(KEY_MIN_TIME_TO_ALARM,
696 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700697 MAX_TEMP_APP_WHITELIST_DURATION = mParser.getLong(
698 KEY_MAX_TEMP_APP_WHITELIST_DURATION, 5 * 60 * 1000L);
699 MMS_TEMP_APP_WHITELIST_DURATION = mParser.getLong(
Dianne Hackborn0b6134b2015-07-14 18:48:07 -0700700 KEY_MMS_TEMP_APP_WHITELIST_DURATION, 60 * 1000L);
Dianne Hackborn451c3462015-07-21 17:39:46 -0700701 SMS_TEMP_APP_WHITELIST_DURATION = mParser.getLong(
702 KEY_SMS_TEMP_APP_WHITELIST_DURATION, 20 * 1000L);
Adam Lesinski31c05d12015-06-09 17:34:04 -0700703 }
704 }
705
706 void dump(PrintWriter pw) {
707 pw.println(" Settings:");
708
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700709 pw.print(" "); pw.print(KEY_LIGHT_IDLE_TIMEOUT); pw.print("=");
710 TimeUtils.formatDuration(LIGHT_IDLE_TIMEOUT, pw);
711 pw.println();
712
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800713 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET); pw.print("=");
714 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MIN_BUDGET, pw);
715 pw.println();
716
717 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET); pw.print("=");
718 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MAX_BUDGET, pw);
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700719 pw.println();
720
Dianne Hackborna750a632015-06-16 17:18:23 -0700721 pw.print(" "); pw.print(KEY_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700722 TimeUtils.formatDuration(INACTIVE_TIMEOUT, pw);
723 pw.println();
724
Dianne Hackborna750a632015-06-16 17:18:23 -0700725 pw.print(" "); pw.print(KEY_SENSING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700726 TimeUtils.formatDuration(SENSING_TIMEOUT, pw);
727 pw.println();
728
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700729 pw.print(" "); pw.print(KEY_LOCATING_TIMEOUT); pw.print("=");
730 TimeUtils.formatDuration(LOCATING_TIMEOUT, pw);
731 pw.println();
732
733 pw.print(" "); pw.print(KEY_LOCATION_ACCURACY); pw.print("=");
734 pw.print(LOCATION_ACCURACY); pw.print("m");
735 pw.println();
736
Dianne Hackborna750a632015-06-16 17:18:23 -0700737 pw.print(" "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700738 TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT, pw);
739 pw.println();
740
Dianne Hackborna750a632015-06-16 17:18:23 -0700741 pw.print(" "); pw.print(KEY_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700742 TimeUtils.formatDuration(IDLE_AFTER_INACTIVE_TIMEOUT, pw);
743 pw.println();
744
Dianne Hackborna750a632015-06-16 17:18:23 -0700745 pw.print(" "); pw.print(KEY_IDLE_PENDING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700746 TimeUtils.formatDuration(IDLE_PENDING_TIMEOUT, pw);
747 pw.println();
748
Dianne Hackborna750a632015-06-16 17:18:23 -0700749 pw.print(" "); pw.print(KEY_MAX_IDLE_PENDING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700750 TimeUtils.formatDuration(MAX_IDLE_PENDING_TIMEOUT, pw);
751 pw.println();
752
Dianne Hackborna750a632015-06-16 17:18:23 -0700753 pw.print(" "); pw.print(KEY_IDLE_PENDING_FACTOR); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700754 pw.println(IDLE_PENDING_FACTOR);
755
Dianne Hackborna750a632015-06-16 17:18:23 -0700756 pw.print(" "); pw.print(KEY_IDLE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700757 TimeUtils.formatDuration(IDLE_TIMEOUT, pw);
758 pw.println();
759
Dianne Hackborna750a632015-06-16 17:18:23 -0700760 pw.print(" "); pw.print(KEY_MAX_IDLE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700761 TimeUtils.formatDuration(MAX_IDLE_TIMEOUT, pw);
762 pw.println();
763
Dianne Hackborna750a632015-06-16 17:18:23 -0700764 pw.print(" "); pw.print(KEY_IDLE_FACTOR); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700765 pw.println(IDLE_FACTOR);
766
Dianne Hackborna750a632015-06-16 17:18:23 -0700767 pw.print(" "); pw.print(KEY_MIN_TIME_TO_ALARM); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700768 TimeUtils.formatDuration(MIN_TIME_TO_ALARM, pw);
769 pw.println();
770
Dianne Hackborna750a632015-06-16 17:18:23 -0700771 pw.print(" "); pw.print(KEY_MAX_TEMP_APP_WHITELIST_DURATION); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700772 TimeUtils.formatDuration(MAX_TEMP_APP_WHITELIST_DURATION, pw);
773 pw.println();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700774
775 pw.print(" "); pw.print(KEY_MMS_TEMP_APP_WHITELIST_DURATION); pw.print("=");
776 TimeUtils.formatDuration(MMS_TEMP_APP_WHITELIST_DURATION, pw);
777 pw.println();
Dianne Hackborn451c3462015-07-21 17:39:46 -0700778
779 pw.print(" "); pw.print(KEY_SMS_TEMP_APP_WHITELIST_DURATION); pw.print("=");
780 TimeUtils.formatDuration(SMS_TEMP_APP_WHITELIST_DURATION, pw);
781 pw.println();
Adam Lesinski31c05d12015-06-09 17:34:04 -0700782 }
783 }
784
785 private Constants mConstants;
786
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700787 @Override
788 public void onAnyMotionResult(int result) {
789 if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700790 if (result == AnyMotionDetector.RESULT_MOVED) {
791 if (DEBUG) Slog.d(TAG, "RESULT_MOVED received.");
792 synchronized (this) {
793 handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "sense_motion");
794 }
795 } else if (result == AnyMotionDetector.RESULT_STATIONARY) {
796 if (DEBUG) Slog.d(TAG, "RESULT_STATIONARY received.");
797 if (mState == STATE_SENSING) {
798 // If we are currently sensing, it is time to move to locating.
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700799 synchronized (this) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700800 mNotMoving = true;
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800801 stepIdleStateLocked("s:stationary");
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700802 }
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700803 } else if (mState == STATE_LOCATING) {
804 // If we are currently locating, note that we are not moving and step
805 // if we have located the position.
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700806 synchronized (this) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700807 mNotMoving = true;
808 if (mLocated) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800809 stepIdleStateLocked("s:stationary");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700810 }
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700811 }
812 }
813 }
814 }
815
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700816 static final int MSG_WRITE_CONFIG = 1;
817 static final int MSG_REPORT_IDLE_ON = 2;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700818 static final int MSG_REPORT_IDLE_ON_LIGHT = 3;
819 static final int MSG_REPORT_IDLE_OFF = 4;
820 static final int MSG_REPORT_ACTIVE = 5;
821 static final int MSG_TEMP_APP_WHITELIST_TIMEOUT = 6;
Yao Chenca5edbb2016-01-13 14:44:36 -0800822 static final int MSG_REPORT_MAINTENANCE_ACTIVITY = 7;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700823
824 final class MyHandler extends Handler {
825 MyHandler(Looper looper) {
826 super(looper);
827 }
828
829 @Override public void handleMessage(Message msg) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700830 if (DEBUG) Slog.d(TAG, "handleMessage(" + msg.what + ")");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700831 switch (msg.what) {
832 case MSG_WRITE_CONFIG: {
833 handleWriteConfigFile();
834 } break;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700835 case MSG_REPORT_IDLE_ON:
836 case MSG_REPORT_IDLE_ON_LIGHT: {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700837 EventLogTags.writeDeviceIdleOnStart();
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700838 final boolean fullChanged;
839 final boolean lightChanged;
840 if (msg.what == MSG_REPORT_IDLE_ON) {
841 fullChanged = mLocalPowerManager.setDeviceIdleMode(true);
842 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
843 } else {
844 fullChanged = mLocalPowerManager.setDeviceIdleMode(false);
845 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(true);
846 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700847 try {
848 mNetworkPolicyManager.setDeviceIdleMode(true);
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700849 mBatteryStats.noteDeviceIdleMode(msg.what == MSG_REPORT_IDLE_ON
850 ? BatteryStats.DEVICE_IDLE_MODE_FULL
851 : BatteryStats.DEVICE_IDLE_MODE_LIGHT, null, Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700852 } catch (RemoteException e) {
853 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700854 if (fullChanged) {
855 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
856 }
857 if (lightChanged) {
858 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL);
859 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700860 EventLogTags.writeDeviceIdleOnComplete();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700861 } break;
862 case MSG_REPORT_IDLE_OFF: {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700863 EventLogTags.writeDeviceIdleOffStart("unknown");
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700864 final boolean fullChanged = mLocalPowerManager.setDeviceIdleMode(false);
865 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700866 try {
867 mNetworkPolicyManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700868 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF,
869 null, Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700870 } catch (RemoteException e) {
871 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700872 if (fullChanged) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800873 incActiveIdleOps();
874 getContext().sendOrderedBroadcastAsUser(mIdleIntent, UserHandle.ALL,
875 null, mIdleStartedDoneReceiver, null, 0, null, null);
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700876 }
877 if (lightChanged) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800878 incActiveIdleOps();
879 getContext().sendOrderedBroadcastAsUser(mLightIdleIntent, UserHandle.ALL,
880 null, mIdleStartedDoneReceiver, null, 0, null, null);
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700881 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800882 // Always start with one active op for the message being sent here.
883 // Now we we done!
884 decActiveIdleOps();
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700885 EventLogTags.writeDeviceIdleOffComplete();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700886 } break;
887 case MSG_REPORT_ACTIVE: {
Dianne Hackbornb6683c42015-06-18 17:40:33 -0700888 String activeReason = (String)msg.obj;
889 int activeUid = msg.arg1;
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700890 EventLogTags.writeDeviceIdleOffStart(
891 activeReason != null ? activeReason : "unknown");
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700892 final boolean fullChanged = mLocalPowerManager.setDeviceIdleMode(false);
893 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700894 try {
895 mNetworkPolicyManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700896 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF,
897 activeReason, activeUid);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700898 } catch (RemoteException e) {
899 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700900 if (fullChanged) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700901 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
902 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700903 if (lightChanged) {
904 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL);
905 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700906 EventLogTags.writeDeviceIdleOffComplete();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700907 } break;
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700908 case MSG_TEMP_APP_WHITELIST_TIMEOUT: {
909 int uid = msg.arg1;
910 checkTempAppWhitelistTimeout(uid);
911 } break;
Yao Chenca5edbb2016-01-13 14:44:36 -0800912 case MSG_REPORT_MAINTENANCE_ACTIVITY: {
913 boolean active = (msg.arg1 == 1);
914 final int size = mMaintenanceActivityListeners.beginBroadcast();
915 try {
916 for (int i = 0; i < size; i++) {
917 try {
918 mMaintenanceActivityListeners.getBroadcastItem(i)
919 .onMaintenanceActivityChanged(active);
920 } catch (RemoteException ignored) {
921 }
922 }
923 } finally {
924 mMaintenanceActivityListeners.finishBroadcast();
925 }
926 } break;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700927 }
928 }
929 }
930
931 final MyHandler mHandler;
932
Dianne Hackborn9461b6f2015-10-07 17:33:16 -0700933 BinderService mBinderService;
934
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700935 private final class BinderService extends IDeviceIdleController.Stub {
936 @Override public void addPowerSaveWhitelistApp(String name) {
937 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
938 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -0800939 long ident = Binder.clearCallingIdentity();
940 try {
941 addPowerSaveWhitelistAppInternal(name);
942 } finally {
943 Binder.restoreCallingIdentity(ident);
944 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700945 }
946
947 @Override public void removePowerSaveWhitelistApp(String name) {
948 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
949 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -0800950 long ident = Binder.clearCallingIdentity();
951 try {
952 removePowerSaveWhitelistAppInternal(name);
953 } finally {
954 Binder.restoreCallingIdentity(ident);
955 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700956 }
957
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700958 @Override public String[] getSystemPowerWhitelistExceptIdle() {
959 return getSystemPowerWhitelistExceptIdleInternal();
960 }
961
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700962 @Override public String[] getSystemPowerWhitelist() {
963 return getSystemPowerWhitelistInternal();
964 }
965
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700966 @Override public String[] getFullPowerWhitelistExceptIdle() {
967 return getFullPowerWhitelistExceptIdleInternal();
968 }
969
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700970 @Override public String[] getFullPowerWhitelist() {
971 return getFullPowerWhitelistInternal();
972 }
973
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700974 @Override public int[] getAppIdWhitelistExceptIdle() {
975 return getAppIdWhitelistExceptIdleInternal();
976 }
977
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700978 @Override public int[] getAppIdWhitelist() {
979 return getAppIdWhitelistInternal();
980 }
981
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700982 @Override public int[] getAppIdTempWhitelist() {
983 return getAppIdTempWhitelistInternal();
984 }
985
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700986 @Override public boolean isPowerSaveWhitelistExceptIdleApp(String name) {
987 return isPowerSaveWhitelistExceptIdleAppInternal(name);
988 }
989
Amith Yamasani06bf8242015-05-08 16:36:21 -0700990 @Override public boolean isPowerSaveWhitelistApp(String name) {
991 return isPowerSaveWhitelistAppInternal(name);
992 }
993
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700994 @Override public void addPowerSaveTempWhitelistApp(String packageName, long duration,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700995 int userId, String reason) throws RemoteException {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -0700996 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700997 }
998
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700999 @Override public long addPowerSaveTempWhitelistAppForMms(String packageName,
1000 int userId, String reason) throws RemoteException {
1001 long duration = mConstants.MMS_TEMP_APP_WHITELIST_DURATION;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001002 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001003 return duration;
1004 }
1005
Dianne Hackborn451c3462015-07-21 17:39:46 -07001006 @Override public long addPowerSaveTempWhitelistAppForSms(String packageName,
1007 int userId, String reason) throws RemoteException {
1008 long duration = mConstants.SMS_TEMP_APP_WHITELIST_DURATION;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001009 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Dianne Hackborn451c3462015-07-21 17:39:46 -07001010 return duration;
1011 }
1012
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001013 @Override public void exitIdle(String reason) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001014 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER,
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001015 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001016 long ident = Binder.clearCallingIdentity();
1017 try {
1018 exitIdleInternal(reason);
1019 } finally {
1020 Binder.restoreCallingIdentity(ident);
1021 }
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001022 }
1023
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001024 @Override public void downloadServiceActive(IBinder token) {
1025 getContext().enforceCallingOrSelfPermission(
1026 "android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS", null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001027 long ident = Binder.clearCallingIdentity();
1028 try {
1029 DeviceIdleController.this.downloadServiceActive(token);
1030 } finally {
1031 Binder.restoreCallingIdentity(ident);
1032 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001033 }
1034
1035 @Override public void downloadServiceInactive() {
1036 getContext().enforceCallingOrSelfPermission(
1037 "android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS", null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001038 long ident = Binder.clearCallingIdentity();
1039 try {
1040 DeviceIdleController.this.downloadServiceInactive();
1041 } finally {
1042 Binder.restoreCallingIdentity(ident);
1043 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001044 }
1045
Yao Chenca5edbb2016-01-13 14:44:36 -08001046 @Override public boolean registerMaintenanceActivityListener(
1047 IMaintenanceActivityListener listener) {
1048 return DeviceIdleController.this.registerMaintenanceActivityListener(listener);
1049 }
1050
1051 @Override public void unregisterMaintenanceActivityListener(
1052 IMaintenanceActivityListener listener) {
1053 DeviceIdleController.this.unregisterMaintenanceActivityListener(listener);
1054 }
1055
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001056 @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1057 DeviceIdleController.this.dump(fd, pw, args);
1058 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001059
1060 @Override public void onShellCommand(FileDescriptor in, FileDescriptor out,
1061 FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
1062 (new Shell()).exec(this, in, out, err, args, resultReceiver);
1063 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001064 }
1065
Dianne Hackborna750a632015-06-16 17:18:23 -07001066 public final class LocalService {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001067 public void addPowerSaveTempWhitelistAppDirect(int appId, long duration, boolean sync,
1068 String reason) {
1069 addPowerSaveTempWhitelistAppDirectInternal(0, appId, duration, sync, reason);
1070 }
1071
1072 public void setNetworkPolicyTempWhitelistCallback(Runnable callback) {
1073 setNetworkPolicyTempWhitelistCallbackInternal(callback);
Dianne Hackborna750a632015-06-16 17:18:23 -07001074 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001075
1076 public void setSyncActive(boolean active) {
1077 DeviceIdleController.this.setSyncActive(active);
1078 }
1079
1080 public void setJobsActive(boolean active) {
1081 DeviceIdleController.this.setJobsActive(active);
1082 }
1083
1084 // Up-call from alarm manager.
1085 public void setAlarmsActive(boolean active) {
1086 DeviceIdleController.this.setAlarmsActive(active);
1087 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001088 }
1089
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001090 public DeviceIdleController(Context context) {
1091 super(context);
1092 mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml"));
1093 mHandler = new MyHandler(BackgroundThread.getHandler().getLooper());
1094 }
1095
1096 private static File getSystemDir() {
1097 return new File(Environment.getDataDirectory(), "system");
1098 }
1099
1100 @Override
1101 public void onStart() {
1102 final PackageManager pm = getContext().getPackageManager();
1103
1104 synchronized (this) {
Dianne Hackborn92617032015-06-19 15:32:19 -07001105 mEnabled = getContext().getResources().getBoolean(
1106 com.android.internal.R.bool.config_enableAutoPowerModes);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001107 SystemConfig sysConfig = SystemConfig.getInstance();
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001108 ArraySet<String> allowPowerExceptIdle = sysConfig.getAllowInPowerSaveExceptIdle();
1109 for (int i=0; i<allowPowerExceptIdle.size(); i++) {
1110 String pkg = allowPowerExceptIdle.valueAt(i);
1111 try {
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07001112 ApplicationInfo ai = pm.getApplicationInfo(pkg,
1113 PackageManager.MATCH_SYSTEM_ONLY);
1114 int appid = UserHandle.getAppId(ai.uid);
1115 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
1116 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001117 } catch (PackageManager.NameNotFoundException e) {
1118 }
1119 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001120 ArraySet<String> allowPower = sysConfig.getAllowInPowerSave();
1121 for (int i=0; i<allowPower.size(); i++) {
1122 String pkg = allowPower.valueAt(i);
1123 try {
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07001124 ApplicationInfo ai = pm.getApplicationInfo(pkg,
1125 PackageManager.MATCH_SYSTEM_ONLY);
1126 int appid = UserHandle.getAppId(ai.uid);
1127 // These apps are on both the whitelist-except-idle as well
1128 // as the full whitelist, so they apply in all cases.
1129 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
1130 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
1131 mPowerSaveWhitelistApps.put(ai.packageName, appid);
1132 mPowerSaveWhitelistSystemAppIds.put(appid, true);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001133 } catch (PackageManager.NameNotFoundException e) {
1134 }
1135 }
1136
Adam Lesinski31c05d12015-06-09 17:34:04 -07001137 mConstants = new Constants(mHandler, getContext().getContentResolver());
1138
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001139 readConfigFileLocked();
1140 updateWhitelistAppIdsLocked();
1141
1142 mScreenOn = true;
1143 // Start out assuming we are charging. If we aren't, we will at least get
1144 // a battery update the next time the level drops.
1145 mCharging = true;
1146 mState = STATE_ACTIVE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001147 mLightState = LIGHT_STATE_ACTIVE;
Adam Lesinski31c05d12015-06-09 17:34:04 -07001148 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001149 }
1150
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001151 mBinderService = new BinderService();
1152 publishBinderService(Context.DEVICE_IDLE_CONTROLLER, mBinderService);
Dianne Hackborna750a632015-06-16 17:18:23 -07001153 publishLocalService(LocalService.class, new LocalService());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001154 }
1155
1156 @Override
1157 public void onBootPhase(int phase) {
1158 if (phase == PHASE_SYSTEM_SERVICES_READY) {
1159 synchronized (this) {
1160 mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
1161 mBatteryStats = BatteryStatsService.getService();
1162 mLocalPowerManager = getLocalService(PowerManagerInternal.class);
1163 mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface(
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001164 ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001165 mDisplayManager = (DisplayManager) getContext().getSystemService(
1166 Context.DISPLAY_SERVICE);
1167 mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001168 int sigMotionSensorId = getContext().getResources().getInteger(
1169 com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor);
1170 if (sigMotionSensorId > 0) {
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001171 mMotionSensor = mSensorManager.getDefaultSensor(sigMotionSensorId, true);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001172 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001173 if (mMotionSensor == null && getContext().getResources().getBoolean(
Joe LaPenna23d681b2015-08-27 15:12:11 -07001174 com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) {
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001175 mMotionSensor = mSensorManager.getDefaultSensor(
1176 Sensor.TYPE_WRIST_TILT_GESTURE, true);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001177 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001178 if (mMotionSensor == null) {
Joe LaPenna23d681b2015-08-27 15:12:11 -07001179 // As a last ditch, fall back to SMD.
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001180 mMotionSensor = mSensorManager.getDefaultSensor(
1181 Sensor.TYPE_SIGNIFICANT_MOTION, true);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001182 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001183
Joe LaPenna23d681b2015-08-27 15:12:11 -07001184 if (getContext().getResources().getBoolean(
1185 com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) {
1186 mLocationManager = (LocationManager) getContext().getSystemService(
1187 Context.LOCATION_SERVICE);
1188 mLocationRequest = new LocationRequest()
1189 .setQuality(LocationRequest.ACCURACY_FINE)
1190 .setInterval(0)
1191 .setFastestInterval(0)
1192 .setNumUpdates(1);
1193 }
1194
1195 float angleThreshold = getContext().getResources().getInteger(
1196 com.android.internal.R.integer.config_autoPowerModeThresholdAngle) / 100f;
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001197 mAnyMotionDetector = new AnyMotionDetector(
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001198 (PowerManager) getContext().getSystemService(Context.POWER_SERVICE),
Joe LaPenna23d681b2015-08-27 15:12:11 -07001199 mHandler, mSensorManager, this, angleThreshold);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001200
1201 Intent intent = new Intent(ACTION_STEP_IDLE_STATE)
1202 .setPackage("android")
1203 .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1204 mAlarmIntent = PendingIntent.getBroadcast(getContext(), 0, intent, 0);
1205
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001206 Intent intentLight = new Intent(ACTION_STEP_LIGHT_IDLE_STATE)
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001207 .setPackage("android")
1208 .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001209 mLightAlarmIntent = PendingIntent.getBroadcast(getContext(), 0, intentLight, 0);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001210
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001211 mIdleIntent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001212 mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1213 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001214 mLightIdleIntent = new Intent(PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
1215 mLightIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1216 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001217
1218 IntentFilter filter = new IntentFilter();
1219 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
1220 filter.addAction(ACTION_STEP_IDLE_STATE);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001221 filter.addAction(ACTION_STEP_LIGHT_IDLE_STATE);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001222 getContext().registerReceiver(mReceiver, filter);
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07001223 filter = new IntentFilter();
1224 filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
1225 filter.addDataScheme("package");
1226 getContext().registerReceiver(mReceiver, filter);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001227
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001228 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07001229
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001230 mDisplayManager.registerDisplayListener(mDisplayListener, null);
1231 updateDisplayLocked();
1232 }
1233 }
1234 }
1235
1236 public boolean addPowerSaveWhitelistAppInternal(String name) {
1237 synchronized (this) {
1238 try {
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07001239 ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name,
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07001240 PackageManager.MATCH_UNINSTALLED_PACKAGES);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001241 if (mPowerSaveWhitelistUserApps.put(name, UserHandle.getAppId(ai.uid)) == null) {
1242 reportPowerSaveWhitelistChangedLocked();
1243 updateWhitelistAppIdsLocked();
1244 writeConfigFileLocked();
1245 }
1246 return true;
1247 } catch (PackageManager.NameNotFoundException e) {
1248 return false;
1249 }
1250 }
1251 }
1252
1253 public boolean removePowerSaveWhitelistAppInternal(String name) {
1254 synchronized (this) {
1255 if (mPowerSaveWhitelistUserApps.remove(name) != null) {
1256 reportPowerSaveWhitelistChangedLocked();
1257 updateWhitelistAppIdsLocked();
1258 writeConfigFileLocked();
1259 return true;
1260 }
1261 }
1262 return false;
1263 }
1264
Felipe Lemef8a46232016-02-10 13:51:54 -08001265 public boolean getPowerSaveWhitelistAppInternal(String name) {
1266 synchronized (this) {
1267 return mPowerSaveWhitelistUserApps.containsKey(name);
1268 }
1269 }
1270
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001271 public String[] getSystemPowerWhitelistExceptIdleInternal() {
1272 synchronized (this) {
1273 int size = mPowerSaveWhitelistAppsExceptIdle.size();
1274 String[] apps = new String[size];
1275 for (int i = 0; i < size; i++) {
1276 apps[i] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i);
1277 }
1278 return apps;
1279 }
1280 }
1281
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001282 public String[] getSystemPowerWhitelistInternal() {
1283 synchronized (this) {
1284 int size = mPowerSaveWhitelistApps.size();
1285 String[] apps = new String[size];
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001286 for (int i = 0; i < size; i++) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001287 apps[i] = mPowerSaveWhitelistApps.keyAt(i);
1288 }
1289 return apps;
1290 }
1291 }
1292
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001293 public String[] getFullPowerWhitelistExceptIdleInternal() {
1294 synchronized (this) {
1295 int size = mPowerSaveWhitelistAppsExceptIdle.size() + mPowerSaveWhitelistUserApps.size();
1296 String[] apps = new String[size];
1297 int cur = 0;
1298 for (int i = 0; i < mPowerSaveWhitelistAppsExceptIdle.size(); i++) {
1299 apps[cur] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i);
1300 cur++;
1301 }
1302 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
1303 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i);
1304 cur++;
1305 }
1306 return apps;
1307 }
1308 }
1309
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001310 public String[] getFullPowerWhitelistInternal() {
1311 synchronized (this) {
1312 int size = mPowerSaveWhitelistApps.size() + mPowerSaveWhitelistUserApps.size();
1313 String[] apps = new String[size];
1314 int cur = 0;
1315 for (int i = 0; i < mPowerSaveWhitelistApps.size(); i++) {
1316 apps[cur] = mPowerSaveWhitelistApps.keyAt(i);
1317 cur++;
1318 }
1319 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
1320 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i);
1321 cur++;
1322 }
1323 return apps;
1324 }
1325 }
1326
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001327 public boolean isPowerSaveWhitelistExceptIdleAppInternal(String packageName) {
1328 synchronized (this) {
1329 return mPowerSaveWhitelistAppsExceptIdle.containsKey(packageName)
1330 || mPowerSaveWhitelistUserApps.containsKey(packageName);
1331 }
1332 }
1333
Amith Yamasani06bf8242015-05-08 16:36:21 -07001334 public boolean isPowerSaveWhitelistAppInternal(String packageName) {
1335 synchronized (this) {
1336 return mPowerSaveWhitelistApps.containsKey(packageName)
1337 || mPowerSaveWhitelistUserApps.containsKey(packageName);
1338 }
1339 }
1340
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001341 public int[] getAppIdWhitelistExceptIdleInternal() {
1342 synchronized (this) {
1343 return mPowerSaveWhitelistExceptIdleAppIdArray;
1344 }
1345 }
1346
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001347 public int[] getAppIdWhitelistInternal() {
1348 synchronized (this) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001349 return mPowerSaveWhitelistAllAppIdArray;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001350 }
1351 }
1352
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001353 public int[] getAppIdTempWhitelistInternal() {
1354 synchronized (this) {
1355 return mTempWhitelistAppIdArray;
1356 }
1357 }
1358
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001359 void addPowerSaveTempWhitelistAppChecked(String packageName, long duration,
1360 int userId, String reason) throws RemoteException {
1361 getContext().enforceCallingPermission(
1362 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
1363 "No permission to change device idle whitelist");
1364 final int callingUid = Binder.getCallingUid();
1365 userId = ActivityManagerNative.getDefault().handleIncomingUser(
1366 Binder.getCallingPid(),
1367 callingUid,
1368 userId,
1369 /*allowAll=*/ false,
1370 /*requireFull=*/ false,
1371 "addPowerSaveTempWhitelistApp", null);
1372 final long token = Binder.clearCallingIdentity();
1373 try {
1374 addPowerSaveTempWhitelistAppInternal(callingUid,
1375 packageName, duration, userId, true, reason);
1376 } finally {
1377 Binder.restoreCallingIdentity(token);
1378 }
1379 }
1380
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001381 /**
1382 * Adds an app to the temporary whitelist and resets the endTime for granting the
1383 * app an exemption to access network and acquire wakelocks.
1384 */
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001385 void addPowerSaveTempWhitelistAppInternal(int callingUid, String packageName,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001386 long duration, int userId, boolean sync, String reason) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001387 try {
Jeff Sharkeye06b4d12016-01-06 14:51:50 -07001388 int uid = getContext().getPackageManager().getPackageUidAsUser(packageName, userId);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001389 int appId = UserHandle.getAppId(uid);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001390 addPowerSaveTempWhitelistAppDirectInternal(callingUid, appId, duration, sync, reason);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001391 } catch (NameNotFoundException e) {
1392 }
1393 }
1394
Dianne Hackborna750a632015-06-16 17:18:23 -07001395 /**
1396 * Adds an app to the temporary whitelist and resets the endTime for granting the
1397 * app an exemption to access network and acquire wakelocks.
1398 */
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001399 void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int appId,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001400 long duration, boolean sync, String reason) {
Dianne Hackborna750a632015-06-16 17:18:23 -07001401 final long timeNow = SystemClock.elapsedRealtime();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001402 Runnable networkPolicyTempWhitelistCallback = null;
Dianne Hackborna750a632015-06-16 17:18:23 -07001403 synchronized (this) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001404 int callingAppId = UserHandle.getAppId(callingUid);
1405 if (callingAppId >= Process.FIRST_APPLICATION_UID) {
1406 if (!mPowerSaveWhitelistSystemAppIds.get(callingAppId)) {
1407 throw new SecurityException("Calling app " + UserHandle.formatUid(callingUid)
1408 + " is not on whitelist");
1409 }
1410 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001411 duration = Math.min(duration, mConstants.MAX_TEMP_APP_WHITELIST_DURATION);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001412 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId);
1413 final boolean newEntry = entry == null;
Dianne Hackborna750a632015-06-16 17:18:23 -07001414 // Set the new end time
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001415 if (newEntry) {
1416 entry = new Pair<>(new MutableLong(0), reason);
1417 mTempWhitelistAppIdEndTimes.put(appId, entry);
1418 }
1419 entry.first.value = timeNow + duration;
Dianne Hackborna750a632015-06-16 17:18:23 -07001420 if (DEBUG) {
1421 Slog.d(TAG, "Adding AppId " + appId + " to temp whitelist");
1422 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001423 if (newEntry) {
Dianne Hackborna750a632015-06-16 17:18:23 -07001424 // No pending timeout for the app id, post a delayed message
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001425 try {
1426 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_START,
1427 reason, appId);
1428 } catch (RemoteException e) {
1429 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001430 postTempActiveTimeoutMessage(appId, duration);
1431 updateTempWhitelistAppIdsLocked();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001432 if (mNetworkPolicyTempWhitelistCallback != null) {
1433 if (!sync) {
1434 mHandler.post(mNetworkPolicyTempWhitelistCallback);
1435 } else {
1436 networkPolicyTempWhitelistCallback = mNetworkPolicyTempWhitelistCallback;
1437 }
1438 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001439 reportTempWhitelistChangedLocked();
1440 }
1441 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001442 if (networkPolicyTempWhitelistCallback != null) {
1443 networkPolicyTempWhitelistCallback.run();
1444 }
1445 }
1446
1447 public void setNetworkPolicyTempWhitelistCallbackInternal(Runnable callback) {
1448 synchronized (this) {
1449 mNetworkPolicyTempWhitelistCallback = callback;
1450 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001451 }
1452
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001453 private void postTempActiveTimeoutMessage(int uid, long delay) {
1454 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, uid, 0),
1455 delay);
1456 }
1457
1458 void checkTempAppWhitelistTimeout(int uid) {
Dianne Hackborna750a632015-06-16 17:18:23 -07001459 final long timeNow = SystemClock.elapsedRealtime();
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001460 synchronized (this) {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001461 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(uid);
1462 if (entry == null) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001463 // Nothing to do
1464 return;
1465 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001466 if (timeNow >= entry.first.value) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001467 mTempWhitelistAppIdEndTimes.delete(uid);
1468 if (DEBUG) {
1469 Slog.d(TAG, "Removing UID " + uid + " from temp whitelist");
1470 }
1471 updateTempWhitelistAppIdsLocked();
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001472 if (mNetworkPolicyTempWhitelistCallback != null) {
1473 mHandler.post(mNetworkPolicyTempWhitelistCallback);
1474 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001475 reportTempWhitelistChangedLocked();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001476 try {
1477 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH,
1478 entry.second, uid);
1479 } catch (RemoteException e) {
1480 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001481 } else {
1482 // Need more time
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001483 postTempActiveTimeoutMessage(uid, entry.first.value - timeNow);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001484 }
1485 }
1486 }
1487
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001488 public void exitIdleInternal(String reason) {
1489 synchronized (this) {
1490 becomeActiveLocked(reason, Binder.getCallingUid());
1491 }
1492 }
1493
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001494 void updateDisplayLocked() {
1495 mCurDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
1496 // We consider any situation where the display is showing something to be it on,
1497 // because if there is anything shown we are going to be updating it at some
1498 // frequency so can't be allowed to go into deep sleeps.
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001499 boolean screenOn = mCurDisplay.getState() == Display.STATE_ON;
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001500 if (DEBUG) Slog.d(TAG, "updateDisplayLocked: screenOn=" + screenOn);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001501 if (!screenOn && mScreenOn) {
1502 mScreenOn = false;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001503 if (!mForceIdle) {
1504 becomeInactiveIfAppropriateLocked();
1505 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001506 } else if (screenOn) {
1507 mScreenOn = true;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001508 if (!mForceIdle) {
1509 becomeActiveLocked("screen", Process.myUid());
1510 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001511 }
1512 }
1513
1514 void updateChargingLocked(boolean charging) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001515 if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001516 if (!charging && mCharging) {
1517 mCharging = false;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001518 if (!mForceIdle) {
1519 becomeInactiveIfAppropriateLocked();
1520 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001521 } else if (charging) {
1522 mCharging = charging;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001523 if (!mForceIdle) {
1524 becomeActiveLocked("charging", Process.myUid());
1525 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001526 }
1527 }
1528
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001529 void scheduleReportActiveLocked(String activeReason, int activeUid) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001530 Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid, 0, activeReason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001531 mHandler.sendMessage(msg);
1532 }
1533
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001534 void becomeActiveLocked(String activeReason, int activeUid) {
1535 if (DEBUG) Slog.i(TAG, "becomeActiveLocked, reason = " + activeReason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001536 if (mState != STATE_ACTIVE || mLightState != STATE_ACTIVE) {
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001537 EventLogTags.writeDeviceIdle(STATE_ACTIVE, activeReason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001538 EventLogTags.writeDeviceIdleLight(LIGHT_STATE_ACTIVE, activeReason);
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001539 scheduleReportActiveLocked(activeReason, activeUid);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001540 mState = STATE_ACTIVE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001541 mLightState = LIGHT_STATE_ACTIVE;
Adam Lesinski31c05d12015-06-09 17:34:04 -07001542 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001543 mCurIdleBudget = 0;
1544 mMaintenanceStartTime = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001545 resetIdleManagementLocked();
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001546 resetLightIdleManagementLocked();
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001547 addEvent(EVENT_NORMAL);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001548 }
1549 }
1550
1551 void becomeInactiveIfAppropriateLocked() {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001552 if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()");
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001553 if (((!mScreenOn && !mCharging) || mForceIdle) && mEnabled) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001554 // Screen has turned off; we are now going to become inactive and start
1555 // waiting to see if we will ultimately go idle.
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001556 if (mState == STATE_ACTIVE) {
1557 mState = STATE_INACTIVE;
1558 if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE");
1559 resetIdleManagementLocked();
1560 scheduleAlarmLocked(mInactiveTimeout, false);
1561 EventLogTags.writeDeviceIdle(mState, "no activity");
1562 }
1563 if (mLightState == LIGHT_STATE_ACTIVE) {
1564 mLightState = LIGHT_STATE_INACTIVE;
1565 if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE");
1566 resetLightIdleManagementLocked();
1567 scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_TIMEOUT);
1568 EventLogTags.writeDeviceIdleLight(mLightState, "no activity");
1569 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001570 }
1571 }
1572
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001573 void resetIdleManagementLocked() {
1574 mNextIdlePendingDelay = 0;
1575 mNextIdleDelay = 0;
1576 cancelAlarmLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001577 cancelLocatingLocked();
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001578 stopMonitoringMotionLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001579 mAnyMotionDetector.stop();
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001580 }
1581
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001582 void resetLightIdleManagementLocked() {
1583 cancelLightAlarmLocked();
1584 }
1585
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001586 void exitForceIdleLocked() {
1587 if (mForceIdle) {
1588 mForceIdle = false;
1589 if (mScreenOn || mCharging) {
1590 becomeActiveLocked("exit-force-idle", Process.myUid());
1591 }
1592 }
1593 }
1594
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001595 void stepLightIdleStateLocked(String reason) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001596 if (mLightState == LIGHT_STATE_OVERRIDE) {
1597 // If we are already in full device idle mode, then
1598 // there is nothing left to do for light mode.
1599 return;
1600 }
1601
1602 if (DEBUG) Slog.d(TAG, "stepLightIdleStateLocked: mLightState=" + mLightState);
1603 EventLogTags.writeDeviceIdleLightStep();
1604
1605 switch (mLightState) {
1606 case LIGHT_STATE_INACTIVE:
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001607 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
1608 mMaintenanceStartTime = 0;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001609 case LIGHT_STATE_IDLE_MAINTENANCE:
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001610 if (mMaintenanceStartTime != 0) {
1611 long duration = SystemClock.elapsedRealtime() - mMaintenanceStartTime;
1612 if (duration < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
1613 // We didn't use up all of our minimum budget; add this to the reserve.
1614 mCurIdleBudget += (mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET-duration);
1615 } else {
1616 // We used more than our minimum budget; this comes out of the reserve.
1617 mCurIdleBudget -= (duration-mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET);
1618 }
1619 }
1620 mMaintenanceStartTime = 0;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001621 scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_TIMEOUT);
1622 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_STATE_IDLE.");
1623 mLightState = LIGHT_STATE_IDLE;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001624 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001625 addEvent(EVENT_LIGHT_IDLE);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001626 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON_LIGHT);
1627 break;
1628 case LIGHT_STATE_IDLE:
1629 // We have been idling long enough, now it is time to do some work.
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001630 mActiveIdleOpCount = 1;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001631 mMaintenanceStartTime = SystemClock.elapsedRealtime();
1632 if (mCurIdleBudget < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
1633 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
1634 } else if (mCurIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) {
1635 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
1636 }
1637 mMaintenanceStartTime = SystemClock.elapsedRealtime();
1638 scheduleLightAlarmLocked(mCurIdleBudget);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001639 if (DEBUG) Slog.d(TAG,
1640 "Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE.");
1641 mLightState = LIGHT_STATE_IDLE_MAINTENANCE;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001642 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001643 addEvent(EVENT_LIGHT_MAINTENANCE);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001644 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
1645 break;
1646 }
1647 }
1648
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001649 void stepIdleStateLocked(String reason) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001650 if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001651 EventLogTags.writeDeviceIdleStep();
1652
1653 final long now = SystemClock.elapsedRealtime();
Adam Lesinski31c05d12015-06-09 17:34:04 -07001654 if ((now+mConstants.MIN_TIME_TO_ALARM) > mAlarmManager.getNextWakeFromIdleTime()) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001655 // Whoops, there is an upcoming alarm. We don't actually want to go idle.
1656 if (mState != STATE_ACTIVE) {
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001657 becomeActiveLocked("alarm", Process.myUid());
Koji Fukui27b33302015-12-16 19:43:01 +09001658 becomeInactiveIfAppropriateLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001659 }
1660 return;
1661 }
1662
1663 switch (mState) {
1664 case STATE_INACTIVE:
1665 // We have now been inactive long enough, it is time to start looking
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001666 // for motion and sleep some more while doing so.
1667 startMonitoringMotionLocked();
Adam Lesinski31c05d12015-06-09 17:34:04 -07001668 scheduleAlarmLocked(mConstants.IDLE_AFTER_INACTIVE_TIMEOUT, false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001669 // Reset the upcoming idle delays.
Adam Lesinski31c05d12015-06-09 17:34:04 -07001670 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
1671 mNextIdleDelay = mConstants.IDLE_TIMEOUT;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001672 mState = STATE_IDLE_PENDING;
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001673 if (DEBUG) Slog.d(TAG, "Moved from STATE_INACTIVE to STATE_IDLE_PENDING.");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001674 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001675 break;
1676 case STATE_IDLE_PENDING:
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001677 mState = STATE_SENSING;
1678 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING.");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001679 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackborn18acb552015-10-26 14:31:07 -07001680 scheduleAlarmLocked(mConstants.SENSING_TIMEOUT, false);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001681 cancelLocatingLocked();
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001682 mAnyMotionDetector.checkForAnyMotion();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001683 mNotMoving = false;
1684 mLocated = false;
1685 mLastGenericLocation = null;
1686 mLastGpsLocation = null;
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001687 break;
1688 case STATE_SENSING:
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001689 mState = STATE_LOCATING;
1690 if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING.");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001691 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001692 scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT, false);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001693 if (mLocationManager != null
1694 && mLocationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
1695 mLocationManager.requestLocationUpdates(mLocationRequest,
1696 mGenericLocationListener, mHandler.getLooper());
1697 mLocating = true;
1698 } else {
1699 mHasNetworkLocation = false;
1700 }
1701 if (mLocationManager != null
1702 && mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
1703 mHasGps = true;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001704 mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5,
1705 mGpsLocationListener, mHandler.getLooper());
Joe LaPenna23d681b2015-08-27 15:12:11 -07001706 mLocating = true;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001707 } else {
Joe LaPenna23d681b2015-08-27 15:12:11 -07001708 mHasGps = false;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001709 }
Joe LaPenna23d681b2015-08-27 15:12:11 -07001710 // If we have a location provider, we're all set, the listeners will move state
1711 // forward.
1712 if (mLocating) {
1713 break;
1714 }
1715
1716 // Otherwise, we have to move from locating into idle maintenance.
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001717 case STATE_LOCATING:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001718 cancelAlarmLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001719 cancelLocatingLocked();
1720 mAnyMotionDetector.stop();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001721 case STATE_IDLE_MAINTENANCE:
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001722 scheduleAlarmLocked(mNextIdleDelay, true);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001723 if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay +
1724 " ms.");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001725 mNextIdleDelay = (long)(mNextIdleDelay * mConstants.IDLE_FACTOR);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001726 if (DEBUG) Slog.d(TAG, "Setting mNextIdleDelay = " + mNextIdleDelay);
Adam Lesinski31c05d12015-06-09 17:34:04 -07001727 mNextIdleDelay = Math.min(mNextIdleDelay, mConstants.MAX_IDLE_TIMEOUT);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001728 mState = STATE_IDLE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001729 if (mLightState != LIGHT_STATE_OVERRIDE) {
1730 mLightState = LIGHT_STATE_OVERRIDE;
1731 cancelLightAlarmLocked();
1732 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001733 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001734 addEvent(EVENT_FULL_IDLE);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001735 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON);
1736 break;
1737 case STATE_IDLE:
1738 // We have been idling long enough, now it is time to do some work.
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001739 mActiveIdleOpCount = 1;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001740 scheduleAlarmLocked(mNextIdlePendingDelay, false);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001741 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE to STATE_IDLE_MAINTENANCE. " +
1742 "Next alarm in " + mNextIdlePendingDelay + " ms.");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001743 mNextIdlePendingDelay = Math.min(mConstants.MAX_IDLE_PENDING_TIMEOUT,
1744 (long)(mNextIdlePendingDelay * mConstants.IDLE_PENDING_FACTOR));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001745 mState = STATE_IDLE_MAINTENANCE;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001746 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001747 addEvent(EVENT_FULL_MAINTENANCE);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001748 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
1749 break;
1750 }
1751 }
1752
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001753 void incActiveIdleOps() {
1754 synchronized (this) {
1755 mActiveIdleOpCount++;
1756 }
1757 }
1758
1759 void decActiveIdleOps() {
1760 synchronized (this) {
1761 mActiveIdleOpCount--;
1762 if (mActiveIdleOpCount <= 0) {
1763 exitMaintenanceEarlyIfNeededLocked();
1764 }
1765 }
1766 }
1767
1768 void downloadServiceActive(IBinder token) {
1769 synchronized (this) {
1770 mDownloadServiceActive = token;
Yao Chenca5edbb2016-01-13 14:44:36 -08001771 reportMaintenanceActivityIfNeededLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001772 try {
1773 token.linkToDeath(new IBinder.DeathRecipient() {
1774 @Override public void binderDied() {
1775 downloadServiceInactive();
1776 }
1777 }, 0);
1778 } catch (RemoteException e) {
1779 mDownloadServiceActive = null;
1780 }
1781 }
1782 }
1783
1784 void downloadServiceInactive() {
1785 synchronized (this) {
1786 mDownloadServiceActive = null;
Yao Chenca5edbb2016-01-13 14:44:36 -08001787 reportMaintenanceActivityIfNeededLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001788 exitMaintenanceEarlyIfNeededLocked();
1789 }
1790 }
1791
1792 void setSyncActive(boolean active) {
1793 synchronized (this) {
1794 mSyncActive = active;
Yao Chenca5edbb2016-01-13 14:44:36 -08001795 reportMaintenanceActivityIfNeededLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001796 if (!active) {
1797 exitMaintenanceEarlyIfNeededLocked();
1798 }
1799 }
1800 }
1801
1802 void setJobsActive(boolean active) {
1803 synchronized (this) {
1804 mJobsActive = active;
Yao Chenca5edbb2016-01-13 14:44:36 -08001805 reportMaintenanceActivityIfNeededLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001806 if (!active) {
1807 exitMaintenanceEarlyIfNeededLocked();
1808 }
1809 }
1810 }
1811
1812 void setAlarmsActive(boolean active) {
1813 synchronized (this) {
1814 mAlarmsActive = active;
1815 if (!active) {
1816 exitMaintenanceEarlyIfNeededLocked();
1817 }
1818 }
1819 }
1820
Yao Chenca5edbb2016-01-13 14:44:36 -08001821 boolean registerMaintenanceActivityListener(IMaintenanceActivityListener listener) {
1822 synchronized (this) {
1823 mMaintenanceActivityListeners.register(listener);
1824 return mReportedMaintenanceActivity;
1825 }
1826 }
1827
1828 void unregisterMaintenanceActivityListener(IMaintenanceActivityListener listener) {
1829 synchronized (this) {
1830 mMaintenanceActivityListeners.unregister(listener);
1831 }
1832 }
1833
1834 void reportMaintenanceActivityIfNeededLocked() {
1835 boolean active = mJobsActive | mSyncActive | (mDownloadServiceActive != null);
1836 if (active == mReportedMaintenanceActivity) {
1837 return;
1838 }
1839 mReportedMaintenanceActivity = active;
1840 Message msg = mHandler.obtainMessage(MSG_REPORT_MAINTENANCE_ACTIVITY,
1841 mReportedMaintenanceActivity ? 1 : 0, 0);
1842 mHandler.sendMessage(msg);
1843 }
1844
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001845 void exitMaintenanceEarlyIfNeededLocked() {
1846 if (mState == STATE_IDLE_MAINTENANCE || mLightState == LIGHT_STATE_IDLE_MAINTENANCE) {
1847 if (mActiveIdleOpCount <= 0 && mDownloadServiceActive == null
1848 && !mSyncActive && !mJobsActive && !mAlarmsActive) {
1849 if (mState == STATE_IDLE_MAINTENANCE) {
1850 stepIdleStateLocked("s:early");
1851 } else {
1852 stepLightIdleStateLocked("s:early");
1853 }
1854 }
1855 }
1856 }
1857
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001858 void motionLocked() {
1859 if (DEBUG) Slog.d(TAG, "motionLocked()");
1860 // The motion sensor will have been disabled at this point
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001861 handleMotionDetectedLocked(mConstants.MOTION_INACTIVE_TIMEOUT, "motion");
1862 }
1863
1864 void handleMotionDetectedLocked(long timeout, String type) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001865 // The device is not yet active, so we want to go back to the pending idle
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001866 // state to wait again for no motion. Note that we only monitor for motion
1867 // after moving out of the inactive state, so no need to worry about that.
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001868 boolean becomeInactive = false;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001869 if (mState != STATE_ACTIVE) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001870 scheduleReportActiveLocked(type, Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001871 mState = STATE_ACTIVE;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001872 mInactiveTimeout = timeout;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001873 mCurIdleBudget = 0;
1874 mMaintenanceStartTime = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001875 EventLogTags.writeDeviceIdle(mState, type);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001876 addEvent(EVENT_NORMAL);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001877 becomeInactive = true;
1878 }
1879 if (mLightState == LIGHT_STATE_OVERRIDE) {
1880 // We went out of light idle mode because we had started full idle mode... let's
1881 // now go back and reset things so we resume light idling if appropriate.
1882 mLightState = STATE_ACTIVE;
1883 EventLogTags.writeDeviceIdleLight(mLightState, type);
1884 becomeInactive = true;
1885 }
1886 if (becomeInactive) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001887 becomeInactiveIfAppropriateLocked();
1888 }
1889 }
1890
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001891 void receivedGenericLocationLocked(Location location) {
1892 if (mState != STATE_LOCATING) {
1893 cancelLocatingLocked();
1894 return;
1895 }
1896 if (DEBUG) Slog.d(TAG, "Generic location: " + location);
1897 mLastGenericLocation = new Location(location);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001898 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHasGps) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001899 return;
1900 }
1901 mLocated = true;
1902 if (mNotMoving) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001903 stepIdleStateLocked("s:location");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001904 }
1905 }
1906
1907 void receivedGpsLocationLocked(Location location) {
1908 if (mState != STATE_LOCATING) {
1909 cancelLocatingLocked();
1910 return;
1911 }
1912 if (DEBUG) Slog.d(TAG, "GPS location: " + location);
1913 mLastGpsLocation = new Location(location);
1914 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY) {
1915 return;
1916 }
1917 mLocated = true;
1918 if (mNotMoving) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001919 stepIdleStateLocked("s:gps");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001920 }
1921 }
1922
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001923 void startMonitoringMotionLocked() {
1924 if (DEBUG) Slog.d(TAG, "startMonitoringMotionLocked()");
1925 if (mMotionSensor != null && !mMotionListener.active) {
1926 mMotionListener.registerLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001927 }
1928 }
1929
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001930 void stopMonitoringMotionLocked() {
1931 if (DEBUG) Slog.d(TAG, "stopMonitoringMotionLocked()");
1932 if (mMotionSensor != null && mMotionListener.active) {
1933 mMotionListener.unregisterLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001934 }
1935 }
1936
1937 void cancelAlarmLocked() {
1938 if (mNextAlarmTime != 0) {
1939 mNextAlarmTime = 0;
1940 mAlarmManager.cancel(mAlarmIntent);
1941 }
1942 }
1943
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001944 void cancelLightAlarmLocked() {
1945 if (mNextLightAlarmTime != 0) {
1946 mNextLightAlarmTime = 0;
1947 mAlarmManager.cancel(mLightAlarmIntent);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001948 }
1949 }
1950
1951 void cancelLocatingLocked() {
1952 if (mLocating) {
1953 mLocationManager.removeUpdates(mGenericLocationListener);
1954 mLocationManager.removeUpdates(mGpsLocationListener);
1955 mLocating = false;
1956 }
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001957 }
1958
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001959 void scheduleAlarmLocked(long delay, boolean idleUntil) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001960 if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")");
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001961 if (mMotionSensor == null) {
Joe LaPenna23d681b2015-08-27 15:12:11 -07001962 // If there is no motion sensor on this device, then we won't schedule
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001963 // alarms, because we can't determine if the device is not moving. This effectively
Joe LaPenna23d681b2015-08-27 15:12:11 -07001964 // turns off normal execution of device idling, although it is still possible to
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001965 // manually poke it by pretending like the alarm is going off.
1966 return;
1967 }
1968 mNextAlarmTime = SystemClock.elapsedRealtime() + delay;
1969 if (idleUntil) {
1970 mAlarmManager.setIdleUntil(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1971 mNextAlarmTime, mAlarmIntent);
1972 } else {
1973 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1974 mNextAlarmTime, mAlarmIntent);
1975 }
1976 }
1977
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001978 void scheduleLightAlarmLocked(long delay) {
1979 if (DEBUG) Slog.d(TAG, "scheduleLightAlarmLocked(" + delay + ")");
1980 if (mMotionSensor == null) {
1981 // If there is no motion sensor on this device, then we won't schedule
1982 // alarms, because we can't determine if the device is not moving. This effectively
1983 // turns off normal execution of device idling, although it is still possible to
1984 // manually poke it by pretending like the alarm is going off.
1985 return;
1986 }
1987 mNextLightAlarmTime = SystemClock.elapsedRealtime() + delay;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001988 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001989 mNextLightAlarmTime, mLightAlarmIntent);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001990 }
1991
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001992 private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps,
1993 ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds) {
1994 outAppIds.clear();
1995 for (int i=0; i<systemApps.size(); i++) {
1996 outAppIds.put(systemApps.valueAt(i), true);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001997 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001998 for (int i=0; i<userApps.size(); i++) {
1999 outAppIds.put(userApps.valueAt(i), true);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002000 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002001 int size = outAppIds.size();
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002002 int[] appids = new int[size];
2003 for (int i = 0; i < size; i++) {
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002004 appids[i] = outAppIds.keyAt(i);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002005 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002006 return appids;
2007 }
2008
2009 private void updateWhitelistAppIdsLocked() {
2010 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(mPowerSaveWhitelistAppsExceptIdle,
2011 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistExceptIdleAppIds);
2012 mPowerSaveWhitelistAllAppIdArray = buildAppIdArray(mPowerSaveWhitelistApps,
2013 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistAllAppIds);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002014 if (mLocalPowerManager != null) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002015 if (DEBUG) {
2016 Slog.d(TAG, "Setting wakelock whitelist to "
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002017 + Arrays.toString(mPowerSaveWhitelistAllAppIdArray));
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002018 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002019 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002020 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002021 }
2022
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002023 private void updateTempWhitelistAppIdsLocked() {
2024 final int size = mTempWhitelistAppIdEndTimes.size();
2025 if (mTempWhitelistAppIdArray.length != size) {
2026 mTempWhitelistAppIdArray = new int[size];
2027 }
2028 for (int i = 0; i < size; i++) {
2029 mTempWhitelistAppIdArray[i] = mTempWhitelistAppIdEndTimes.keyAt(i);
2030 }
2031 if (mLocalPowerManager != null) {
2032 if (DEBUG) {
2033 Slog.d(TAG, "Setting wakelock temp whitelist to "
2034 + Arrays.toString(mTempWhitelistAppIdArray));
2035 }
2036 mLocalPowerManager.setDeviceIdleTempWhitelist(mTempWhitelistAppIdArray);
2037 }
2038 }
2039
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002040 private void reportPowerSaveWhitelistChangedLocked() {
2041 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
2042 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Xiaohui Chene4de5a02015-09-22 15:33:31 -07002043 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002044 }
2045
2046 private void reportTempWhitelistChangedLocked() {
2047 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED);
2048 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Xiaohui Chene4de5a02015-09-22 15:33:31 -07002049 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002050 }
2051
2052 void readConfigFileLocked() {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002053 if (DEBUG) Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002054 mPowerSaveWhitelistUserApps.clear();
2055 FileInputStream stream;
2056 try {
2057 stream = mConfigFile.openRead();
2058 } catch (FileNotFoundException e) {
2059 return;
2060 }
2061 try {
2062 XmlPullParser parser = Xml.newPullParser();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01002063 parser.setInput(stream, StandardCharsets.UTF_8.name());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002064 readConfigFileLocked(parser);
2065 } catch (XmlPullParserException e) {
2066 } finally {
2067 try {
2068 stream.close();
2069 } catch (IOException e) {
2070 }
2071 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002072 }
2073
2074 private void readConfigFileLocked(XmlPullParser parser) {
2075 final PackageManager pm = getContext().getPackageManager();
2076
2077 try {
2078 int type;
2079 while ((type = parser.next()) != XmlPullParser.START_TAG
2080 && type != XmlPullParser.END_DOCUMENT) {
2081 ;
2082 }
2083
2084 if (type != XmlPullParser.START_TAG) {
2085 throw new IllegalStateException("no start tag found");
2086 }
2087
2088 int outerDepth = parser.getDepth();
2089 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2090 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2091 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2092 continue;
2093 }
2094
2095 String tagName = parser.getName();
2096 if (tagName.equals("wl")) {
2097 String name = parser.getAttributeValue(null, "n");
2098 if (name != null) {
2099 try {
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07002100 ApplicationInfo ai = pm.getApplicationInfo(name,
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07002101 PackageManager.MATCH_UNINSTALLED_PACKAGES);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002102 mPowerSaveWhitelistUserApps.put(ai.packageName,
2103 UserHandle.getAppId(ai.uid));
2104 } catch (PackageManager.NameNotFoundException e) {
2105 }
2106 }
2107 } else {
2108 Slog.w(TAG, "Unknown element under <config>: "
2109 + parser.getName());
2110 XmlUtils.skipCurrentTag(parser);
2111 }
2112 }
2113
2114 } catch (IllegalStateException e) {
2115 Slog.w(TAG, "Failed parsing config " + e);
2116 } catch (NullPointerException e) {
2117 Slog.w(TAG, "Failed parsing config " + e);
2118 } catch (NumberFormatException e) {
2119 Slog.w(TAG, "Failed parsing config " + e);
2120 } catch (XmlPullParserException e) {
2121 Slog.w(TAG, "Failed parsing config " + e);
2122 } catch (IOException e) {
2123 Slog.w(TAG, "Failed parsing config " + e);
2124 } catch (IndexOutOfBoundsException e) {
2125 Slog.w(TAG, "Failed parsing config " + e);
2126 }
2127 }
2128
2129 void writeConfigFileLocked() {
2130 mHandler.removeMessages(MSG_WRITE_CONFIG);
2131 mHandler.sendEmptyMessageDelayed(MSG_WRITE_CONFIG, 5000);
2132 }
2133
2134 void handleWriteConfigFile() {
2135 final ByteArrayOutputStream memStream = new ByteArrayOutputStream();
2136
2137 try {
2138 synchronized (this) {
2139 XmlSerializer out = new FastXmlSerializer();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01002140 out.setOutput(memStream, StandardCharsets.UTF_8.name());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002141 writeConfigFileLocked(out);
2142 }
2143 } catch (IOException e) {
2144 }
2145
2146 synchronized (mConfigFile) {
2147 FileOutputStream stream = null;
2148 try {
2149 stream = mConfigFile.startWrite();
2150 memStream.writeTo(stream);
2151 stream.flush();
2152 FileUtils.sync(stream);
2153 stream.close();
2154 mConfigFile.finishWrite(stream);
2155 } catch (IOException e) {
2156 Slog.w(TAG, "Error writing config file", e);
2157 mConfigFile.failWrite(stream);
2158 }
2159 }
2160 }
2161
2162 void writeConfigFileLocked(XmlSerializer out) throws IOException {
2163 out.startDocument(null, true);
2164 out.startTag(null, "config");
2165 for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) {
2166 String name = mPowerSaveWhitelistUserApps.keyAt(i);
2167 out.startTag(null, "wl");
2168 out.attribute(null, "n", name);
2169 out.endTag(null, "wl");
2170 }
2171 out.endTag(null, "config");
2172 out.endDocument();
2173 }
2174
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002175 static void dumpHelp(PrintWriter pw) {
2176 pw.println("Device idle controller (deviceidle) commands:");
2177 pw.println(" help");
2178 pw.println(" Print this help text.");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002179 pw.println(" step");
2180 pw.println(" Immediately step to next state, without waiting for alarm.");
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002181 pw.println(" light-step");
2182 pw.println(" Immediately step to next light idle state, without waiting for alarm.");
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002183 pw.println(" force-idle");
2184 pw.println(" Force directly into idle mode, regardless of other device state.");
2185 pw.println(" Use \"step\" to get out.");
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002186 pw.println(" disable");
2187 pw.println(" Completely disable device idle mode.");
2188 pw.println(" enable");
2189 pw.println(" Re-enable device idle mode after it had previously been disabled.");
Dianne Hackborn92617032015-06-19 15:32:19 -07002190 pw.println(" enabled");
2191 pw.println(" Print 1 if device idle mode is currently enabled, else 0.");
Dianne Hackborn1b139682015-07-06 15:13:37 -07002192 pw.println(" whitelist");
2193 pw.println(" Print currently whitelisted apps.");
Dianne Hackborn92617032015-06-19 15:32:19 -07002194 pw.println(" whitelist [package ...]");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002195 pw.println(" Add (prefix with +) or remove (prefix with -) packages.");
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002196 pw.println(" tempwhitelist [-u] [package ..]");
Dianne Hackborn92617032015-06-19 15:32:19 -07002197 pw.println(" Temporarily place packages in whitelist for 10 seconds.");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002198 }
2199
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002200 class Shell extends ShellCommand {
2201 int userId = UserHandle.USER_SYSTEM;
2202
2203 @Override
2204 public int onCommand(String cmd) {
2205 return onShellCommand(this, cmd);
2206 }
2207
2208 @Override
2209 public void onHelp() {
2210 PrintWriter pw = getOutPrintWriter();
2211 dumpHelp(pw);
2212 }
2213 }
2214
2215 int onShellCommand(Shell shell, String cmd) {
2216 PrintWriter pw = shell.getOutPrintWriter();
2217 if ("step".equals(cmd)) {
2218 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
2219 null);
2220 synchronized (this) {
2221 long token = Binder.clearCallingIdentity();
2222 try {
2223 exitForceIdleLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002224 stepIdleStateLocked("s:shell");
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002225 pw.print("Stepped to: ");
2226 pw.println(stateToString(mState));
2227 } finally {
2228 Binder.restoreCallingIdentity(token);
2229 }
2230 }
2231 } else if ("light-step".equals(cmd)) {
2232 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
2233 null);
2234 synchronized (this) {
2235 long token = Binder.clearCallingIdentity();
2236 try {
2237 exitForceIdleLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002238 stepLightIdleStateLocked("s:shell");
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002239 pw.print("Stepped to: "); pw.println(lightStateToString(mLightState));
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002240 } finally {
2241 Binder.restoreCallingIdentity(token);
2242 }
2243 }
2244 } else if ("force-idle".equals(cmd)) {
2245 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
2246 null);
2247 synchronized (this) {
2248 long token = Binder.clearCallingIdentity();
2249 try {
2250 if (!mEnabled) {
2251 pw.println("Unable to go idle; not enabled");
2252 return -1;
2253 }
2254 mForceIdle = true;
2255 becomeInactiveIfAppropriateLocked();
2256 int curState = mState;
2257 while (curState != STATE_IDLE) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002258 stepIdleStateLocked("s:shell");
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002259 if (curState == mState) {
2260 pw.print("Unable to go idle; stopped at ");
2261 pw.println(stateToString(mState));
2262 exitForceIdleLocked();
2263 return -1;
2264 }
2265 curState = mState;
2266 }
2267 pw.println("Now forced in to idle mode");
2268 } finally {
2269 Binder.restoreCallingIdentity(token);
2270 }
2271 }
2272 } else if ("disable".equals(cmd)) {
2273 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
2274 null);
2275 synchronized (this) {
2276 long token = Binder.clearCallingIdentity();
2277 try {
2278 if (mEnabled) {
2279 mEnabled = false;
2280 becomeActiveLocked("disabled", Process.myUid());
2281 pw.println("Idle mode disabled");
2282 }
2283 } finally {
2284 Binder.restoreCallingIdentity(token);
2285 }
2286 }
2287 } else if ("enable".equals(cmd)) {
2288 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
2289 null);
2290 synchronized (this) {
2291 long token = Binder.clearCallingIdentity();
2292 try {
2293 exitForceIdleLocked();
2294 if (!mEnabled) {
2295 mEnabled = true;
2296 becomeInactiveIfAppropriateLocked();
2297 pw.println("Idle mode enabled");
2298 }
2299 } finally {
2300 Binder.restoreCallingIdentity(token);
2301 }
2302 }
2303 } else if ("enabled".equals(cmd)) {
2304 synchronized (this) {
2305 pw.println(mEnabled ? "1" : " 0");
2306 }
2307 } else if ("whitelist".equals(cmd)) {
2308 long token = Binder.clearCallingIdentity();
2309 try {
2310 String arg = shell.getNextArg();
2311 if (arg != null) {
2312 getContext().enforceCallingOrSelfPermission(
2313 android.Manifest.permission.DEVICE_POWER, null);
2314 do {
2315 if (arg.length() < 1 || (arg.charAt(0) != '-'
Felipe Lemef8a46232016-02-10 13:51:54 -08002316 && arg.charAt(0) != '+' && arg.charAt(0) != '=')) {
2317 pw.println("Package must be prefixed with +, -, or =: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002318 return -1;
2319 }
2320 char op = arg.charAt(0);
2321 String pkg = arg.substring(1);
2322 if (op == '+') {
2323 if (addPowerSaveWhitelistAppInternal(pkg)) {
2324 pw.println("Added: " + pkg);
2325 } else {
2326 pw.println("Unknown package: " + pkg);
2327 }
Felipe Lemef8a46232016-02-10 13:51:54 -08002328 } else if (op == '-') {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002329 if (removePowerSaveWhitelistAppInternal(pkg)) {
2330 pw.println("Removed: " + pkg);
2331 }
Felipe Lemef8a46232016-02-10 13:51:54 -08002332 } else {
2333 pw.println(getPowerSaveWhitelistAppInternal(pkg));
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002334 }
2335 } while ((arg=shell.getNextArg()) != null);
2336 } else {
2337 synchronized (this) {
2338 for (int j=0; j<mPowerSaveWhitelistAppsExceptIdle.size(); j++) {
2339 pw.print("system-excidle,");
2340 pw.print(mPowerSaveWhitelistAppsExceptIdle.keyAt(j));
2341 pw.print(",");
2342 pw.println(mPowerSaveWhitelistAppsExceptIdle.valueAt(j));
2343 }
2344 for (int j=0; j<mPowerSaveWhitelistApps.size(); j++) {
2345 pw.print("system,");
2346 pw.print(mPowerSaveWhitelistApps.keyAt(j));
2347 pw.print(",");
2348 pw.println(mPowerSaveWhitelistApps.valueAt(j));
2349 }
2350 for (int j=0; j<mPowerSaveWhitelistUserApps.size(); j++) {
2351 pw.print("user,");
2352 pw.print(mPowerSaveWhitelistUserApps.keyAt(j));
2353 pw.print(",");
2354 pw.println(mPowerSaveWhitelistUserApps.valueAt(j));
2355 }
2356 }
2357 }
2358 } finally {
2359 Binder.restoreCallingIdentity(token);
2360 }
2361 } else if ("tempwhitelist".equals(cmd)) {
2362 String opt;
2363 while ((opt=shell.getNextOption()) != null) {
2364 if ("-u".equals(opt)) {
2365 opt = shell.getNextArg();
2366 if (opt == null) {
2367 pw.println("-u requires a user number");
2368 return -1;
2369 }
2370 shell.userId = Integer.parseInt(opt);
2371 }
2372 }
2373 String arg = shell.getNextArg();
2374 if (arg != null) {
2375 try {
2376 addPowerSaveTempWhitelistAppChecked(arg, 10000L, shell.userId, "shell");
2377 } catch (RemoteException re) {
2378 pw.println("Failed: " + re);
2379 }
2380 } else {
2381 pw.println("At least one package name must be specified");
2382 return -1;
2383 }
2384 } else {
2385 return shell.handleDefaultCommands(cmd);
2386 }
2387 return 0;
2388 }
2389
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002390 void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2391 if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
2392 != PackageManager.PERMISSION_GRANTED) {
2393 pw.println("Permission Denial: can't dump DeviceIdleController from from pid="
2394 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2395 + " without permission " + android.Manifest.permission.DUMP);
2396 return;
2397 }
2398
2399 if (args != null) {
Xiaohui Chen7c696362015-09-16 09:56:14 -07002400 int userId = UserHandle.USER_SYSTEM;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002401 for (int i=0; i<args.length; i++) {
2402 String arg = args[i];
2403 if ("-h".equals(arg)) {
2404 dumpHelp(pw);
2405 return;
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002406 } else if ("-u".equals(arg)) {
2407 i++;
2408 if (i < args.length) {
2409 arg = args[i];
2410 userId = Integer.parseInt(arg);
2411 }
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002412 } else if ("-a".equals(arg)) {
2413 // Ignore, we always dump all.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002414 } else if (arg.length() > 0 && arg.charAt(0) == '-'){
2415 pw.println("Unknown option: " + arg);
2416 return;
2417 } else {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002418 Shell shell = new Shell();
2419 shell.userId = userId;
2420 String[] newArgs = new String[args.length-i];
2421 System.arraycopy(args, i, newArgs, 0, args.length-i);
2422 shell.exec(mBinderService, null, fd, null, newArgs, new ResultReceiver(null));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002423 return;
2424 }
2425 }
2426 }
2427
2428 synchronized (this) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002429 mConstants.dump(pw);
2430
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002431 if (mEventCmds[0] != EVENT_NULL) {
2432 pw.println(" Idling history:");
2433 long now = SystemClock.elapsedRealtime();
2434 for (int i=EVENT_BUFFER_SIZE-1; i>=0; i--) {
2435 int cmd = mEventCmds[i];
2436 if (cmd == EVENT_NULL) {
2437 continue;
2438 }
2439 String label;
2440 switch (mEventCmds[i]) {
2441 case EVENT_NORMAL: label = " normal"; break;
2442 case EVENT_LIGHT_IDLE: label = " light-idle"; break;
2443 case EVENT_LIGHT_MAINTENANCE: label = "light-maint"; break;
2444 case EVENT_FULL_IDLE: label = " full-idle"; break;
2445 case EVENT_FULL_MAINTENANCE: label = " full-maint"; break;
2446 default: label = " ??"; break;
2447 }
2448 pw.print(" ");
2449 pw.print(label);
2450 pw.print(": ");
2451 TimeUtils.formatDuration(mEventTimes[i], now, pw);;
2452 pw.println();
2453 }
2454 }
2455
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002456 int size = mPowerSaveWhitelistAppsExceptIdle.size();
2457 if (size > 0) {
2458 pw.println(" Whitelist (except idle) system apps:");
2459 for (int i = 0; i < size; i++) {
2460 pw.print(" ");
2461 pw.println(mPowerSaveWhitelistAppsExceptIdle.keyAt(i));
2462 }
2463 }
2464 size = mPowerSaveWhitelistApps.size();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002465 if (size > 0) {
2466 pw.println(" Whitelist system apps:");
2467 for (int i = 0; i < size; i++) {
2468 pw.print(" ");
2469 pw.println(mPowerSaveWhitelistApps.keyAt(i));
2470 }
2471 }
2472 size = mPowerSaveWhitelistUserApps.size();
2473 if (size > 0) {
2474 pw.println(" Whitelist user apps:");
2475 for (int i = 0; i < size; i++) {
2476 pw.print(" ");
2477 pw.println(mPowerSaveWhitelistUserApps.keyAt(i));
2478 }
2479 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002480 size = mPowerSaveWhitelistExceptIdleAppIds.size();
2481 if (size > 0) {
2482 pw.println(" Whitelist (except idle) all app ids:");
2483 for (int i = 0; i < size; i++) {
2484 pw.print(" ");
2485 pw.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
2486 pw.println();
2487 }
2488 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002489 size = mPowerSaveWhitelistAllAppIds.size();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002490 if (size > 0) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002491 pw.println(" Whitelist all app ids:");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002492 for (int i = 0; i < size; i++) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002493 pw.print(" ");
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002494 pw.print(mPowerSaveWhitelistAllAppIds.keyAt(i));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002495 pw.println();
2496 }
2497 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002498 size = mTempWhitelistAppIdEndTimes.size();
2499 if (size > 0) {
2500 pw.println(" Temp whitelist schedule:");
2501 final long timeNow = SystemClock.elapsedRealtime();
2502 for (int i = 0; i < size; i++) {
2503 pw.print(" UID=");
2504 pw.print(mTempWhitelistAppIdEndTimes.keyAt(i));
2505 pw.print(": ");
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002506 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.valueAt(i);
2507 TimeUtils.formatDuration(entry.first.value, timeNow, pw);
2508 pw.print(" - ");
2509 pw.println(entry.second);
Dianne Hackborna750a632015-06-16 17:18:23 -07002510 }
2511 }
2512 size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0;
2513 if (size > 0) {
2514 pw.println(" Temp whitelist app ids:");
2515 for (int i = 0; i < size; i++) {
2516 pw.print(" ");
2517 pw.print(mTempWhitelistAppIdArray[i]);
2518 pw.println();
2519 }
2520 }
Adam Lesinski31c05d12015-06-09 17:34:04 -07002521
Dianne Hackborn92617032015-06-19 15:32:19 -07002522 pw.print(" mEnabled="); pw.println(mEnabled);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002523 pw.print(" mForceIdle="); pw.println(mForceIdle);
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002524 pw.print(" mMotionSensor="); pw.println(mMotionSensor);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002525 pw.print(" mCurDisplay="); pw.println(mCurDisplay);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002526 pw.print(" mScreenOn="); pw.println(mScreenOn);
2527 pw.print(" mCharging="); pw.println(mCharging);
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002528 pw.print(" mMotionActive="); pw.println(mMotionListener.active);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002529 pw.print(" mNotMoving="); pw.println(mNotMoving);
Joe LaPenna23d681b2015-08-27 15:12:11 -07002530 pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHasGps=");
2531 pw.print(mHasGps); pw.print(" mHasNetwork=");
2532 pw.print(mHasNetworkLocation); pw.print(" mLocated="); pw.println(mLocated);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002533 if (mLastGenericLocation != null) {
2534 pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation);
2535 }
2536 if (mLastGpsLocation != null) {
2537 pw.print(" mLastGpsLocation="); pw.println(mLastGpsLocation);
2538 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002539 pw.print(" mState="); pw.print(stateToString(mState));
2540 pw.print(" mLightState=");
2541 pw.println(lightStateToString(mLightState));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002542 pw.print(" mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw);
2543 pw.println();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002544 if (mActiveIdleOpCount != 0) {
2545 pw.print(" mActiveIdleOpCount="); pw.println(mActiveIdleOpCount);
2546 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002547 if (mNextAlarmTime != 0) {
2548 pw.print(" mNextAlarmTime=");
2549 TimeUtils.formatDuration(mNextAlarmTime, SystemClock.elapsedRealtime(), pw);
2550 pw.println();
2551 }
2552 if (mNextIdlePendingDelay != 0) {
2553 pw.print(" mNextIdlePendingDelay=");
2554 TimeUtils.formatDuration(mNextIdlePendingDelay, pw);
2555 pw.println();
2556 }
2557 if (mNextIdleDelay != 0) {
2558 pw.print(" mNextIdleDelay=");
2559 TimeUtils.formatDuration(mNextIdleDelay, pw);
2560 pw.println();
2561 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002562 if (mNextLightAlarmTime != 0) {
2563 pw.print(" mNextLightAlarmTime=");
2564 TimeUtils.formatDuration(mNextLightAlarmTime, SystemClock.elapsedRealtime(), pw);
2565 pw.println();
2566 }
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002567 if (mCurIdleBudget != 0) {
2568 pw.print(" mCurIdleBudget=");
2569 TimeUtils.formatDuration(mCurIdleBudget, pw);
2570 pw.println();
2571 }
2572 if (mMaintenanceStartTime != 0) {
2573 pw.print(" mMaintenanceStartTime=");
2574 TimeUtils.formatDuration(mMaintenanceStartTime, SystemClock.elapsedRealtime(), pw);
2575 pw.println();
2576 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002577 if (mSyncActive) {
2578 pw.print(" mSyncActive="); pw.println(mSyncActive);
2579 }
2580 if (mJobsActive) {
2581 pw.print(" mJobsActive="); pw.println(mJobsActive);
2582 }
2583 if (mAlarmsActive) {
2584 pw.print(" mAlarmsActive="); pw.println(mAlarmsActive);
2585 }
2586 if (mDownloadServiceActive != null) {
2587 pw.print(" mDownloadServiceActive="); pw.println(mDownloadServiceActive);
2588 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002589 }
2590 }
2591}