blob: 9bd79c9cf6c94367bc687778300d470f02d6cf26 [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
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001265 public String[] getSystemPowerWhitelistExceptIdleInternal() {
1266 synchronized (this) {
1267 int size = mPowerSaveWhitelistAppsExceptIdle.size();
1268 String[] apps = new String[size];
1269 for (int i = 0; i < size; i++) {
1270 apps[i] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i);
1271 }
1272 return apps;
1273 }
1274 }
1275
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001276 public String[] getSystemPowerWhitelistInternal() {
1277 synchronized (this) {
1278 int size = mPowerSaveWhitelistApps.size();
1279 String[] apps = new String[size];
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001280 for (int i = 0; i < size; i++) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001281 apps[i] = mPowerSaveWhitelistApps.keyAt(i);
1282 }
1283 return apps;
1284 }
1285 }
1286
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001287 public String[] getFullPowerWhitelistExceptIdleInternal() {
1288 synchronized (this) {
1289 int size = mPowerSaveWhitelistAppsExceptIdle.size() + mPowerSaveWhitelistUserApps.size();
1290 String[] apps = new String[size];
1291 int cur = 0;
1292 for (int i = 0; i < mPowerSaveWhitelistAppsExceptIdle.size(); i++) {
1293 apps[cur] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i);
1294 cur++;
1295 }
1296 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
1297 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i);
1298 cur++;
1299 }
1300 return apps;
1301 }
1302 }
1303
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001304 public String[] getFullPowerWhitelistInternal() {
1305 synchronized (this) {
1306 int size = mPowerSaveWhitelistApps.size() + mPowerSaveWhitelistUserApps.size();
1307 String[] apps = new String[size];
1308 int cur = 0;
1309 for (int i = 0; i < mPowerSaveWhitelistApps.size(); i++) {
1310 apps[cur] = mPowerSaveWhitelistApps.keyAt(i);
1311 cur++;
1312 }
1313 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
1314 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i);
1315 cur++;
1316 }
1317 return apps;
1318 }
1319 }
1320
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001321 public boolean isPowerSaveWhitelistExceptIdleAppInternal(String packageName) {
1322 synchronized (this) {
1323 return mPowerSaveWhitelistAppsExceptIdle.containsKey(packageName)
1324 || mPowerSaveWhitelistUserApps.containsKey(packageName);
1325 }
1326 }
1327
Amith Yamasani06bf8242015-05-08 16:36:21 -07001328 public boolean isPowerSaveWhitelistAppInternal(String packageName) {
1329 synchronized (this) {
1330 return mPowerSaveWhitelistApps.containsKey(packageName)
1331 || mPowerSaveWhitelistUserApps.containsKey(packageName);
1332 }
1333 }
1334
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001335 public int[] getAppIdWhitelistExceptIdleInternal() {
1336 synchronized (this) {
1337 return mPowerSaveWhitelistExceptIdleAppIdArray;
1338 }
1339 }
1340
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001341 public int[] getAppIdWhitelistInternal() {
1342 synchronized (this) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001343 return mPowerSaveWhitelistAllAppIdArray;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001344 }
1345 }
1346
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001347 public int[] getAppIdTempWhitelistInternal() {
1348 synchronized (this) {
1349 return mTempWhitelistAppIdArray;
1350 }
1351 }
1352
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001353 void addPowerSaveTempWhitelistAppChecked(String packageName, long duration,
1354 int userId, String reason) throws RemoteException {
1355 getContext().enforceCallingPermission(
1356 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
1357 "No permission to change device idle whitelist");
1358 final int callingUid = Binder.getCallingUid();
1359 userId = ActivityManagerNative.getDefault().handleIncomingUser(
1360 Binder.getCallingPid(),
1361 callingUid,
1362 userId,
1363 /*allowAll=*/ false,
1364 /*requireFull=*/ false,
1365 "addPowerSaveTempWhitelistApp", null);
1366 final long token = Binder.clearCallingIdentity();
1367 try {
1368 addPowerSaveTempWhitelistAppInternal(callingUid,
1369 packageName, duration, userId, true, reason);
1370 } finally {
1371 Binder.restoreCallingIdentity(token);
1372 }
1373 }
1374
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001375 /**
1376 * Adds an app to the temporary whitelist and resets the endTime for granting the
1377 * app an exemption to access network and acquire wakelocks.
1378 */
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001379 void addPowerSaveTempWhitelistAppInternal(int callingUid, String packageName,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001380 long duration, int userId, boolean sync, String reason) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001381 try {
Jeff Sharkeye06b4d12016-01-06 14:51:50 -07001382 int uid = getContext().getPackageManager().getPackageUidAsUser(packageName, userId);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001383 int appId = UserHandle.getAppId(uid);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001384 addPowerSaveTempWhitelistAppDirectInternal(callingUid, appId, duration, sync, reason);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001385 } catch (NameNotFoundException e) {
1386 }
1387 }
1388
Dianne Hackborna750a632015-06-16 17:18:23 -07001389 /**
1390 * Adds an app to the temporary whitelist and resets the endTime for granting the
1391 * app an exemption to access network and acquire wakelocks.
1392 */
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001393 void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int appId,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001394 long duration, boolean sync, String reason) {
Dianne Hackborna750a632015-06-16 17:18:23 -07001395 final long timeNow = SystemClock.elapsedRealtime();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001396 Runnable networkPolicyTempWhitelistCallback = null;
Dianne Hackborna750a632015-06-16 17:18:23 -07001397 synchronized (this) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001398 int callingAppId = UserHandle.getAppId(callingUid);
1399 if (callingAppId >= Process.FIRST_APPLICATION_UID) {
1400 if (!mPowerSaveWhitelistSystemAppIds.get(callingAppId)) {
1401 throw new SecurityException("Calling app " + UserHandle.formatUid(callingUid)
1402 + " is not on whitelist");
1403 }
1404 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001405 duration = Math.min(duration, mConstants.MAX_TEMP_APP_WHITELIST_DURATION);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001406 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId);
1407 final boolean newEntry = entry == null;
Dianne Hackborna750a632015-06-16 17:18:23 -07001408 // Set the new end time
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001409 if (newEntry) {
1410 entry = new Pair<>(new MutableLong(0), reason);
1411 mTempWhitelistAppIdEndTimes.put(appId, entry);
1412 }
1413 entry.first.value = timeNow + duration;
Dianne Hackborna750a632015-06-16 17:18:23 -07001414 if (DEBUG) {
1415 Slog.d(TAG, "Adding AppId " + appId + " to temp whitelist");
1416 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001417 if (newEntry) {
Dianne Hackborna750a632015-06-16 17:18:23 -07001418 // No pending timeout for the app id, post a delayed message
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001419 try {
1420 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_START,
1421 reason, appId);
1422 } catch (RemoteException e) {
1423 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001424 postTempActiveTimeoutMessage(appId, duration);
1425 updateTempWhitelistAppIdsLocked();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001426 if (mNetworkPolicyTempWhitelistCallback != null) {
1427 if (!sync) {
1428 mHandler.post(mNetworkPolicyTempWhitelistCallback);
1429 } else {
1430 networkPolicyTempWhitelistCallback = mNetworkPolicyTempWhitelistCallback;
1431 }
1432 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001433 reportTempWhitelistChangedLocked();
1434 }
1435 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001436 if (networkPolicyTempWhitelistCallback != null) {
1437 networkPolicyTempWhitelistCallback.run();
1438 }
1439 }
1440
1441 public void setNetworkPolicyTempWhitelistCallbackInternal(Runnable callback) {
1442 synchronized (this) {
1443 mNetworkPolicyTempWhitelistCallback = callback;
1444 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001445 }
1446
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001447 private void postTempActiveTimeoutMessage(int uid, long delay) {
1448 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, uid, 0),
1449 delay);
1450 }
1451
1452 void checkTempAppWhitelistTimeout(int uid) {
Dianne Hackborna750a632015-06-16 17:18:23 -07001453 final long timeNow = SystemClock.elapsedRealtime();
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001454 synchronized (this) {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001455 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(uid);
1456 if (entry == null) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001457 // Nothing to do
1458 return;
1459 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001460 if (timeNow >= entry.first.value) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001461 mTempWhitelistAppIdEndTimes.delete(uid);
1462 if (DEBUG) {
1463 Slog.d(TAG, "Removing UID " + uid + " from temp whitelist");
1464 }
1465 updateTempWhitelistAppIdsLocked();
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001466 if (mNetworkPolicyTempWhitelistCallback != null) {
1467 mHandler.post(mNetworkPolicyTempWhitelistCallback);
1468 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001469 reportTempWhitelistChangedLocked();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001470 try {
1471 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH,
1472 entry.second, uid);
1473 } catch (RemoteException e) {
1474 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001475 } else {
1476 // Need more time
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001477 postTempActiveTimeoutMessage(uid, entry.first.value - timeNow);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001478 }
1479 }
1480 }
1481
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001482 public void exitIdleInternal(String reason) {
1483 synchronized (this) {
1484 becomeActiveLocked(reason, Binder.getCallingUid());
1485 }
1486 }
1487
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001488 void updateDisplayLocked() {
1489 mCurDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
1490 // We consider any situation where the display is showing something to be it on,
1491 // because if there is anything shown we are going to be updating it at some
1492 // frequency so can't be allowed to go into deep sleeps.
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001493 boolean screenOn = mCurDisplay.getState() == Display.STATE_ON;
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001494 if (DEBUG) Slog.d(TAG, "updateDisplayLocked: screenOn=" + screenOn);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001495 if (!screenOn && mScreenOn) {
1496 mScreenOn = false;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001497 if (!mForceIdle) {
1498 becomeInactiveIfAppropriateLocked();
1499 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001500 } else if (screenOn) {
1501 mScreenOn = true;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001502 if (!mForceIdle) {
1503 becomeActiveLocked("screen", Process.myUid());
1504 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001505 }
1506 }
1507
1508 void updateChargingLocked(boolean charging) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001509 if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001510 if (!charging && mCharging) {
1511 mCharging = false;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001512 if (!mForceIdle) {
1513 becomeInactiveIfAppropriateLocked();
1514 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001515 } else if (charging) {
1516 mCharging = charging;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001517 if (!mForceIdle) {
1518 becomeActiveLocked("charging", Process.myUid());
1519 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001520 }
1521 }
1522
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001523 void scheduleReportActiveLocked(String activeReason, int activeUid) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001524 Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid, 0, activeReason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001525 mHandler.sendMessage(msg);
1526 }
1527
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001528 void becomeActiveLocked(String activeReason, int activeUid) {
1529 if (DEBUG) Slog.i(TAG, "becomeActiveLocked, reason = " + activeReason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001530 if (mState != STATE_ACTIVE || mLightState != STATE_ACTIVE) {
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001531 EventLogTags.writeDeviceIdle(STATE_ACTIVE, activeReason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001532 EventLogTags.writeDeviceIdleLight(LIGHT_STATE_ACTIVE, activeReason);
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001533 scheduleReportActiveLocked(activeReason, activeUid);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001534 mState = STATE_ACTIVE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001535 mLightState = LIGHT_STATE_ACTIVE;
Adam Lesinski31c05d12015-06-09 17:34:04 -07001536 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001537 mCurIdleBudget = 0;
1538 mMaintenanceStartTime = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001539 resetIdleManagementLocked();
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001540 resetLightIdleManagementLocked();
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001541 addEvent(EVENT_NORMAL);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001542 }
1543 }
1544
1545 void becomeInactiveIfAppropriateLocked() {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001546 if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()");
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001547 if (((!mScreenOn && !mCharging) || mForceIdle) && mEnabled) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001548 // Screen has turned off; we are now going to become inactive and start
1549 // waiting to see if we will ultimately go idle.
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001550 if (mState == STATE_ACTIVE) {
1551 mState = STATE_INACTIVE;
1552 if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE");
1553 resetIdleManagementLocked();
1554 scheduleAlarmLocked(mInactiveTimeout, false);
1555 EventLogTags.writeDeviceIdle(mState, "no activity");
1556 }
1557 if (mLightState == LIGHT_STATE_ACTIVE) {
1558 mLightState = LIGHT_STATE_INACTIVE;
1559 if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE");
1560 resetLightIdleManagementLocked();
1561 scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_TIMEOUT);
1562 EventLogTags.writeDeviceIdleLight(mLightState, "no activity");
1563 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001564 }
1565 }
1566
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001567 void resetIdleManagementLocked() {
1568 mNextIdlePendingDelay = 0;
1569 mNextIdleDelay = 0;
1570 cancelAlarmLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001571 cancelLocatingLocked();
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001572 stopMonitoringMotionLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001573 mAnyMotionDetector.stop();
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001574 }
1575
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001576 void resetLightIdleManagementLocked() {
1577 cancelLightAlarmLocked();
1578 }
1579
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001580 void exitForceIdleLocked() {
1581 if (mForceIdle) {
1582 mForceIdle = false;
1583 if (mScreenOn || mCharging) {
1584 becomeActiveLocked("exit-force-idle", Process.myUid());
1585 }
1586 }
1587 }
1588
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001589 void stepLightIdleStateLocked(String reason) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001590 if (mLightState == LIGHT_STATE_OVERRIDE) {
1591 // If we are already in full device idle mode, then
1592 // there is nothing left to do for light mode.
1593 return;
1594 }
1595
1596 if (DEBUG) Slog.d(TAG, "stepLightIdleStateLocked: mLightState=" + mLightState);
1597 EventLogTags.writeDeviceIdleLightStep();
1598
1599 switch (mLightState) {
1600 case LIGHT_STATE_INACTIVE:
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001601 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
1602 mMaintenanceStartTime = 0;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001603 case LIGHT_STATE_IDLE_MAINTENANCE:
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001604 if (mMaintenanceStartTime != 0) {
1605 long duration = SystemClock.elapsedRealtime() - mMaintenanceStartTime;
1606 if (duration < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
1607 // We didn't use up all of our minimum budget; add this to the reserve.
1608 mCurIdleBudget += (mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET-duration);
1609 } else {
1610 // We used more than our minimum budget; this comes out of the reserve.
1611 mCurIdleBudget -= (duration-mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET);
1612 }
1613 }
1614 mMaintenanceStartTime = 0;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001615 scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_TIMEOUT);
1616 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_STATE_IDLE.");
1617 mLightState = LIGHT_STATE_IDLE;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001618 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001619 addEvent(EVENT_LIGHT_IDLE);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001620 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON_LIGHT);
1621 break;
1622 case LIGHT_STATE_IDLE:
1623 // We have been idling long enough, now it is time to do some work.
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001624 mActiveIdleOpCount = 1;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001625 mMaintenanceStartTime = SystemClock.elapsedRealtime();
1626 if (mCurIdleBudget < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
1627 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
1628 } else if (mCurIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) {
1629 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
1630 }
1631 mMaintenanceStartTime = SystemClock.elapsedRealtime();
1632 scheduleLightAlarmLocked(mCurIdleBudget);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001633 if (DEBUG) Slog.d(TAG,
1634 "Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE.");
1635 mLightState = LIGHT_STATE_IDLE_MAINTENANCE;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001636 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001637 addEvent(EVENT_LIGHT_MAINTENANCE);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001638 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
1639 break;
1640 }
1641 }
1642
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001643 void stepIdleStateLocked(String reason) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001644 if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001645 EventLogTags.writeDeviceIdleStep();
1646
1647 final long now = SystemClock.elapsedRealtime();
Adam Lesinski31c05d12015-06-09 17:34:04 -07001648 if ((now+mConstants.MIN_TIME_TO_ALARM) > mAlarmManager.getNextWakeFromIdleTime()) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001649 // Whoops, there is an upcoming alarm. We don't actually want to go idle.
1650 if (mState != STATE_ACTIVE) {
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001651 becomeActiveLocked("alarm", Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001652 }
1653 return;
1654 }
1655
1656 switch (mState) {
1657 case STATE_INACTIVE:
1658 // We have now been inactive long enough, it is time to start looking
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001659 // for motion and sleep some more while doing so.
1660 startMonitoringMotionLocked();
Adam Lesinski31c05d12015-06-09 17:34:04 -07001661 scheduleAlarmLocked(mConstants.IDLE_AFTER_INACTIVE_TIMEOUT, false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001662 // Reset the upcoming idle delays.
Adam Lesinski31c05d12015-06-09 17:34:04 -07001663 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
1664 mNextIdleDelay = mConstants.IDLE_TIMEOUT;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001665 mState = STATE_IDLE_PENDING;
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001666 if (DEBUG) Slog.d(TAG, "Moved from STATE_INACTIVE to STATE_IDLE_PENDING.");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001667 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001668 break;
1669 case STATE_IDLE_PENDING:
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001670 mState = STATE_SENSING;
1671 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING.");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001672 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackborn18acb552015-10-26 14:31:07 -07001673 scheduleAlarmLocked(mConstants.SENSING_TIMEOUT, false);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001674 cancelLocatingLocked();
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001675 mAnyMotionDetector.checkForAnyMotion();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001676 mNotMoving = false;
1677 mLocated = false;
1678 mLastGenericLocation = null;
1679 mLastGpsLocation = null;
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001680 break;
1681 case STATE_SENSING:
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001682 mState = STATE_LOCATING;
1683 if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING.");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001684 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001685 scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT, false);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001686 if (mLocationManager != null
1687 && mLocationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
1688 mLocationManager.requestLocationUpdates(mLocationRequest,
1689 mGenericLocationListener, mHandler.getLooper());
1690 mLocating = true;
1691 } else {
1692 mHasNetworkLocation = false;
1693 }
1694 if (mLocationManager != null
1695 && mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
1696 mHasGps = true;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001697 mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5,
1698 mGpsLocationListener, mHandler.getLooper());
Joe LaPenna23d681b2015-08-27 15:12:11 -07001699 mLocating = true;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001700 } else {
Joe LaPenna23d681b2015-08-27 15:12:11 -07001701 mHasGps = false;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001702 }
Joe LaPenna23d681b2015-08-27 15:12:11 -07001703 // If we have a location provider, we're all set, the listeners will move state
1704 // forward.
1705 if (mLocating) {
1706 break;
1707 }
1708
1709 // Otherwise, we have to move from locating into idle maintenance.
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001710 case STATE_LOCATING:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001711 cancelAlarmLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001712 cancelLocatingLocked();
1713 mAnyMotionDetector.stop();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001714 case STATE_IDLE_MAINTENANCE:
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001715 scheduleAlarmLocked(mNextIdleDelay, true);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001716 if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay +
1717 " ms.");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001718 mNextIdleDelay = (long)(mNextIdleDelay * mConstants.IDLE_FACTOR);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001719 if (DEBUG) Slog.d(TAG, "Setting mNextIdleDelay = " + mNextIdleDelay);
Adam Lesinski31c05d12015-06-09 17:34:04 -07001720 mNextIdleDelay = Math.min(mNextIdleDelay, mConstants.MAX_IDLE_TIMEOUT);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001721 mState = STATE_IDLE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001722 if (mLightState != LIGHT_STATE_OVERRIDE) {
1723 mLightState = LIGHT_STATE_OVERRIDE;
1724 cancelLightAlarmLocked();
1725 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001726 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001727 addEvent(EVENT_FULL_IDLE);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001728 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON);
1729 break;
1730 case STATE_IDLE:
1731 // We have been idling long enough, now it is time to do some work.
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001732 mActiveIdleOpCount = 1;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001733 scheduleAlarmLocked(mNextIdlePendingDelay, false);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001734 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE to STATE_IDLE_MAINTENANCE. " +
1735 "Next alarm in " + mNextIdlePendingDelay + " ms.");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001736 mNextIdlePendingDelay = Math.min(mConstants.MAX_IDLE_PENDING_TIMEOUT,
1737 (long)(mNextIdlePendingDelay * mConstants.IDLE_PENDING_FACTOR));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001738 mState = STATE_IDLE_MAINTENANCE;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001739 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001740 addEvent(EVENT_FULL_MAINTENANCE);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001741 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
1742 break;
1743 }
1744 }
1745
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001746 void incActiveIdleOps() {
1747 synchronized (this) {
1748 mActiveIdleOpCount++;
1749 }
1750 }
1751
1752 void decActiveIdleOps() {
1753 synchronized (this) {
1754 mActiveIdleOpCount--;
1755 if (mActiveIdleOpCount <= 0) {
1756 exitMaintenanceEarlyIfNeededLocked();
1757 }
1758 }
1759 }
1760
1761 void downloadServiceActive(IBinder token) {
1762 synchronized (this) {
1763 mDownloadServiceActive = token;
Yao Chenca5edbb2016-01-13 14:44:36 -08001764 reportMaintenanceActivityIfNeededLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001765 try {
1766 token.linkToDeath(new IBinder.DeathRecipient() {
1767 @Override public void binderDied() {
1768 downloadServiceInactive();
1769 }
1770 }, 0);
1771 } catch (RemoteException e) {
1772 mDownloadServiceActive = null;
1773 }
1774 }
1775 }
1776
1777 void downloadServiceInactive() {
1778 synchronized (this) {
1779 mDownloadServiceActive = null;
Yao Chenca5edbb2016-01-13 14:44:36 -08001780 reportMaintenanceActivityIfNeededLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001781 exitMaintenanceEarlyIfNeededLocked();
1782 }
1783 }
1784
1785 void setSyncActive(boolean active) {
1786 synchronized (this) {
1787 mSyncActive = active;
Yao Chenca5edbb2016-01-13 14:44:36 -08001788 reportMaintenanceActivityIfNeededLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001789 if (!active) {
1790 exitMaintenanceEarlyIfNeededLocked();
1791 }
1792 }
1793 }
1794
1795 void setJobsActive(boolean active) {
1796 synchronized (this) {
1797 mJobsActive = active;
Yao Chenca5edbb2016-01-13 14:44:36 -08001798 reportMaintenanceActivityIfNeededLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001799 if (!active) {
1800 exitMaintenanceEarlyIfNeededLocked();
1801 }
1802 }
1803 }
1804
1805 void setAlarmsActive(boolean active) {
1806 synchronized (this) {
1807 mAlarmsActive = active;
1808 if (!active) {
1809 exitMaintenanceEarlyIfNeededLocked();
1810 }
1811 }
1812 }
1813
Yao Chenca5edbb2016-01-13 14:44:36 -08001814 boolean registerMaintenanceActivityListener(IMaintenanceActivityListener listener) {
1815 synchronized (this) {
1816 mMaintenanceActivityListeners.register(listener);
1817 return mReportedMaintenanceActivity;
1818 }
1819 }
1820
1821 void unregisterMaintenanceActivityListener(IMaintenanceActivityListener listener) {
1822 synchronized (this) {
1823 mMaintenanceActivityListeners.unregister(listener);
1824 }
1825 }
1826
1827 void reportMaintenanceActivityIfNeededLocked() {
1828 boolean active = mJobsActive | mSyncActive | (mDownloadServiceActive != null);
1829 if (active == mReportedMaintenanceActivity) {
1830 return;
1831 }
1832 mReportedMaintenanceActivity = active;
1833 Message msg = mHandler.obtainMessage(MSG_REPORT_MAINTENANCE_ACTIVITY,
1834 mReportedMaintenanceActivity ? 1 : 0, 0);
1835 mHandler.sendMessage(msg);
1836 }
1837
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001838 void exitMaintenanceEarlyIfNeededLocked() {
1839 if (mState == STATE_IDLE_MAINTENANCE || mLightState == LIGHT_STATE_IDLE_MAINTENANCE) {
1840 if (mActiveIdleOpCount <= 0 && mDownloadServiceActive == null
1841 && !mSyncActive && !mJobsActive && !mAlarmsActive) {
1842 if (mState == STATE_IDLE_MAINTENANCE) {
1843 stepIdleStateLocked("s:early");
1844 } else {
1845 stepLightIdleStateLocked("s:early");
1846 }
1847 }
1848 }
1849 }
1850
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001851 void motionLocked() {
1852 if (DEBUG) Slog.d(TAG, "motionLocked()");
1853 // The motion sensor will have been disabled at this point
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001854 handleMotionDetectedLocked(mConstants.MOTION_INACTIVE_TIMEOUT, "motion");
1855 }
1856
1857 void handleMotionDetectedLocked(long timeout, String type) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001858 // The device is not yet active, so we want to go back to the pending idle
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001859 // state to wait again for no motion. Note that we only monitor for motion
1860 // after moving out of the inactive state, so no need to worry about that.
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001861 boolean becomeInactive = false;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001862 if (mState != STATE_ACTIVE) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001863 scheduleReportActiveLocked(type, Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001864 mState = STATE_ACTIVE;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001865 mInactiveTimeout = timeout;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001866 mCurIdleBudget = 0;
1867 mMaintenanceStartTime = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001868 EventLogTags.writeDeviceIdle(mState, type);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001869 addEvent(EVENT_NORMAL);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001870 becomeInactive = true;
1871 }
1872 if (mLightState == LIGHT_STATE_OVERRIDE) {
1873 // We went out of light idle mode because we had started full idle mode... let's
1874 // now go back and reset things so we resume light idling if appropriate.
1875 mLightState = STATE_ACTIVE;
1876 EventLogTags.writeDeviceIdleLight(mLightState, type);
1877 becomeInactive = true;
1878 }
1879 if (becomeInactive) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001880 becomeInactiveIfAppropriateLocked();
1881 }
1882 }
1883
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001884 void receivedGenericLocationLocked(Location location) {
1885 if (mState != STATE_LOCATING) {
1886 cancelLocatingLocked();
1887 return;
1888 }
1889 if (DEBUG) Slog.d(TAG, "Generic location: " + location);
1890 mLastGenericLocation = new Location(location);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001891 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHasGps) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001892 return;
1893 }
1894 mLocated = true;
1895 if (mNotMoving) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001896 stepIdleStateLocked("s:location");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001897 }
1898 }
1899
1900 void receivedGpsLocationLocked(Location location) {
1901 if (mState != STATE_LOCATING) {
1902 cancelLocatingLocked();
1903 return;
1904 }
1905 if (DEBUG) Slog.d(TAG, "GPS location: " + location);
1906 mLastGpsLocation = new Location(location);
1907 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY) {
1908 return;
1909 }
1910 mLocated = true;
1911 if (mNotMoving) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001912 stepIdleStateLocked("s:gps");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001913 }
1914 }
1915
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001916 void startMonitoringMotionLocked() {
1917 if (DEBUG) Slog.d(TAG, "startMonitoringMotionLocked()");
1918 if (mMotionSensor != null && !mMotionListener.active) {
1919 mMotionListener.registerLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001920 }
1921 }
1922
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001923 void stopMonitoringMotionLocked() {
1924 if (DEBUG) Slog.d(TAG, "stopMonitoringMotionLocked()");
1925 if (mMotionSensor != null && mMotionListener.active) {
1926 mMotionListener.unregisterLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001927 }
1928 }
1929
1930 void cancelAlarmLocked() {
1931 if (mNextAlarmTime != 0) {
1932 mNextAlarmTime = 0;
1933 mAlarmManager.cancel(mAlarmIntent);
1934 }
1935 }
1936
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001937 void cancelLightAlarmLocked() {
1938 if (mNextLightAlarmTime != 0) {
1939 mNextLightAlarmTime = 0;
1940 mAlarmManager.cancel(mLightAlarmIntent);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001941 }
1942 }
1943
1944 void cancelLocatingLocked() {
1945 if (mLocating) {
1946 mLocationManager.removeUpdates(mGenericLocationListener);
1947 mLocationManager.removeUpdates(mGpsLocationListener);
1948 mLocating = false;
1949 }
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001950 }
1951
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001952 void scheduleAlarmLocked(long delay, boolean idleUntil) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001953 if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")");
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001954 if (mMotionSensor == null) {
Joe LaPenna23d681b2015-08-27 15:12:11 -07001955 // If there is no motion sensor on this device, then we won't schedule
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001956 // alarms, because we can't determine if the device is not moving. This effectively
Joe LaPenna23d681b2015-08-27 15:12:11 -07001957 // turns off normal execution of device idling, although it is still possible to
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001958 // manually poke it by pretending like the alarm is going off.
1959 return;
1960 }
1961 mNextAlarmTime = SystemClock.elapsedRealtime() + delay;
1962 if (idleUntil) {
1963 mAlarmManager.setIdleUntil(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1964 mNextAlarmTime, mAlarmIntent);
1965 } else {
1966 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1967 mNextAlarmTime, mAlarmIntent);
1968 }
1969 }
1970
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001971 void scheduleLightAlarmLocked(long delay) {
1972 if (DEBUG) Slog.d(TAG, "scheduleLightAlarmLocked(" + delay + ")");
1973 if (mMotionSensor == null) {
1974 // If there is no motion sensor on this device, then we won't schedule
1975 // alarms, because we can't determine if the device is not moving. This effectively
1976 // turns off normal execution of device idling, although it is still possible to
1977 // manually poke it by pretending like the alarm is going off.
1978 return;
1979 }
1980 mNextLightAlarmTime = SystemClock.elapsedRealtime() + delay;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001981 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001982 mNextLightAlarmTime, mLightAlarmIntent);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001983 }
1984
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001985 private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps,
1986 ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds) {
1987 outAppIds.clear();
1988 for (int i=0; i<systemApps.size(); i++) {
1989 outAppIds.put(systemApps.valueAt(i), true);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001990 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001991 for (int i=0; i<userApps.size(); i++) {
1992 outAppIds.put(userApps.valueAt(i), true);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001993 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001994 int size = outAppIds.size();
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07001995 int[] appids = new int[size];
1996 for (int i = 0; i < size; i++) {
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001997 appids[i] = outAppIds.keyAt(i);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07001998 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001999 return appids;
2000 }
2001
2002 private void updateWhitelistAppIdsLocked() {
2003 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(mPowerSaveWhitelistAppsExceptIdle,
2004 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistExceptIdleAppIds);
2005 mPowerSaveWhitelistAllAppIdArray = buildAppIdArray(mPowerSaveWhitelistApps,
2006 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistAllAppIds);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002007 if (mLocalPowerManager != null) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002008 if (DEBUG) {
2009 Slog.d(TAG, "Setting wakelock whitelist to "
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002010 + Arrays.toString(mPowerSaveWhitelistAllAppIdArray));
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002011 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002012 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002013 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002014 }
2015
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002016 private void updateTempWhitelistAppIdsLocked() {
2017 final int size = mTempWhitelistAppIdEndTimes.size();
2018 if (mTempWhitelistAppIdArray.length != size) {
2019 mTempWhitelistAppIdArray = new int[size];
2020 }
2021 for (int i = 0; i < size; i++) {
2022 mTempWhitelistAppIdArray[i] = mTempWhitelistAppIdEndTimes.keyAt(i);
2023 }
2024 if (mLocalPowerManager != null) {
2025 if (DEBUG) {
2026 Slog.d(TAG, "Setting wakelock temp whitelist to "
2027 + Arrays.toString(mTempWhitelistAppIdArray));
2028 }
2029 mLocalPowerManager.setDeviceIdleTempWhitelist(mTempWhitelistAppIdArray);
2030 }
2031 }
2032
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002033 private void reportPowerSaveWhitelistChangedLocked() {
2034 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
2035 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Xiaohui Chene4de5a02015-09-22 15:33:31 -07002036 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002037 }
2038
2039 private void reportTempWhitelistChangedLocked() {
2040 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED);
2041 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Xiaohui Chene4de5a02015-09-22 15:33:31 -07002042 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002043 }
2044
2045 void readConfigFileLocked() {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002046 if (DEBUG) Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002047 mPowerSaveWhitelistUserApps.clear();
2048 FileInputStream stream;
2049 try {
2050 stream = mConfigFile.openRead();
2051 } catch (FileNotFoundException e) {
2052 return;
2053 }
2054 try {
2055 XmlPullParser parser = Xml.newPullParser();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01002056 parser.setInput(stream, StandardCharsets.UTF_8.name());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002057 readConfigFileLocked(parser);
2058 } catch (XmlPullParserException e) {
2059 } finally {
2060 try {
2061 stream.close();
2062 } catch (IOException e) {
2063 }
2064 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002065 }
2066
2067 private void readConfigFileLocked(XmlPullParser parser) {
2068 final PackageManager pm = getContext().getPackageManager();
2069
2070 try {
2071 int type;
2072 while ((type = parser.next()) != XmlPullParser.START_TAG
2073 && type != XmlPullParser.END_DOCUMENT) {
2074 ;
2075 }
2076
2077 if (type != XmlPullParser.START_TAG) {
2078 throw new IllegalStateException("no start tag found");
2079 }
2080
2081 int outerDepth = parser.getDepth();
2082 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2083 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2084 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2085 continue;
2086 }
2087
2088 String tagName = parser.getName();
2089 if (tagName.equals("wl")) {
2090 String name = parser.getAttributeValue(null, "n");
2091 if (name != null) {
2092 try {
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07002093 ApplicationInfo ai = pm.getApplicationInfo(name,
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07002094 PackageManager.MATCH_UNINSTALLED_PACKAGES);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002095 mPowerSaveWhitelistUserApps.put(ai.packageName,
2096 UserHandle.getAppId(ai.uid));
2097 } catch (PackageManager.NameNotFoundException e) {
2098 }
2099 }
2100 } else {
2101 Slog.w(TAG, "Unknown element under <config>: "
2102 + parser.getName());
2103 XmlUtils.skipCurrentTag(parser);
2104 }
2105 }
2106
2107 } catch (IllegalStateException e) {
2108 Slog.w(TAG, "Failed parsing config " + e);
2109 } catch (NullPointerException e) {
2110 Slog.w(TAG, "Failed parsing config " + e);
2111 } catch (NumberFormatException e) {
2112 Slog.w(TAG, "Failed parsing config " + e);
2113 } catch (XmlPullParserException e) {
2114 Slog.w(TAG, "Failed parsing config " + e);
2115 } catch (IOException e) {
2116 Slog.w(TAG, "Failed parsing config " + e);
2117 } catch (IndexOutOfBoundsException e) {
2118 Slog.w(TAG, "Failed parsing config " + e);
2119 }
2120 }
2121
2122 void writeConfigFileLocked() {
2123 mHandler.removeMessages(MSG_WRITE_CONFIG);
2124 mHandler.sendEmptyMessageDelayed(MSG_WRITE_CONFIG, 5000);
2125 }
2126
2127 void handleWriteConfigFile() {
2128 final ByteArrayOutputStream memStream = new ByteArrayOutputStream();
2129
2130 try {
2131 synchronized (this) {
2132 XmlSerializer out = new FastXmlSerializer();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01002133 out.setOutput(memStream, StandardCharsets.UTF_8.name());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002134 writeConfigFileLocked(out);
2135 }
2136 } catch (IOException e) {
2137 }
2138
2139 synchronized (mConfigFile) {
2140 FileOutputStream stream = null;
2141 try {
2142 stream = mConfigFile.startWrite();
2143 memStream.writeTo(stream);
2144 stream.flush();
2145 FileUtils.sync(stream);
2146 stream.close();
2147 mConfigFile.finishWrite(stream);
2148 } catch (IOException e) {
2149 Slog.w(TAG, "Error writing config file", e);
2150 mConfigFile.failWrite(stream);
2151 }
2152 }
2153 }
2154
2155 void writeConfigFileLocked(XmlSerializer out) throws IOException {
2156 out.startDocument(null, true);
2157 out.startTag(null, "config");
2158 for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) {
2159 String name = mPowerSaveWhitelistUserApps.keyAt(i);
2160 out.startTag(null, "wl");
2161 out.attribute(null, "n", name);
2162 out.endTag(null, "wl");
2163 }
2164 out.endTag(null, "config");
2165 out.endDocument();
2166 }
2167
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002168 static void dumpHelp(PrintWriter pw) {
2169 pw.println("Device idle controller (deviceidle) commands:");
2170 pw.println(" help");
2171 pw.println(" Print this help text.");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002172 pw.println(" step");
2173 pw.println(" Immediately step to next state, without waiting for alarm.");
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002174 pw.println(" light-step");
2175 pw.println(" Immediately step to next light idle state, without waiting for alarm.");
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002176 pw.println(" force-idle");
2177 pw.println(" Force directly into idle mode, regardless of other device state.");
2178 pw.println(" Use \"step\" to get out.");
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002179 pw.println(" disable");
2180 pw.println(" Completely disable device idle mode.");
2181 pw.println(" enable");
2182 pw.println(" Re-enable device idle mode after it had previously been disabled.");
Dianne Hackborn92617032015-06-19 15:32:19 -07002183 pw.println(" enabled");
2184 pw.println(" Print 1 if device idle mode is currently enabled, else 0.");
Dianne Hackborn1b139682015-07-06 15:13:37 -07002185 pw.println(" whitelist");
2186 pw.println(" Print currently whitelisted apps.");
Dianne Hackborn92617032015-06-19 15:32:19 -07002187 pw.println(" whitelist [package ...]");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002188 pw.println(" Add (prefix with +) or remove (prefix with -) packages.");
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002189 pw.println(" tempwhitelist [-u] [package ..]");
Dianne Hackborn92617032015-06-19 15:32:19 -07002190 pw.println(" Temporarily place packages in whitelist for 10 seconds.");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002191 }
2192
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002193 class Shell extends ShellCommand {
2194 int userId = UserHandle.USER_SYSTEM;
2195
2196 @Override
2197 public int onCommand(String cmd) {
2198 return onShellCommand(this, cmd);
2199 }
2200
2201 @Override
2202 public void onHelp() {
2203 PrintWriter pw = getOutPrintWriter();
2204 dumpHelp(pw);
2205 }
2206 }
2207
2208 int onShellCommand(Shell shell, String cmd) {
2209 PrintWriter pw = shell.getOutPrintWriter();
2210 if ("step".equals(cmd)) {
2211 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
2212 null);
2213 synchronized (this) {
2214 long token = Binder.clearCallingIdentity();
2215 try {
2216 exitForceIdleLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002217 stepIdleStateLocked("s:shell");
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002218 pw.print("Stepped to: ");
2219 pw.println(stateToString(mState));
2220 } finally {
2221 Binder.restoreCallingIdentity(token);
2222 }
2223 }
2224 } else if ("light-step".equals(cmd)) {
2225 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
2226 null);
2227 synchronized (this) {
2228 long token = Binder.clearCallingIdentity();
2229 try {
2230 exitForceIdleLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002231 stepLightIdleStateLocked("s:shell");
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002232 pw.print("Stepped to: "); pw.println(lightStateToString(mLightState));
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002233 } finally {
2234 Binder.restoreCallingIdentity(token);
2235 }
2236 }
2237 } else if ("force-idle".equals(cmd)) {
2238 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
2239 null);
2240 synchronized (this) {
2241 long token = Binder.clearCallingIdentity();
2242 try {
2243 if (!mEnabled) {
2244 pw.println("Unable to go idle; not enabled");
2245 return -1;
2246 }
2247 mForceIdle = true;
2248 becomeInactiveIfAppropriateLocked();
2249 int curState = mState;
2250 while (curState != STATE_IDLE) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002251 stepIdleStateLocked("s:shell");
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002252 if (curState == mState) {
2253 pw.print("Unable to go idle; stopped at ");
2254 pw.println(stateToString(mState));
2255 exitForceIdleLocked();
2256 return -1;
2257 }
2258 curState = mState;
2259 }
2260 pw.println("Now forced in to idle mode");
2261 } finally {
2262 Binder.restoreCallingIdentity(token);
2263 }
2264 }
2265 } else if ("disable".equals(cmd)) {
2266 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
2267 null);
2268 synchronized (this) {
2269 long token = Binder.clearCallingIdentity();
2270 try {
2271 if (mEnabled) {
2272 mEnabled = false;
2273 becomeActiveLocked("disabled", Process.myUid());
2274 pw.println("Idle mode disabled");
2275 }
2276 } finally {
2277 Binder.restoreCallingIdentity(token);
2278 }
2279 }
2280 } else if ("enable".equals(cmd)) {
2281 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
2282 null);
2283 synchronized (this) {
2284 long token = Binder.clearCallingIdentity();
2285 try {
2286 exitForceIdleLocked();
2287 if (!mEnabled) {
2288 mEnabled = true;
2289 becomeInactiveIfAppropriateLocked();
2290 pw.println("Idle mode enabled");
2291 }
2292 } finally {
2293 Binder.restoreCallingIdentity(token);
2294 }
2295 }
2296 } else if ("enabled".equals(cmd)) {
2297 synchronized (this) {
2298 pw.println(mEnabled ? "1" : " 0");
2299 }
2300 } else if ("whitelist".equals(cmd)) {
2301 long token = Binder.clearCallingIdentity();
2302 try {
2303 String arg = shell.getNextArg();
2304 if (arg != null) {
2305 getContext().enforceCallingOrSelfPermission(
2306 android.Manifest.permission.DEVICE_POWER, null);
2307 do {
2308 if (arg.length() < 1 || (arg.charAt(0) != '-'
2309 && arg.charAt(0) != '+')) {
2310 pw.println("Package must be prefixed with + or -: " + arg);
2311 return -1;
2312 }
2313 char op = arg.charAt(0);
2314 String pkg = arg.substring(1);
2315 if (op == '+') {
2316 if (addPowerSaveWhitelistAppInternal(pkg)) {
2317 pw.println("Added: " + pkg);
2318 } else {
2319 pw.println("Unknown package: " + pkg);
2320 }
2321 } else {
2322 if (removePowerSaveWhitelistAppInternal(pkg)) {
2323 pw.println("Removed: " + pkg);
2324 }
2325 }
2326 } while ((arg=shell.getNextArg()) != null);
2327 } else {
2328 synchronized (this) {
2329 for (int j=0; j<mPowerSaveWhitelistAppsExceptIdle.size(); j++) {
2330 pw.print("system-excidle,");
2331 pw.print(mPowerSaveWhitelistAppsExceptIdle.keyAt(j));
2332 pw.print(",");
2333 pw.println(mPowerSaveWhitelistAppsExceptIdle.valueAt(j));
2334 }
2335 for (int j=0; j<mPowerSaveWhitelistApps.size(); j++) {
2336 pw.print("system,");
2337 pw.print(mPowerSaveWhitelistApps.keyAt(j));
2338 pw.print(",");
2339 pw.println(mPowerSaveWhitelistApps.valueAt(j));
2340 }
2341 for (int j=0; j<mPowerSaveWhitelistUserApps.size(); j++) {
2342 pw.print("user,");
2343 pw.print(mPowerSaveWhitelistUserApps.keyAt(j));
2344 pw.print(",");
2345 pw.println(mPowerSaveWhitelistUserApps.valueAt(j));
2346 }
2347 }
2348 }
2349 } finally {
2350 Binder.restoreCallingIdentity(token);
2351 }
2352 } else if ("tempwhitelist".equals(cmd)) {
2353 String opt;
2354 while ((opt=shell.getNextOption()) != null) {
2355 if ("-u".equals(opt)) {
2356 opt = shell.getNextArg();
2357 if (opt == null) {
2358 pw.println("-u requires a user number");
2359 return -1;
2360 }
2361 shell.userId = Integer.parseInt(opt);
2362 }
2363 }
2364 String arg = shell.getNextArg();
2365 if (arg != null) {
2366 try {
2367 addPowerSaveTempWhitelistAppChecked(arg, 10000L, shell.userId, "shell");
2368 } catch (RemoteException re) {
2369 pw.println("Failed: " + re);
2370 }
2371 } else {
2372 pw.println("At least one package name must be specified");
2373 return -1;
2374 }
2375 } else {
2376 return shell.handleDefaultCommands(cmd);
2377 }
2378 return 0;
2379 }
2380
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002381 void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2382 if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
2383 != PackageManager.PERMISSION_GRANTED) {
2384 pw.println("Permission Denial: can't dump DeviceIdleController from from pid="
2385 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2386 + " without permission " + android.Manifest.permission.DUMP);
2387 return;
2388 }
2389
2390 if (args != null) {
Xiaohui Chen7c696362015-09-16 09:56:14 -07002391 int userId = UserHandle.USER_SYSTEM;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002392 for (int i=0; i<args.length; i++) {
2393 String arg = args[i];
2394 if ("-h".equals(arg)) {
2395 dumpHelp(pw);
2396 return;
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002397 } else if ("-u".equals(arg)) {
2398 i++;
2399 if (i < args.length) {
2400 arg = args[i];
2401 userId = Integer.parseInt(arg);
2402 }
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002403 } else if ("-a".equals(arg)) {
2404 // Ignore, we always dump all.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002405 } else if (arg.length() > 0 && arg.charAt(0) == '-'){
2406 pw.println("Unknown option: " + arg);
2407 return;
2408 } else {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002409 Shell shell = new Shell();
2410 shell.userId = userId;
2411 String[] newArgs = new String[args.length-i];
2412 System.arraycopy(args, i, newArgs, 0, args.length-i);
2413 shell.exec(mBinderService, null, fd, null, newArgs, new ResultReceiver(null));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002414 return;
2415 }
2416 }
2417 }
2418
2419 synchronized (this) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002420 mConstants.dump(pw);
2421
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002422 if (mEventCmds[0] != EVENT_NULL) {
2423 pw.println(" Idling history:");
2424 long now = SystemClock.elapsedRealtime();
2425 for (int i=EVENT_BUFFER_SIZE-1; i>=0; i--) {
2426 int cmd = mEventCmds[i];
2427 if (cmd == EVENT_NULL) {
2428 continue;
2429 }
2430 String label;
2431 switch (mEventCmds[i]) {
2432 case EVENT_NORMAL: label = " normal"; break;
2433 case EVENT_LIGHT_IDLE: label = " light-idle"; break;
2434 case EVENT_LIGHT_MAINTENANCE: label = "light-maint"; break;
2435 case EVENT_FULL_IDLE: label = " full-idle"; break;
2436 case EVENT_FULL_MAINTENANCE: label = " full-maint"; break;
2437 default: label = " ??"; break;
2438 }
2439 pw.print(" ");
2440 pw.print(label);
2441 pw.print(": ");
2442 TimeUtils.formatDuration(mEventTimes[i], now, pw);;
2443 pw.println();
2444 }
2445 }
2446
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002447 int size = mPowerSaveWhitelistAppsExceptIdle.size();
2448 if (size > 0) {
2449 pw.println(" Whitelist (except idle) system apps:");
2450 for (int i = 0; i < size; i++) {
2451 pw.print(" ");
2452 pw.println(mPowerSaveWhitelistAppsExceptIdle.keyAt(i));
2453 }
2454 }
2455 size = mPowerSaveWhitelistApps.size();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002456 if (size > 0) {
2457 pw.println(" Whitelist system apps:");
2458 for (int i = 0; i < size; i++) {
2459 pw.print(" ");
2460 pw.println(mPowerSaveWhitelistApps.keyAt(i));
2461 }
2462 }
2463 size = mPowerSaveWhitelistUserApps.size();
2464 if (size > 0) {
2465 pw.println(" Whitelist user apps:");
2466 for (int i = 0; i < size; i++) {
2467 pw.print(" ");
2468 pw.println(mPowerSaveWhitelistUserApps.keyAt(i));
2469 }
2470 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002471 size = mPowerSaveWhitelistExceptIdleAppIds.size();
2472 if (size > 0) {
2473 pw.println(" Whitelist (except idle) all app ids:");
2474 for (int i = 0; i < size; i++) {
2475 pw.print(" ");
2476 pw.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
2477 pw.println();
2478 }
2479 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002480 size = mPowerSaveWhitelistAllAppIds.size();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002481 if (size > 0) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002482 pw.println(" Whitelist all app ids:");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002483 for (int i = 0; i < size; i++) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002484 pw.print(" ");
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002485 pw.print(mPowerSaveWhitelistAllAppIds.keyAt(i));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002486 pw.println();
2487 }
2488 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002489 size = mTempWhitelistAppIdEndTimes.size();
2490 if (size > 0) {
2491 pw.println(" Temp whitelist schedule:");
2492 final long timeNow = SystemClock.elapsedRealtime();
2493 for (int i = 0; i < size; i++) {
2494 pw.print(" UID=");
2495 pw.print(mTempWhitelistAppIdEndTimes.keyAt(i));
2496 pw.print(": ");
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002497 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.valueAt(i);
2498 TimeUtils.formatDuration(entry.first.value, timeNow, pw);
2499 pw.print(" - ");
2500 pw.println(entry.second);
Dianne Hackborna750a632015-06-16 17:18:23 -07002501 }
2502 }
2503 size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0;
2504 if (size > 0) {
2505 pw.println(" Temp whitelist app ids:");
2506 for (int i = 0; i < size; i++) {
2507 pw.print(" ");
2508 pw.print(mTempWhitelistAppIdArray[i]);
2509 pw.println();
2510 }
2511 }
Adam Lesinski31c05d12015-06-09 17:34:04 -07002512
Dianne Hackborn92617032015-06-19 15:32:19 -07002513 pw.print(" mEnabled="); pw.println(mEnabled);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002514 pw.print(" mForceIdle="); pw.println(mForceIdle);
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002515 pw.print(" mMotionSensor="); pw.println(mMotionSensor);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002516 pw.print(" mCurDisplay="); pw.println(mCurDisplay);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002517 pw.print(" mScreenOn="); pw.println(mScreenOn);
2518 pw.print(" mCharging="); pw.println(mCharging);
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002519 pw.print(" mMotionActive="); pw.println(mMotionListener.active);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002520 pw.print(" mNotMoving="); pw.println(mNotMoving);
Joe LaPenna23d681b2015-08-27 15:12:11 -07002521 pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHasGps=");
2522 pw.print(mHasGps); pw.print(" mHasNetwork=");
2523 pw.print(mHasNetworkLocation); pw.print(" mLocated="); pw.println(mLocated);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002524 if (mLastGenericLocation != null) {
2525 pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation);
2526 }
2527 if (mLastGpsLocation != null) {
2528 pw.print(" mLastGpsLocation="); pw.println(mLastGpsLocation);
2529 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002530 pw.print(" mState="); pw.print(stateToString(mState));
2531 pw.print(" mLightState=");
2532 pw.println(lightStateToString(mLightState));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002533 pw.print(" mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw);
2534 pw.println();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002535 if (mActiveIdleOpCount != 0) {
2536 pw.print(" mActiveIdleOpCount="); pw.println(mActiveIdleOpCount);
2537 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002538 if (mNextAlarmTime != 0) {
2539 pw.print(" mNextAlarmTime=");
2540 TimeUtils.formatDuration(mNextAlarmTime, SystemClock.elapsedRealtime(), pw);
2541 pw.println();
2542 }
2543 if (mNextIdlePendingDelay != 0) {
2544 pw.print(" mNextIdlePendingDelay=");
2545 TimeUtils.formatDuration(mNextIdlePendingDelay, pw);
2546 pw.println();
2547 }
2548 if (mNextIdleDelay != 0) {
2549 pw.print(" mNextIdleDelay=");
2550 TimeUtils.formatDuration(mNextIdleDelay, pw);
2551 pw.println();
2552 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002553 if (mNextLightAlarmTime != 0) {
2554 pw.print(" mNextLightAlarmTime=");
2555 TimeUtils.formatDuration(mNextLightAlarmTime, SystemClock.elapsedRealtime(), pw);
2556 pw.println();
2557 }
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002558 if (mCurIdleBudget != 0) {
2559 pw.print(" mCurIdleBudget=");
2560 TimeUtils.formatDuration(mCurIdleBudget, pw);
2561 pw.println();
2562 }
2563 if (mMaintenanceStartTime != 0) {
2564 pw.print(" mMaintenanceStartTime=");
2565 TimeUtils.formatDuration(mMaintenanceStartTime, SystemClock.elapsedRealtime(), pw);
2566 pw.println();
2567 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002568 if (mSyncActive) {
2569 pw.print(" mSyncActive="); pw.println(mSyncActive);
2570 }
2571 if (mJobsActive) {
2572 pw.print(" mJobsActive="); pw.println(mJobsActive);
2573 }
2574 if (mAlarmsActive) {
2575 pw.print(" mAlarmsActive="); pw.println(mAlarmsActive);
2576 }
2577 if (mDownloadServiceActive != null) {
2578 pw.print(" mDownloadServiceActive="); pw.println(mDownloadServiceActive);
2579 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002580 }
2581 }
2582}