blob: ccb4647d8591b6e9ec4133c66ade1fbdc4852582 [file] [log] [blame]
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server;
18
Amith Yamasaniaf575b92015-05-29 15:35:26 -070019import android.Manifest;
20import android.app.ActivityManagerNative;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070021import android.app.AlarmManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070022import android.content.BroadcastReceiver;
Adam Lesinski31c05d12015-06-09 17:34:04 -070023import android.content.ContentResolver;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070024import android.content.Context;
25import android.content.Intent;
26import android.content.IntentFilter;
27import android.content.pm.ApplicationInfo;
28import android.content.pm.PackageManager;
Amith Yamasaniaf575b92015-05-29 15:35:26 -070029import android.content.pm.PackageManager.NameNotFoundException;
Adam Lesinski31c05d12015-06-09 17:34:04 -070030import android.database.ContentObserver;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070031import android.hardware.Sensor;
32import android.hardware.SensorManager;
Nick Vaccaro20feaea2015-09-17 17:22:44 -070033import android.hardware.SensorEvent;
34import android.hardware.SensorEventListener;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070035import android.hardware.TriggerEvent;
36import android.hardware.TriggerEventListener;
37import android.hardware.display.DisplayManager;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -070038import android.location.LocationRequest;
39import android.location.Location;
40import android.location.LocationListener;
41import android.location.LocationManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070042import android.net.INetworkPolicyManager;
Adam Lesinski31c05d12015-06-09 17:34:04 -070043import android.net.Uri;
Dianne Hackbornfd854ee2015-07-13 18:00:37 -070044import android.os.BatteryStats;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070045import android.os.Binder;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -070046import android.os.Bundle;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070047import android.os.Environment;
48import android.os.FileUtils;
49import android.os.Handler;
Dianne Hackborn627dfa12015-11-11 18:10:30 -080050import android.os.IBinder;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070051import android.os.IDeviceIdleController;
Yao Chenca5edbb2016-01-13 14:44:36 -080052import android.os.IMaintenanceActivityListener;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070053import android.os.Looper;
54import android.os.Message;
55import android.os.PowerManager;
56import android.os.PowerManagerInternal;
Dianne Hackbornb6683c42015-06-18 17:40:33 -070057import android.os.Process;
Yao Chenca5edbb2016-01-13 14:44:36 -080058import android.os.RemoteCallbackList;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070059import android.os.RemoteException;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070060import android.os.ResultReceiver;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070061import android.os.ServiceManager;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -070062import android.os.ShellCommand;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070063import android.os.SystemClock;
64import android.os.UserHandle;
Adam Lesinski31c05d12015-06-09 17:34:04 -070065import android.provider.Settings;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070066import android.util.ArrayMap;
67import android.util.ArraySet;
Adam Lesinski31c05d12015-06-09 17:34:04 -070068import android.util.KeyValueListParser;
Dianne Hackbornfd854ee2015-07-13 18:00:37 -070069import android.util.MutableLong;
70import android.util.Pair;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070071import android.util.Slog;
Dianne Hackbornfd854ee2015-07-13 18:00:37 -070072import android.util.SparseArray;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070073import android.util.SparseBooleanArray;
74import android.util.TimeUtils;
75import android.util.Xml;
76import android.view.Display;
Amith Yamasani520d8f22015-05-08 16:36:21 -070077
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070078import com.android.internal.app.IBatteryStats;
79import com.android.internal.os.AtomicFile;
80import com.android.internal.os.BackgroundThread;
81import com.android.internal.util.FastXmlSerializer;
82import com.android.internal.util.XmlUtils;
83import com.android.server.am.BatteryStatsService;
Amith Yamasani520d8f22015-05-08 16:36:21 -070084
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070085import org.xmlpull.v1.XmlPullParser;
86import org.xmlpull.v1.XmlPullParserException;
87import org.xmlpull.v1.XmlSerializer;
88
89import java.io.ByteArrayOutputStream;
90import java.io.File;
91import java.io.FileDescriptor;
92import java.io.FileInputStream;
93import java.io.FileNotFoundException;
94import java.io.FileOutputStream;
95import java.io.IOException;
96import java.io.PrintWriter;
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +010097import java.nio.charset.StandardCharsets;
Amith Yamasaniaf575b92015-05-29 15:35:26 -070098import java.util.Arrays;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -070099
100/**
101 * Keeps track of device idleness and drives low power mode based on that.
102 */
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700103public class DeviceIdleController extends SystemService
104 implements AnyMotionDetector.DeviceIdleCallback {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700105 private static final String TAG = "DeviceIdleController";
106
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700107 private static final boolean DEBUG = false;
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700108
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700109 private static final boolean COMPRESS_TIME = false;
Amith Yamasani520d8f22015-05-08 16:36:21 -0700110
Dianne Hackborn953fc942016-03-29 15:36:24 -0700111 private static final int EVENT_BUFFER_SIZE = 100;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800112
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700113 private AlarmManager mAlarmManager;
114 private IBatteryStats mBatteryStats;
115 private PowerManagerInternal mLocalPowerManager;
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700116 private PowerManager mPowerManager;
Dianne Hackborn262ae5c2016-02-10 16:28:29 -0800117 private AlarmManagerService.LocalService mLocalAlarmManager;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700118 private INetworkPolicyManager mNetworkPolicyManager;
119 private DisplayManager mDisplayManager;
120 private SensorManager mSensorManager;
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700121 private Sensor mMotionSensor;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700122 private LocationManager mLocationManager;
123 private LocationRequest mLocationRequest;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700124 private Intent mIdleIntent;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700125 private Intent mLightIdleIntent;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700126 private Display mCurDisplay;
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700127 private AnyMotionDetector mAnyMotionDetector;
Dianne Hackbornb6843652016-02-22 12:20:13 -0800128 private boolean mLightEnabled;
129 private boolean mDeepEnabled;
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700130 private boolean mForceIdle;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700131 private boolean mScreenOn;
132 private boolean mCharging;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700133 private boolean mNotMoving;
134 private boolean mLocating;
135 private boolean mLocated;
Joe LaPenna23d681b2015-08-27 15:12:11 -0700136 private boolean mHasGps;
137 private boolean mHasNetworkLocation;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700138 private Location mLastGenericLocation;
139 private Location mLastGpsLocation;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700140
141 /** Device is currently active. */
142 private static final int STATE_ACTIVE = 0;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700143 /** Device is inactive (screen off, no motion) and we are waiting to for idle. */
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700144 private static final int STATE_INACTIVE = 1;
145 /** Device is past the initial inactive period, and waiting for the next idle period. */
146 private static final int STATE_IDLE_PENDING = 2;
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700147 /** Device is currently sensing motion. */
148 private static final int STATE_SENSING = 3;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700149 /** Device is currently finding location (and may still be sensing). */
150 private static final int STATE_LOCATING = 4;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700151 /** Device is in the idle state, trying to stay asleep as much as possible. */
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700152 private static final int STATE_IDLE = 5;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700153 /** Device is in the idle state, but temporarily out of idle to do regular maintenance. */
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700154 private static final int STATE_IDLE_MAINTENANCE = 6;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700155 private static String stateToString(int state) {
156 switch (state) {
157 case STATE_ACTIVE: return "ACTIVE";
158 case STATE_INACTIVE: return "INACTIVE";
159 case STATE_IDLE_PENDING: return "IDLE_PENDING";
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700160 case STATE_SENSING: return "SENSING";
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700161 case STATE_LOCATING: return "LOCATING";
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700162 case STATE_IDLE: return "IDLE";
163 case STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE";
164 default: return Integer.toString(state);
165 }
166 }
167
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700168 /** Device is currently active. */
169 private static final int LIGHT_STATE_ACTIVE = 0;
170 /** Device is inactive (screen off) and we are waiting to for the first light idle. */
171 private static final int LIGHT_STATE_INACTIVE = 1;
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700172 /** Device is about to go idle for the first time, wait for current work to complete. */
173 private static final int LIGHT_STATE_PRE_IDLE = 3;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700174 /** Device is in the light idle state, trying to stay asleep as much as possible. */
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700175 private static final int LIGHT_STATE_IDLE = 4;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700176 /** Device is in the light idle state, but temporarily out of idle to do regular maintenance. */
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700177 private static final int LIGHT_STATE_IDLE_MAINTENANCE = 5;
Dianne Hackbornb6843652016-02-22 12:20:13 -0800178 /** Device light idle state is overriden, now applying deep doze state. */
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700179 private static final int LIGHT_STATE_OVERRIDE = 6;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700180 private static String lightStateToString(int state) {
181 switch (state) {
182 case LIGHT_STATE_ACTIVE: return "ACTIVE";
183 case LIGHT_STATE_INACTIVE: return "INACTIVE";
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700184 case LIGHT_STATE_PRE_IDLE: return "PRE_IDLE";
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700185 case LIGHT_STATE_IDLE: return "IDLE";
186 case LIGHT_STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE";
187 case LIGHT_STATE_OVERRIDE: return "OVERRIDE";
188 default: return Integer.toString(state);
189 }
190 }
191
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700192 private int mState;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700193 private int mLightState;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700194
195 private long mInactiveTimeout;
196 private long mNextAlarmTime;
197 private long mNextIdlePendingDelay;
198 private long mNextIdleDelay;
Dianne Hackborn953fc942016-03-29 15:36:24 -0700199 private long mNextLightIdleDelay;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700200 private long mNextLightAlarmTime;
Kevin Gabayan92f15e62016-04-04 17:52:22 -0700201 private long mNextSensingTimeoutAlarmTime;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800202 private long mCurIdleBudget;
203 private long mMaintenanceStartTime;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700204
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800205 private int mActiveIdleOpCount;
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700206 private PowerManager.WakeLock mActiveIdleWakeLock;
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800207 private IBinder mDownloadServiceActive;
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800208 private boolean mJobsActive;
209 private boolean mAlarmsActive;
Yao Chenca5edbb2016-01-13 14:44:36 -0800210 private boolean mReportedMaintenanceActivity;
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800211
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700212 public final AtomicFile mConfigFile;
213
Yao Chenca5edbb2016-01-13 14:44:36 -0800214 private final RemoteCallbackList<IMaintenanceActivityListener> mMaintenanceActivityListeners =
215 new RemoteCallbackList<IMaintenanceActivityListener>();
216
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700217 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700218 * Package names the system has white-listed to opt out of power save restrictions,
219 * except for device idle mode.
220 */
221 private final ArrayMap<String, Integer> mPowerSaveWhitelistAppsExceptIdle = new ArrayMap<>();
222
223 /**
224 * Package names the system has white-listed to opt out of power save restrictions for
225 * all modes.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700226 */
227 private final ArrayMap<String, Integer> mPowerSaveWhitelistApps = new ArrayMap<>();
228
229 /**
230 * Package names the user has white-listed to opt out of power save restrictions.
231 */
232 private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>();
233
234 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700235 * App IDs of built-in system apps that have been white-listed except for idle modes.
236 */
237 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIdsExceptIdle
238 = new SparseBooleanArray();
239
240 /**
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700241 * App IDs of built-in system apps that have been white-listed.
242 */
243 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray();
244
245 /**
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700246 * App IDs that have been white-listed to opt out of power save restrictions, except
247 * for device idle modes.
248 */
249 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
250
251 /**
252 * Current app IDs that are in the complete power save white list, but shouldn't be
253 * excluded from idle modes. This array can be shared with others because it will not be
254 * modified once set.
255 */
256 private int[] mPowerSaveWhitelistExceptIdleAppIdArray = new int[0];
257
258 /**
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700259 * App IDs that have been white-listed to opt out of power save restrictions.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700260 */
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700261 private final SparseBooleanArray mPowerSaveWhitelistAllAppIds = new SparseBooleanArray();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700262
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700263 /**
264 * Current app IDs that are in the complete power save white list. This array can
265 * be shared with others because it will not be modified once set.
266 */
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700267 private int[] mPowerSaveWhitelistAllAppIdArray = new int[0];
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -0700268
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700269 /**
Dianne Hackborn262ae5c2016-02-10 16:28:29 -0800270 * App IDs that have been white-listed by the user to opt out of power save restrictions.
271 */
272 private final SparseBooleanArray mPowerSaveWhitelistUserAppIds = new SparseBooleanArray();
273
274 /**
275 * Current app IDs that are in the user power save white list. This array can
276 * be shared with others because it will not be modified once set.
277 */
278 private int[] mPowerSaveWhitelistUserAppIdArray = new int[0];
279
280 /**
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700281 * List of end times for UIDs that are temporarily marked as being allowed to access
282 * the network and acquire wakelocks. Times are in milliseconds.
283 */
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700284 private final SparseArray<Pair<MutableLong, String>> mTempWhitelistAppIdEndTimes
285 = new SparseArray<>();
286
287 /**
288 * Callback to the NetworkPolicyManagerService to tell it that the temp whitelist has changed.
289 */
290 Runnable mNetworkPolicyTempWhitelistCallback;
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700291
292 /**
293 * Current app IDs of temporarily whitelist apps for high-priority messages.
294 */
295 private int[] mTempWhitelistAppIdArray = new int[0];
296
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800297 private static final int EVENT_NULL = 0;
298 private static final int EVENT_NORMAL = 1;
299 private static final int EVENT_LIGHT_IDLE = 2;
300 private static final int EVENT_LIGHT_MAINTENANCE = 3;
Dianne Hackbornb6843652016-02-22 12:20:13 -0800301 private static final int EVENT_DEEP_IDLE = 4;
302 private static final int EVENT_DEEP_MAINTENANCE = 5;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800303
304 private int[] mEventCmds = new int[EVENT_BUFFER_SIZE];
305 private long[] mEventTimes = new long[EVENT_BUFFER_SIZE];
306
307 private void addEvent(int cmd) {
308 if (mEventCmds[0] != cmd) {
309 System.arraycopy(mEventCmds, 0, mEventCmds, 1, EVENT_BUFFER_SIZE - 1);
310 System.arraycopy(mEventTimes, 0, mEventTimes, 1, EVENT_BUFFER_SIZE - 1);
311 mEventCmds[0] = cmd;
312 mEventTimes[0] = SystemClock.elapsedRealtime();
313 }
314 }
315
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700316 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
317 @Override public void onReceive(Context context, Intent intent) {
318 if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
319 int plugged = intent.getIntExtra("plugged", 0);
320 updateChargingLocked(plugged != 0);
Dianne Hackborn1b79ad72015-10-12 10:59:47 -0700321 } else if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
322 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
323 Uri data = intent.getData();
324 String ssp;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700325 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
Dianne Hackborn1b79ad72015-10-12 10:59:47 -0700326 removePowerSaveWhitelistAppInternal(ssp);
327 }
328 }
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700329 }
330 }
331 };
332
333 private final AlarmManager.OnAlarmListener mLightAlarmListener
334 = new AlarmManager.OnAlarmListener() {
335 @Override
336 public void onAlarm() {
337 synchronized (DeviceIdleController.this) {
338 stepLightIdleStateLocked("s:alarm");
339 }
340 }
341 };
342
Kevin Gabayan92f15e62016-04-04 17:52:22 -0700343 private final AlarmManager.OnAlarmListener mSensingTimeoutAlarmListener
344 = new AlarmManager.OnAlarmListener() {
345 @Override
346 public void onAlarm() {
347 if (mState == STATE_SENSING) {
348 synchronized (DeviceIdleController.this) {
349 becomeInactiveIfAppropriateLocked();
350 }
351 }
352 }
353 };
354
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700355 private final AlarmManager.OnAlarmListener mDeepAlarmListener
356 = new AlarmManager.OnAlarmListener() {
357 @Override
358 public void onAlarm() {
359 synchronized (DeviceIdleController.this) {
360 stepIdleStateLocked("s:alarm");
361 }
362 }
363 };
364
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800365 private final BroadcastReceiver mIdleStartedDoneReceiver = new BroadcastReceiver() {
366 @Override public void onReceive(Context context, Intent intent) {
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700367 // When coming out of a deep idle, we will add in some delay before we allow
368 // the system to settle down and finish the maintenance window. This is
369 // to give a chance for any pending work to be scheduled.
370 if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(intent.getAction())) {
371 mHandler.sendEmptyMessageDelayed(MSG_FINISH_IDLE_OP,
372 mConstants.MIN_DEEP_MAINTENANCE_TIME);
373 } else {
374 mHandler.sendEmptyMessageDelayed(MSG_FINISH_IDLE_OP,
375 mConstants.MIN_LIGHT_MAINTENANCE_TIME);
376 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800377 }
378 };
379
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700380 private final DisplayManager.DisplayListener mDisplayListener
381 = new DisplayManager.DisplayListener() {
382 @Override public void onDisplayAdded(int displayId) {
383 }
384
385 @Override public void onDisplayRemoved(int displayId) {
386 }
387
388 @Override public void onDisplayChanged(int displayId) {
389 if (displayId == Display.DEFAULT_DISPLAY) {
390 synchronized (DeviceIdleController.this) {
391 updateDisplayLocked();
392 }
393 }
394 }
395 };
396
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700397 private final class MotionListener extends TriggerEventListener
398 implements SensorEventListener {
399
400 boolean active = false;
401
402 @Override
403 public void onTrigger(TriggerEvent event) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700404 synchronized (DeviceIdleController.this) {
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700405 active = false;
406 motionLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700407 }
408 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700409
410 @Override
411 public void onSensorChanged(SensorEvent event) {
412 synchronized (DeviceIdleController.this) {
413 mSensorManager.unregisterListener(this, mMotionSensor);
414 active = false;
415 motionLocked();
416 }
417 }
418
419 @Override
420 public void onAccuracyChanged(Sensor sensor, int accuracy) {}
421
422 public boolean registerLocked() {
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700423 boolean success;
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700424 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
425 success = mSensorManager.requestTriggerSensor(mMotionListener, mMotionSensor);
426 } else {
427 success = mSensorManager.registerListener(
428 mMotionListener, mMotionSensor, SensorManager.SENSOR_DELAY_NORMAL);
429 }
430 if (success) {
431 active = true;
432 } else {
433 Slog.e(TAG, "Unable to register for " + mMotionSensor);
434 }
435 return success;
436 }
437
438 public void unregisterLocked() {
439 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
440 mSensorManager.cancelTriggerSensor(mMotionListener, mMotionSensor);
441 } else {
442 mSensorManager.unregisterListener(mMotionListener);
443 }
444 active = false;
445 }
446 }
447 private final MotionListener mMotionListener = new MotionListener();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700448
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700449 private final LocationListener mGenericLocationListener = new LocationListener() {
450 @Override
451 public void onLocationChanged(Location location) {
452 synchronized (DeviceIdleController.this) {
453 receivedGenericLocationLocked(location);
454 }
455 }
456
457 @Override
458 public void onStatusChanged(String provider, int status, Bundle extras) {
459 }
460
461 @Override
462 public void onProviderEnabled(String provider) {
463 }
464
465 @Override
466 public void onProviderDisabled(String provider) {
467 }
468 };
469
470 private final LocationListener mGpsLocationListener = new LocationListener() {
471 @Override
472 public void onLocationChanged(Location location) {
473 synchronized (DeviceIdleController.this) {
474 receivedGpsLocationLocked(location);
475 }
476 }
477
478 @Override
479 public void onStatusChanged(String provider, int status, Bundle extras) {
480 }
481
482 @Override
483 public void onProviderEnabled(String provider) {
484 }
485
486 @Override
487 public void onProviderDisabled(String provider) {
488 }
489 };
490
Adam Lesinski31c05d12015-06-09 17:34:04 -0700491 /**
492 * All times are in milliseconds. These constants are kept synchronized with the system
493 * global Settings. Any access to this class or its fields should be done while
494 * holding the DeviceIdleController lock.
495 */
Dianne Hackborna750a632015-06-16 17:18:23 -0700496 private final class Constants extends ContentObserver {
Adam Lesinski31c05d12015-06-09 17:34:04 -0700497 // Key names stored in the settings value.
Dianne Hackborn953fc942016-03-29 15:36:24 -0700498 private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT
499 = "light_after_inactive_to";
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700500 private static final String KEY_LIGHT_PRE_IDLE_TIMEOUT = "light_pre_idle_to";
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700501 private static final String KEY_LIGHT_IDLE_TIMEOUT = "light_idle_to";
Dianne Hackborn953fc942016-03-29 15:36:24 -0700502 private static final String KEY_LIGHT_IDLE_FACTOR = "light_idle_factor";
503 private static final String KEY_LIGHT_MAX_IDLE_TIMEOUT = "light_max_idle_to";
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800504 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET
505 = "light_idle_maintenance_min_budget";
506 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET
507 = "light_idle_maintenance_max_budget";
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700508 private static final String KEY_MIN_LIGHT_MAINTENANCE_TIME = "min_light_maintenance_time";
509 private static final String KEY_MIN_DEEP_MAINTENANCE_TIME = "min_deep_maintenance_time";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700510 private static final String KEY_INACTIVE_TIMEOUT = "inactive_to";
511 private static final String KEY_SENSING_TIMEOUT = "sensing_to";
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700512 private static final String KEY_LOCATING_TIMEOUT = "locating_to";
513 private static final String KEY_LOCATION_ACCURACY = "location_accuracy";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700514 private static final String KEY_MOTION_INACTIVE_TIMEOUT = "motion_inactive_to";
515 private static final String KEY_IDLE_AFTER_INACTIVE_TIMEOUT = "idle_after_inactive_to";
516 private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to";
517 private static final String KEY_MAX_IDLE_PENDING_TIMEOUT = "max_idle_pending_to";
518 private static final String KEY_IDLE_PENDING_FACTOR = "idle_pending_factor";
519 private static final String KEY_IDLE_TIMEOUT = "idle_to";
520 private static final String KEY_MAX_IDLE_TIMEOUT = "max_idle_to";
521 private static final String KEY_IDLE_FACTOR = "idle_factor";
522 private static final String KEY_MIN_TIME_TO_ALARM = "min_time_to_alarm";
523 private static final String KEY_MAX_TEMP_APP_WHITELIST_DURATION =
524 "max_temp_app_whitelist_duration";
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700525 private static final String KEY_MMS_TEMP_APP_WHITELIST_DURATION =
526 "mms_temp_app_whitelist_duration";
Dianne Hackborn451c3462015-07-21 17:39:46 -0700527 private static final String KEY_SMS_TEMP_APP_WHITELIST_DURATION =
528 "sms_temp_app_whitelist_duration";
Adam Lesinski31c05d12015-06-09 17:34:04 -0700529
530 /**
Dianne Hackborn953fc942016-03-29 15:36:24 -0700531 * This is the time, after becoming inactive, that we go in to the first
532 * light-weight idle mode.
533 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
534 * @see #KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT
535 */
536 public long LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT;
537
538 /**
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700539 * This is amount of time we will wait from the point where we decide we would
540 * like to go idle until we actually do, while waiting for jobs and other current
541 * activity to finish.
542 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
543 * @see #KEY_LIGHT_PRE_IDLE_TIMEOUT
544 */
545 public long LIGHT_PRE_IDLE_TIMEOUT;
546
547 /**
Dianne Hackborn953fc942016-03-29 15:36:24 -0700548 * This is the initial time that we will run in idle maintenance mode.
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700549 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
550 * @see #KEY_LIGHT_IDLE_TIMEOUT
551 */
552 public long LIGHT_IDLE_TIMEOUT;
553
554 /**
Dianne Hackborn953fc942016-03-29 15:36:24 -0700555 * Scaling factor to apply to the light idle mode time each time we complete a cycle.
556 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
557 * @see #KEY_LIGHT_IDLE_FACTOR
558 */
559 public float LIGHT_IDLE_FACTOR;
560
561 /**
562 * This is the maximum time we will run in idle maintenence mode.
563 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
564 * @see #KEY_LIGHT_MAX_IDLE_TIMEOUT
565 */
566 public long LIGHT_MAX_IDLE_TIMEOUT;
567
568 /**
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800569 * This is the minimum amount of time we want to make available for maintenance mode
570 * when lightly idling. That is, we will always have at least this amount of time
571 * available maintenance before timing out and cutting off maintenance mode.
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700572 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800573 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700574 */
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800575 public long LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
576
577 /**
578 * This is the maximum amount of time we want to make available for maintenance mode
579 * when lightly idling. That is, if the system isn't using up its minimum maintenance
580 * budget and this time is being added to the budget reserve, this is the maximum
581 * reserve size we will allow to grow and thus the maximum amount of time we will
582 * allow for the maintenance window.
583 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
584 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET
585 */
586 public long LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700587
588 /**
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700589 * This is the minimum amount of time that we will stay in maintenance mode after
590 * a light doze. We have this minimum to allow various things to respond to switching
591 * in to maintenance mode and scheduling their work -- otherwise we may
592 * see there is nothing to do (no jobs or downloads pending) and go out of maintenance
593 * mode immediately.
594 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
595 * @see #KEY_MIN_LIGHT_MAINTENANCE_TIME
596 */
597 public long MIN_LIGHT_MAINTENANCE_TIME;
598
599 /**
600 * This is the minimum amount of time that we will stay in maintenance mode after
601 * a full doze. We have this minimum to allow various things to respond to switching
602 * in to maintenance mode and scheduling their work -- otherwise we may
603 * see there is nothing to do (no jobs or downloads pending) and go out of maintenance
604 * mode immediately.
605 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
606 * @see #KEY_MIN_DEEP_MAINTENANCE_TIME
607 */
608 public long MIN_DEEP_MAINTENANCE_TIME;
609
610 /**
Adam Lesinski31c05d12015-06-09 17:34:04 -0700611 * This is the time, after becoming inactive, at which we start looking at the
612 * motion sensor to determine if the device is being left alone. We don't do this
613 * immediately after going inactive just because we don't want to be continually running
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700614 * the motion sensor whenever the screen is off.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700615 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
616 * @see #KEY_INACTIVE_TIMEOUT
617 */
618 public long INACTIVE_TIMEOUT;
619
620 /**
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700621 * If we don't receive a callback from AnyMotion in this amount of time +
622 * {@link #LOCATING_TIMEOUT}, we will change from
Adam Lesinski31c05d12015-06-09 17:34:04 -0700623 * STATE_SENSING to STATE_INACTIVE, and any AnyMotion callbacks while not in STATE_SENSING
624 * will be ignored.
625 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
626 * @see #KEY_SENSING_TIMEOUT
627 */
628 public long SENSING_TIMEOUT;
629
630 /**
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700631 * This is how long we will wait to try to get a good location fix before going in to
632 * idle mode.
633 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
634 * @see #KEY_LOCATING_TIMEOUT
635 */
636 public long LOCATING_TIMEOUT;
637
638 /**
639 * The desired maximum accuracy (in meters) we consider the location to be good enough to go
640 * on to idle. We will be trying to get an accuracy fix at least this good or until
641 * {@link #LOCATING_TIMEOUT} expires.
642 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
643 * @see #KEY_LOCATION_ACCURACY
644 */
645 public float LOCATION_ACCURACY;
646
647 /**
Adam Lesinski31c05d12015-06-09 17:34:04 -0700648 * This is the time, after seeing motion, that we wait after becoming inactive from
649 * that until we start looking for motion again.
650 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
651 * @see #KEY_MOTION_INACTIVE_TIMEOUT
652 */
653 public long MOTION_INACTIVE_TIMEOUT;
654
655 /**
656 * This is the time, after the inactive timeout elapses, that we will wait looking
Nick Vaccaro20feaea2015-09-17 17:22:44 -0700657 * for motion until we truly consider the device to be idle.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700658 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
659 * @see #KEY_IDLE_AFTER_INACTIVE_TIMEOUT
660 */
661 public long IDLE_AFTER_INACTIVE_TIMEOUT;
662
663 /**
664 * This is the initial time, after being idle, that we will allow ourself to be back
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700665 * in the IDLE_MAINTENANCE state allowing the system to run normally until we return to
666 * idle.
Adam Lesinski31c05d12015-06-09 17:34:04 -0700667 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
668 * @see #KEY_IDLE_PENDING_TIMEOUT
669 */
670 public long IDLE_PENDING_TIMEOUT;
671
672 /**
673 * Maximum pending idle timeout (time spent running) we will be allowed to use.
674 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
675 * @see #KEY_MAX_IDLE_PENDING_TIMEOUT
676 */
677 public long MAX_IDLE_PENDING_TIMEOUT;
678
679 /**
680 * Scaling factor to apply to current pending idle timeout each time we cycle through
681 * that state.
682 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
683 * @see #KEY_IDLE_PENDING_FACTOR
684 */
685 public float IDLE_PENDING_FACTOR;
686
687 /**
688 * This is the initial time that we want to sit in the idle state before waking up
689 * again to return to pending idle and allowing normal work to run.
690 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
691 * @see #KEY_IDLE_TIMEOUT
692 */
693 public long IDLE_TIMEOUT;
694
695 /**
696 * Maximum idle duration we will be allowed to use.
697 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
698 * @see #KEY_MAX_IDLE_TIMEOUT
699 */
700 public long MAX_IDLE_TIMEOUT;
701
702 /**
703 * Scaling factor to apply to current idle timeout each time we cycle through that state.
704 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
705 * @see #KEY_IDLE_FACTOR
706 */
707 public float IDLE_FACTOR;
708
709 /**
710 * This is the minimum time we will allow until the next upcoming alarm for us to
711 * actually go in to idle mode.
712 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
713 * @see #KEY_MIN_TIME_TO_ALARM
714 */
715 public long MIN_TIME_TO_ALARM;
716
717 /**
718 * Max amount of time to temporarily whitelist an app when it receives a high priority
719 * tickle.
720 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
721 * @see #KEY_MAX_TEMP_APP_WHITELIST_DURATION
722 */
723 public long MAX_TEMP_APP_WHITELIST_DURATION;
724
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700725 /**
726 * Amount of time we would like to whitelist an app that is receiving an MMS.
727 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
728 * @see #KEY_MMS_TEMP_APP_WHITELIST_DURATION
729 */
730 public long MMS_TEMP_APP_WHITELIST_DURATION;
731
Dianne Hackborn451c3462015-07-21 17:39:46 -0700732 /**
733 * Amount of time we would like to whitelist an app that is receiving an SMS.
734 * @see Settings.Global#DEVICE_IDLE_CONSTANTS
735 * @see #KEY_SMS_TEMP_APP_WHITELIST_DURATION
736 */
737 public long SMS_TEMP_APP_WHITELIST_DURATION;
738
Adam Lesinski31c05d12015-06-09 17:34:04 -0700739 private final ContentResolver mResolver;
Joe LaPennaf33b5bf2016-03-23 15:19:47 -0700740 private final boolean mHasWatch;
Adam Lesinski31c05d12015-06-09 17:34:04 -0700741 private final KeyValueListParser mParser = new KeyValueListParser(',');
742
743 public Constants(Handler handler, ContentResolver resolver) {
744 super(handler);
745 mResolver = resolver;
Joe LaPennaf33b5bf2016-03-23 15:19:47 -0700746 mHasWatch = getContext().getPackageManager().hasSystemFeature(
747 PackageManager.FEATURE_WATCH);
748 mResolver.registerContentObserver(Settings.Global.getUriFor(
749 mHasWatch ? Settings.Global.DEVICE_IDLE_CONSTANTS_WATCH
750 : Settings.Global.DEVICE_IDLE_CONSTANTS),
751 false, this);
Adam Lesinski31c05d12015-06-09 17:34:04 -0700752 updateConstants();
753 }
754
755 @Override
756 public void onChange(boolean selfChange, Uri uri) {
757 updateConstants();
758 }
759
760 private void updateConstants() {
761 synchronized (DeviceIdleController.this) {
762 try {
763 mParser.setString(Settings.Global.getString(mResolver,
Joe LaPennaf33b5bf2016-03-23 15:19:47 -0700764 mHasWatch ? Settings.Global.DEVICE_IDLE_CONSTANTS_WATCH
765 : Settings.Global.DEVICE_IDLE_CONSTANTS));
Adam Lesinski31c05d12015-06-09 17:34:04 -0700766 } catch (IllegalArgumentException e) {
767 // Failed to parse the settings string, log this and move on
768 // with defaults.
769 Slog.e(TAG, "Bad device idle settings", e);
770 }
771
Dianne Hackborn953fc942016-03-29 15:36:24 -0700772 LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getLong(
773 KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
774 !COMPRESS_TIME ? 5 * 60 * 1000L : 15 * 1000L);
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700775 LIGHT_PRE_IDLE_TIMEOUT = mParser.getLong(KEY_LIGHT_PRE_IDLE_TIMEOUT,
776 !COMPRESS_TIME ? 10 * 60 * 1000L : 30 * 1000L);
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700777 LIGHT_IDLE_TIMEOUT = mParser.getLong(KEY_LIGHT_IDLE_TIMEOUT,
Dianne Hackborn953fc942016-03-29 15:36:24 -0700778 !COMPRESS_TIME ? 5 * 60 * 1000L : 15 * 1000L);
779 LIGHT_IDLE_FACTOR = mParser.getFloat(KEY_LIGHT_IDLE_FACTOR,
780 2f);
781 LIGHT_MAX_IDLE_TIMEOUT = mParser.getLong(KEY_LIGHT_MAX_IDLE_TIMEOUT,
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700782 !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800783 LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = mParser.getLong(
784 KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET,
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700785 !COMPRESS_TIME ? 1 * 60 * 1000L : 15 * 1000L);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800786 LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = mParser.getLong(
787 KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET,
788 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L);
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700789 MIN_LIGHT_MAINTENANCE_TIME = mParser.getLong(
790 KEY_MIN_LIGHT_MAINTENANCE_TIME,
791 !COMPRESS_TIME ? 5 * 1000L : 1 * 1000L);
792 MIN_DEEP_MAINTENANCE_TIME = mParser.getLong(
793 KEY_MIN_DEEP_MAINTENANCE_TIME,
794 !COMPRESS_TIME ? 30 * 1000L : 5 * 1000L);
Joe LaPenna0c5d3e92016-03-24 13:29:56 -0700795 long inactiveTimeoutDefault = (mHasWatch ? 15 : 30) * 60 * 1000L;
Adam Lesinski31c05d12015-06-09 17:34:04 -0700796 INACTIVE_TIMEOUT = mParser.getLong(KEY_INACTIVE_TIMEOUT,
Joe LaPenna0c5d3e92016-03-24 13:29:56 -0700797 !COMPRESS_TIME ? inactiveTimeoutDefault : (inactiveTimeoutDefault / 10));
Adam Lesinski31c05d12015-06-09 17:34:04 -0700798 SENSING_TIMEOUT = mParser.getLong(KEY_SENSING_TIMEOUT,
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700799 !DEBUG ? 4 * 60 * 1000L : 60 * 1000L);
800 LOCATING_TIMEOUT = mParser.getLong(KEY_LOCATING_TIMEOUT,
801 !DEBUG ? 30 * 1000L : 15 * 1000L);
802 LOCATION_ACCURACY = mParser.getFloat(KEY_LOCATION_ACCURACY, 20);
Adam Lesinski31c05d12015-06-09 17:34:04 -0700803 MOTION_INACTIVE_TIMEOUT = mParser.getLong(KEY_MOTION_INACTIVE_TIMEOUT,
804 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
Joe LaPenna0c5d3e92016-03-24 13:29:56 -0700805 long idleAfterInactiveTimeout = (mHasWatch ? 15 : 30) * 60 * 1000L;
Adam Lesinski31c05d12015-06-09 17:34:04 -0700806 IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getLong(KEY_IDLE_AFTER_INACTIVE_TIMEOUT,
Joe LaPenna0c5d3e92016-03-24 13:29:56 -0700807 !COMPRESS_TIME ? idleAfterInactiveTimeout
808 : (idleAfterInactiveTimeout / 10));
Adam Lesinski31c05d12015-06-09 17:34:04 -0700809 IDLE_PENDING_TIMEOUT = mParser.getLong(KEY_IDLE_PENDING_TIMEOUT,
810 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L);
811 MAX_IDLE_PENDING_TIMEOUT = mParser.getLong(KEY_MAX_IDLE_PENDING_TIMEOUT,
812 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
813 IDLE_PENDING_FACTOR = mParser.getFloat(KEY_IDLE_PENDING_FACTOR,
814 2f);
815 IDLE_TIMEOUT = mParser.getLong(KEY_IDLE_TIMEOUT,
816 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
817 MAX_IDLE_TIMEOUT = mParser.getLong(KEY_MAX_IDLE_TIMEOUT,
818 !COMPRESS_TIME ? 6 * 60 * 60 * 1000L : 30 * 60 * 1000L);
819 IDLE_FACTOR = mParser.getFloat(KEY_IDLE_FACTOR,
820 2f);
821 MIN_TIME_TO_ALARM = mParser.getLong(KEY_MIN_TIME_TO_ALARM,
822 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700823 MAX_TEMP_APP_WHITELIST_DURATION = mParser.getLong(
824 KEY_MAX_TEMP_APP_WHITELIST_DURATION, 5 * 60 * 1000L);
825 MMS_TEMP_APP_WHITELIST_DURATION = mParser.getLong(
Dianne Hackborn0b6134b2015-07-14 18:48:07 -0700826 KEY_MMS_TEMP_APP_WHITELIST_DURATION, 60 * 1000L);
Dianne Hackborn451c3462015-07-21 17:39:46 -0700827 SMS_TEMP_APP_WHITELIST_DURATION = mParser.getLong(
828 KEY_SMS_TEMP_APP_WHITELIST_DURATION, 20 * 1000L);
Adam Lesinski31c05d12015-06-09 17:34:04 -0700829 }
830 }
831
832 void dump(PrintWriter pw) {
833 pw.println(" Settings:");
834
Dianne Hackborn953fc942016-03-29 15:36:24 -0700835 pw.print(" "); pw.print(KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("=");
836 TimeUtils.formatDuration(LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT, pw);
837 pw.println();
838
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700839 pw.print(" "); pw.print(KEY_LIGHT_PRE_IDLE_TIMEOUT); pw.print("=");
840 TimeUtils.formatDuration(LIGHT_PRE_IDLE_TIMEOUT, pw);
841 pw.println();
842
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700843 pw.print(" "); pw.print(KEY_LIGHT_IDLE_TIMEOUT); pw.print("=");
844 TimeUtils.formatDuration(LIGHT_IDLE_TIMEOUT, pw);
845 pw.println();
846
Dianne Hackborn953fc942016-03-29 15:36:24 -0700847 pw.print(" "); pw.print(KEY_LIGHT_IDLE_FACTOR); pw.print("=");
848 pw.print(LIGHT_IDLE_FACTOR);
849 pw.println();
850
851 pw.print(" "); pw.print(KEY_LIGHT_MAX_IDLE_TIMEOUT); pw.print("=");
852 TimeUtils.formatDuration(LIGHT_MAX_IDLE_TIMEOUT, pw);
853 pw.println();
854
Dianne Hackborn8ed2b972015-11-18 14:52:04 -0800855 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET); pw.print("=");
856 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MIN_BUDGET, pw);
857 pw.println();
858
859 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET); pw.print("=");
860 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MAX_BUDGET, pw);
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700861 pw.println();
862
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -0700863 pw.print(" "); pw.print(KEY_MIN_LIGHT_MAINTENANCE_TIME); pw.print("=");
864 TimeUtils.formatDuration(MIN_LIGHT_MAINTENANCE_TIME, pw);
865 pw.println();
866
867 pw.print(" "); pw.print(KEY_MIN_DEEP_MAINTENANCE_TIME); pw.print("=");
868 TimeUtils.formatDuration(MIN_DEEP_MAINTENANCE_TIME, pw);
869 pw.println();
870
Dianne Hackborna750a632015-06-16 17:18:23 -0700871 pw.print(" "); pw.print(KEY_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700872 TimeUtils.formatDuration(INACTIVE_TIMEOUT, pw);
873 pw.println();
874
Dianne Hackborna750a632015-06-16 17:18:23 -0700875 pw.print(" "); pw.print(KEY_SENSING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700876 TimeUtils.formatDuration(SENSING_TIMEOUT, pw);
877 pw.println();
878
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700879 pw.print(" "); pw.print(KEY_LOCATING_TIMEOUT); pw.print("=");
880 TimeUtils.formatDuration(LOCATING_TIMEOUT, pw);
881 pw.println();
882
883 pw.print(" "); pw.print(KEY_LOCATION_ACCURACY); pw.print("=");
884 pw.print(LOCATION_ACCURACY); pw.print("m");
885 pw.println();
886
Dianne Hackborna750a632015-06-16 17:18:23 -0700887 pw.print(" "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700888 TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT, pw);
889 pw.println();
890
Dianne Hackborna750a632015-06-16 17:18:23 -0700891 pw.print(" "); pw.print(KEY_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700892 TimeUtils.formatDuration(IDLE_AFTER_INACTIVE_TIMEOUT, pw);
893 pw.println();
894
Dianne Hackborna750a632015-06-16 17:18:23 -0700895 pw.print(" "); pw.print(KEY_IDLE_PENDING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700896 TimeUtils.formatDuration(IDLE_PENDING_TIMEOUT, pw);
897 pw.println();
898
Dianne Hackborna750a632015-06-16 17:18:23 -0700899 pw.print(" "); pw.print(KEY_MAX_IDLE_PENDING_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700900 TimeUtils.formatDuration(MAX_IDLE_PENDING_TIMEOUT, pw);
901 pw.println();
902
Dianne Hackborna750a632015-06-16 17:18:23 -0700903 pw.print(" "); pw.print(KEY_IDLE_PENDING_FACTOR); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700904 pw.println(IDLE_PENDING_FACTOR);
905
Dianne Hackborna750a632015-06-16 17:18:23 -0700906 pw.print(" "); pw.print(KEY_IDLE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700907 TimeUtils.formatDuration(IDLE_TIMEOUT, pw);
908 pw.println();
909
Dianne Hackborna750a632015-06-16 17:18:23 -0700910 pw.print(" "); pw.print(KEY_MAX_IDLE_TIMEOUT); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700911 TimeUtils.formatDuration(MAX_IDLE_TIMEOUT, pw);
912 pw.println();
913
Dianne Hackborna750a632015-06-16 17:18:23 -0700914 pw.print(" "); pw.print(KEY_IDLE_FACTOR); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700915 pw.println(IDLE_FACTOR);
916
Dianne Hackborna750a632015-06-16 17:18:23 -0700917 pw.print(" "); pw.print(KEY_MIN_TIME_TO_ALARM); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700918 TimeUtils.formatDuration(MIN_TIME_TO_ALARM, pw);
919 pw.println();
920
Dianne Hackborna750a632015-06-16 17:18:23 -0700921 pw.print(" "); pw.print(KEY_MAX_TEMP_APP_WHITELIST_DURATION); pw.print("=");
Adam Lesinski31c05d12015-06-09 17:34:04 -0700922 TimeUtils.formatDuration(MAX_TEMP_APP_WHITELIST_DURATION, pw);
923 pw.println();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700924
925 pw.print(" "); pw.print(KEY_MMS_TEMP_APP_WHITELIST_DURATION); pw.print("=");
926 TimeUtils.formatDuration(MMS_TEMP_APP_WHITELIST_DURATION, pw);
927 pw.println();
Dianne Hackborn451c3462015-07-21 17:39:46 -0700928
929 pw.print(" "); pw.print(KEY_SMS_TEMP_APP_WHITELIST_DURATION); pw.print("=");
930 TimeUtils.formatDuration(SMS_TEMP_APP_WHITELIST_DURATION, pw);
931 pw.println();
Adam Lesinski31c05d12015-06-09 17:34:04 -0700932 }
933 }
934
935 private Constants mConstants;
936
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700937 @Override
938 public void onAnyMotionResult(int result) {
939 if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")");
Kevin Gabayan92f15e62016-04-04 17:52:22 -0700940 if (result != AnyMotionDetector.RESULT_UNKNOWN) {
941 synchronized (this) {
942 cancelSensingTimeoutAlarmLocked();
943 }
944 }
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700945 if (result == AnyMotionDetector.RESULT_MOVED) {
946 if (DEBUG) Slog.d(TAG, "RESULT_MOVED received.");
947 synchronized (this) {
948 handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "sense_motion");
949 }
950 } else if (result == AnyMotionDetector.RESULT_STATIONARY) {
951 if (DEBUG) Slog.d(TAG, "RESULT_STATIONARY received.");
952 if (mState == STATE_SENSING) {
953 // If we are currently sensing, it is time to move to locating.
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700954 synchronized (this) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700955 mNotMoving = true;
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800956 stepIdleStateLocked("s:stationary");
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700957 }
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700958 } else if (mState == STATE_LOCATING) {
959 // If we are currently locating, note that we are not moving and step
960 // if we have located the position.
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700961 synchronized (this) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700962 mNotMoving = true;
963 if (mLocated) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800964 stepIdleStateLocked("s:stationary");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -0700965 }
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700966 }
967 }
968 }
969 }
970
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700971 static final int MSG_WRITE_CONFIG = 1;
972 static final int MSG_REPORT_IDLE_ON = 2;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700973 static final int MSG_REPORT_IDLE_ON_LIGHT = 3;
974 static final int MSG_REPORT_IDLE_OFF = 4;
975 static final int MSG_REPORT_ACTIVE = 5;
976 static final int MSG_TEMP_APP_WHITELIST_TIMEOUT = 6;
Yao Chenca5edbb2016-01-13 14:44:36 -0800977 static final int MSG_REPORT_MAINTENANCE_ACTIVITY = 7;
Dianne Hackborn945c9c92016-03-30 14:55:00 -0700978 static final int MSG_FINISH_IDLE_OP = 8;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700979
980 final class MyHandler extends Handler {
981 MyHandler(Looper looper) {
982 super(looper);
983 }
984
985 @Override public void handleMessage(Message msg) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -0700986 if (DEBUG) Slog.d(TAG, "handleMessage(" + msg.what + ")");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700987 switch (msg.what) {
988 case MSG_WRITE_CONFIG: {
989 handleWriteConfigFile();
990 } break;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700991 case MSG_REPORT_IDLE_ON:
992 case MSG_REPORT_IDLE_ON_LIGHT: {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -0700993 EventLogTags.writeDeviceIdleOnStart();
Dianne Hackbornb6843652016-02-22 12:20:13 -0800994 final boolean deepChanged;
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700995 final boolean lightChanged;
996 if (msg.what == MSG_REPORT_IDLE_ON) {
Dianne Hackbornb6843652016-02-22 12:20:13 -0800997 deepChanged = mLocalPowerManager.setDeviceIdleMode(true);
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700998 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
999 } else {
Dianne Hackbornb6843652016-02-22 12:20:13 -08001000 deepChanged = mLocalPowerManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001001 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(true);
1002 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001003 try {
1004 mNetworkPolicyManager.setDeviceIdleMode(true);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001005 mBatteryStats.noteDeviceIdleMode(msg.what == MSG_REPORT_IDLE_ON
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001006 ? BatteryStats.DEVICE_IDLE_MODE_DEEP
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001007 : BatteryStats.DEVICE_IDLE_MODE_LIGHT, null, Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001008 } catch (RemoteException e) {
1009 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08001010 if (deepChanged) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001011 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
1012 }
1013 if (lightChanged) {
1014 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL);
1015 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001016 EventLogTags.writeDeviceIdleOnComplete();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001017 } break;
1018 case MSG_REPORT_IDLE_OFF: {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001019 EventLogTags.writeDeviceIdleOffStart("unknown");
Dianne Hackbornb6843652016-02-22 12:20:13 -08001020 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001021 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001022 try {
1023 mNetworkPolicyManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001024 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF,
1025 null, Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001026 } catch (RemoteException e) {
1027 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08001028 if (deepChanged) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001029 incActiveIdleOps();
1030 getContext().sendOrderedBroadcastAsUser(mIdleIntent, UserHandle.ALL,
1031 null, mIdleStartedDoneReceiver, null, 0, null, null);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001032 }
1033 if (lightChanged) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001034 incActiveIdleOps();
1035 getContext().sendOrderedBroadcastAsUser(mLightIdleIntent, UserHandle.ALL,
1036 null, mIdleStartedDoneReceiver, null, 0, null, null);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001037 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001038 // Always start with one active op for the message being sent here.
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001039 // Now we are done!
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001040 decActiveIdleOps();
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001041 EventLogTags.writeDeviceIdleOffComplete();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001042 } break;
1043 case MSG_REPORT_ACTIVE: {
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001044 String activeReason = (String)msg.obj;
1045 int activeUid = msg.arg1;
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001046 EventLogTags.writeDeviceIdleOffStart(
1047 activeReason != null ? activeReason : "unknown");
Dianne Hackbornb6843652016-02-22 12:20:13 -08001048 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001049 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001050 try {
1051 mNetworkPolicyManager.setDeviceIdleMode(false);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001052 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF,
1053 activeReason, activeUid);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001054 } catch (RemoteException e) {
1055 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08001056 if (deepChanged) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001057 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
1058 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001059 if (lightChanged) {
1060 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL);
1061 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001062 EventLogTags.writeDeviceIdleOffComplete();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001063 } break;
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001064 case MSG_TEMP_APP_WHITELIST_TIMEOUT: {
1065 int uid = msg.arg1;
1066 checkTempAppWhitelistTimeout(uid);
1067 } break;
Yao Chenca5edbb2016-01-13 14:44:36 -08001068 case MSG_REPORT_MAINTENANCE_ACTIVITY: {
1069 boolean active = (msg.arg1 == 1);
1070 final int size = mMaintenanceActivityListeners.beginBroadcast();
1071 try {
1072 for (int i = 0; i < size; i++) {
1073 try {
1074 mMaintenanceActivityListeners.getBroadcastItem(i)
1075 .onMaintenanceActivityChanged(active);
1076 } catch (RemoteException ignored) {
1077 }
1078 }
1079 } finally {
1080 mMaintenanceActivityListeners.finishBroadcast();
1081 }
1082 } break;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001083 case MSG_FINISH_IDLE_OP: {
1084 decActiveIdleOps();
1085 } break;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001086 }
1087 }
1088 }
1089
1090 final MyHandler mHandler;
1091
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001092 BinderService mBinderService;
1093
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001094 private final class BinderService extends IDeviceIdleController.Stub {
1095 @Override public void addPowerSaveWhitelistApp(String name) {
1096 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1097 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001098 long ident = Binder.clearCallingIdentity();
1099 try {
1100 addPowerSaveWhitelistAppInternal(name);
1101 } finally {
1102 Binder.restoreCallingIdentity(ident);
1103 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001104 }
1105
1106 @Override public void removePowerSaveWhitelistApp(String name) {
1107 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
1108 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001109 long ident = Binder.clearCallingIdentity();
1110 try {
1111 removePowerSaveWhitelistAppInternal(name);
1112 } finally {
1113 Binder.restoreCallingIdentity(ident);
1114 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001115 }
1116
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001117 @Override public String[] getSystemPowerWhitelistExceptIdle() {
1118 return getSystemPowerWhitelistExceptIdleInternal();
1119 }
1120
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001121 @Override public String[] getSystemPowerWhitelist() {
1122 return getSystemPowerWhitelistInternal();
1123 }
1124
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001125 @Override public String[] getUserPowerWhitelist() {
1126 return getUserPowerWhitelistInternal();
1127 }
1128
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001129 @Override public String[] getFullPowerWhitelistExceptIdle() {
1130 return getFullPowerWhitelistExceptIdleInternal();
1131 }
1132
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001133 @Override public String[] getFullPowerWhitelist() {
1134 return getFullPowerWhitelistInternal();
1135 }
1136
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001137 @Override public int[] getAppIdWhitelistExceptIdle() {
1138 return getAppIdWhitelistExceptIdleInternal();
1139 }
1140
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001141 @Override public int[] getAppIdWhitelist() {
1142 return getAppIdWhitelistInternal();
1143 }
1144
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001145 @Override public int[] getAppIdUserWhitelist() {
1146 return getAppIdUserWhitelistInternal();
1147 }
1148
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001149 @Override public int[] getAppIdTempWhitelist() {
1150 return getAppIdTempWhitelistInternal();
1151 }
1152
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001153 @Override public boolean isPowerSaveWhitelistExceptIdleApp(String name) {
1154 return isPowerSaveWhitelistExceptIdleAppInternal(name);
1155 }
1156
Amith Yamasani06bf8242015-05-08 16:36:21 -07001157 @Override public boolean isPowerSaveWhitelistApp(String name) {
1158 return isPowerSaveWhitelistAppInternal(name);
1159 }
1160
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001161 @Override public void addPowerSaveTempWhitelistApp(String packageName, long duration,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001162 int userId, String reason) throws RemoteException {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001163 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001164 }
1165
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001166 @Override public long addPowerSaveTempWhitelistAppForMms(String packageName,
1167 int userId, String reason) throws RemoteException {
1168 long duration = mConstants.MMS_TEMP_APP_WHITELIST_DURATION;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001169 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001170 return duration;
1171 }
1172
Dianne Hackborn451c3462015-07-21 17:39:46 -07001173 @Override public long addPowerSaveTempWhitelistAppForSms(String packageName,
1174 int userId, String reason) throws RemoteException {
1175 long duration = mConstants.SMS_TEMP_APP_WHITELIST_DURATION;
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001176 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason);
Dianne Hackborn451c3462015-07-21 17:39:46 -07001177 return duration;
1178 }
1179
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001180 @Override public void exitIdle(String reason) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001181 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER,
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001182 null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001183 long ident = Binder.clearCallingIdentity();
1184 try {
1185 exitIdleInternal(reason);
1186 } finally {
1187 Binder.restoreCallingIdentity(ident);
1188 }
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001189 }
1190
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001191 @Override public void downloadServiceActive(IBinder token) {
1192 getContext().enforceCallingOrSelfPermission(
1193 "android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS", null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001194 long ident = Binder.clearCallingIdentity();
1195 try {
1196 DeviceIdleController.this.downloadServiceActive(token);
1197 } finally {
1198 Binder.restoreCallingIdentity(ident);
1199 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001200 }
1201
1202 @Override public void downloadServiceInactive() {
1203 getContext().enforceCallingOrSelfPermission(
1204 "android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS", null);
Dianne Hackbornc9b2cd12016-01-20 10:54:29 -08001205 long ident = Binder.clearCallingIdentity();
1206 try {
1207 DeviceIdleController.this.downloadServiceInactive();
1208 } finally {
1209 Binder.restoreCallingIdentity(ident);
1210 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001211 }
1212
Yao Chenca5edbb2016-01-13 14:44:36 -08001213 @Override public boolean registerMaintenanceActivityListener(
1214 IMaintenanceActivityListener listener) {
1215 return DeviceIdleController.this.registerMaintenanceActivityListener(listener);
1216 }
1217
1218 @Override public void unregisterMaintenanceActivityListener(
1219 IMaintenanceActivityListener listener) {
1220 DeviceIdleController.this.unregisterMaintenanceActivityListener(listener);
1221 }
1222
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001223 @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1224 DeviceIdleController.this.dump(fd, pw, args);
1225 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001226
1227 @Override public void onShellCommand(FileDescriptor in, FileDescriptor out,
1228 FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
1229 (new Shell()).exec(this, in, out, err, args, resultReceiver);
1230 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001231 }
1232
Dianne Hackborna750a632015-06-16 17:18:23 -07001233 public final class LocalService {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001234 public void addPowerSaveTempWhitelistAppDirect(int appId, long duration, boolean sync,
1235 String reason) {
1236 addPowerSaveTempWhitelistAppDirectInternal(0, appId, duration, sync, reason);
1237 }
1238
1239 public void setNetworkPolicyTempWhitelistCallback(Runnable callback) {
1240 setNetworkPolicyTempWhitelistCallbackInternal(callback);
Dianne Hackborna750a632015-06-16 17:18:23 -07001241 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001242
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001243 public void setJobsActive(boolean active) {
1244 DeviceIdleController.this.setJobsActive(active);
1245 }
1246
1247 // Up-call from alarm manager.
1248 public void setAlarmsActive(boolean active) {
1249 DeviceIdleController.this.setAlarmsActive(active);
1250 }
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001251
1252 /**
1253 * Returns the array of app ids whitelisted by user. Take care not to
1254 * modify this, as it is a reference to the original copy. But the reference
1255 * can change when the list changes, so it needs to be re-acquired when
1256 * {@link PowerManager#ACTION_POWER_SAVE_WHITELIST_CHANGED} is sent.
1257 */
1258 public int[] getPowerSaveWhitelistUserAppIds() {
1259 return DeviceIdleController.this.getPowerSaveWhitelistUserAppIds();
1260 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001261 }
1262
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001263 public DeviceIdleController(Context context) {
1264 super(context);
1265 mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml"));
1266 mHandler = new MyHandler(BackgroundThread.getHandler().getLooper());
1267 }
1268
Amith Yamasanicb926fc2016-03-14 17:15:20 -07001269 int[] getPowerSaveWhitelistUserAppIds() {
1270 synchronized (this) {
1271 return mPowerSaveWhitelistUserAppIdArray;
1272 }
1273 }
1274
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001275 private static File getSystemDir() {
1276 return new File(Environment.getDataDirectory(), "system");
1277 }
1278
1279 @Override
1280 public void onStart() {
1281 final PackageManager pm = getContext().getPackageManager();
1282
1283 synchronized (this) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08001284 mLightEnabled = mDeepEnabled = getContext().getResources().getBoolean(
Dianne Hackborn92617032015-06-19 15:32:19 -07001285 com.android.internal.R.bool.config_enableAutoPowerModes);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001286 SystemConfig sysConfig = SystemConfig.getInstance();
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001287 ArraySet<String> allowPowerExceptIdle = sysConfig.getAllowInPowerSaveExceptIdle();
1288 for (int i=0; i<allowPowerExceptIdle.size(); i++) {
1289 String pkg = allowPowerExceptIdle.valueAt(i);
1290 try {
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07001291 ApplicationInfo ai = pm.getApplicationInfo(pkg,
1292 PackageManager.MATCH_SYSTEM_ONLY);
1293 int appid = UserHandle.getAppId(ai.uid);
1294 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
1295 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001296 } catch (PackageManager.NameNotFoundException e) {
1297 }
1298 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001299 ArraySet<String> allowPower = sysConfig.getAllowInPowerSave();
1300 for (int i=0; i<allowPower.size(); i++) {
1301 String pkg = allowPower.valueAt(i);
1302 try {
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07001303 ApplicationInfo ai = pm.getApplicationInfo(pkg,
1304 PackageManager.MATCH_SYSTEM_ONLY);
1305 int appid = UserHandle.getAppId(ai.uid);
1306 // These apps are on both the whitelist-except-idle as well
1307 // as the full whitelist, so they apply in all cases.
1308 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
1309 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
1310 mPowerSaveWhitelistApps.put(ai.packageName, appid);
1311 mPowerSaveWhitelistSystemAppIds.put(appid, true);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001312 } catch (PackageManager.NameNotFoundException e) {
1313 }
1314 }
1315
Adam Lesinski31c05d12015-06-09 17:34:04 -07001316 mConstants = new Constants(mHandler, getContext().getContentResolver());
1317
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001318 readConfigFileLocked();
1319 updateWhitelistAppIdsLocked();
1320
1321 mScreenOn = true;
1322 // Start out assuming we are charging. If we aren't, we will at least get
1323 // a battery update the next time the level drops.
1324 mCharging = true;
1325 mState = STATE_ACTIVE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001326 mLightState = LIGHT_STATE_ACTIVE;
Adam Lesinski31c05d12015-06-09 17:34:04 -07001327 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001328 }
1329
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001330 mBinderService = new BinderService();
1331 publishBinderService(Context.DEVICE_IDLE_CONTROLLER, mBinderService);
Dianne Hackborna750a632015-06-16 17:18:23 -07001332 publishLocalService(LocalService.class, new LocalService());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001333 }
1334
1335 @Override
1336 public void onBootPhase(int phase) {
1337 if (phase == PHASE_SYSTEM_SERVICES_READY) {
1338 synchronized (this) {
1339 mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
1340 mBatteryStats = BatteryStatsService.getService();
1341 mLocalPowerManager = getLocalService(PowerManagerInternal.class);
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001342 mPowerManager = getContext().getSystemService(PowerManager.class);
1343 mActiveIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
1344 "deviceidle_maint");
1345 mActiveIdleWakeLock.setReferenceCounted(false);
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001346 mLocalAlarmManager = getLocalService(AlarmManagerService.LocalService.class);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001347 mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface(
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001348 ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001349 mDisplayManager = (DisplayManager) getContext().getSystemService(
1350 Context.DISPLAY_SERVICE);
1351 mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001352 int sigMotionSensorId = getContext().getResources().getInteger(
1353 com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor);
1354 if (sigMotionSensorId > 0) {
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001355 mMotionSensor = mSensorManager.getDefaultSensor(sigMotionSensorId, true);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001356 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001357 if (mMotionSensor == null && getContext().getResources().getBoolean(
Joe LaPenna23d681b2015-08-27 15:12:11 -07001358 com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) {
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001359 mMotionSensor = mSensorManager.getDefaultSensor(
1360 Sensor.TYPE_WRIST_TILT_GESTURE, true);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001361 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001362 if (mMotionSensor == null) {
Joe LaPenna23d681b2015-08-27 15:12:11 -07001363 // As a last ditch, fall back to SMD.
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001364 mMotionSensor = mSensorManager.getDefaultSensor(
1365 Sensor.TYPE_SIGNIFICANT_MOTION, true);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001366 }
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001367
Joe LaPenna23d681b2015-08-27 15:12:11 -07001368 if (getContext().getResources().getBoolean(
1369 com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) {
1370 mLocationManager = (LocationManager) getContext().getSystemService(
1371 Context.LOCATION_SERVICE);
1372 mLocationRequest = new LocationRequest()
1373 .setQuality(LocationRequest.ACCURACY_FINE)
1374 .setInterval(0)
1375 .setFastestInterval(0)
1376 .setNumUpdates(1);
1377 }
1378
1379 float angleThreshold = getContext().getResources().getInteger(
1380 com.android.internal.R.integer.config_autoPowerModeThresholdAngle) / 100f;
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001381 mAnyMotionDetector = new AnyMotionDetector(
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001382 (PowerManager) getContext().getSystemService(Context.POWER_SERVICE),
Joe LaPenna23d681b2015-08-27 15:12:11 -07001383 mHandler, mSensorManager, this, angleThreshold);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001384
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001385 mIdleIntent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001386 mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1387 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001388 mLightIdleIntent = new Intent(PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
1389 mLightIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1390 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001391
1392 IntentFilter filter = new IntentFilter();
1393 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001394 getContext().registerReceiver(mReceiver, filter);
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07001395 filter = new IntentFilter();
1396 filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
1397 filter.addDataScheme("package");
1398 getContext().registerReceiver(mReceiver, filter);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001399
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001400 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001401 mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001402 mDisplayManager.registerDisplayListener(mDisplayListener, null);
1403 updateDisplayLocked();
1404 }
1405 }
1406 }
1407
1408 public boolean addPowerSaveWhitelistAppInternal(String name) {
1409 synchronized (this) {
1410 try {
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07001411 ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name,
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07001412 PackageManager.MATCH_UNINSTALLED_PACKAGES);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001413 if (mPowerSaveWhitelistUserApps.put(name, UserHandle.getAppId(ai.uid)) == null) {
1414 reportPowerSaveWhitelistChangedLocked();
1415 updateWhitelistAppIdsLocked();
1416 writeConfigFileLocked();
1417 }
1418 return true;
1419 } catch (PackageManager.NameNotFoundException e) {
1420 return false;
1421 }
1422 }
1423 }
1424
1425 public boolean removePowerSaveWhitelistAppInternal(String name) {
1426 synchronized (this) {
1427 if (mPowerSaveWhitelistUserApps.remove(name) != null) {
1428 reportPowerSaveWhitelistChangedLocked();
1429 updateWhitelistAppIdsLocked();
1430 writeConfigFileLocked();
1431 return true;
1432 }
1433 }
1434 return false;
1435 }
1436
Felipe Lemef8a46232016-02-10 13:51:54 -08001437 public boolean getPowerSaveWhitelistAppInternal(String name) {
1438 synchronized (this) {
1439 return mPowerSaveWhitelistUserApps.containsKey(name);
1440 }
1441 }
1442
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001443 public String[] getSystemPowerWhitelistExceptIdleInternal() {
1444 synchronized (this) {
1445 int size = mPowerSaveWhitelistAppsExceptIdle.size();
1446 String[] apps = new String[size];
1447 for (int i = 0; i < size; i++) {
1448 apps[i] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i);
1449 }
1450 return apps;
1451 }
1452 }
1453
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001454 public String[] getSystemPowerWhitelistInternal() {
1455 synchronized (this) {
1456 int size = mPowerSaveWhitelistApps.size();
1457 String[] apps = new String[size];
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001458 for (int i = 0; i < size; i++) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001459 apps[i] = mPowerSaveWhitelistApps.keyAt(i);
1460 }
1461 return apps;
1462 }
1463 }
1464
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001465 public String[] getUserPowerWhitelistInternal() {
1466 synchronized (this) {
1467 int size = mPowerSaveWhitelistUserApps.size();
1468 String[] apps = new String[size];
1469 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
1470 apps[i] = mPowerSaveWhitelistUserApps.keyAt(i);
1471 }
1472 return apps;
1473 }
1474 }
1475
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001476 public String[] getFullPowerWhitelistExceptIdleInternal() {
1477 synchronized (this) {
1478 int size = mPowerSaveWhitelistAppsExceptIdle.size() + mPowerSaveWhitelistUserApps.size();
1479 String[] apps = new String[size];
1480 int cur = 0;
1481 for (int i = 0; i < mPowerSaveWhitelistAppsExceptIdle.size(); i++) {
1482 apps[cur] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i);
1483 cur++;
1484 }
1485 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
1486 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i);
1487 cur++;
1488 }
1489 return apps;
1490 }
1491 }
1492
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001493 public String[] getFullPowerWhitelistInternal() {
1494 synchronized (this) {
1495 int size = mPowerSaveWhitelistApps.size() + mPowerSaveWhitelistUserApps.size();
1496 String[] apps = new String[size];
1497 int cur = 0;
1498 for (int i = 0; i < mPowerSaveWhitelistApps.size(); i++) {
1499 apps[cur] = mPowerSaveWhitelistApps.keyAt(i);
1500 cur++;
1501 }
1502 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) {
1503 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i);
1504 cur++;
1505 }
1506 return apps;
1507 }
1508 }
1509
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001510 public boolean isPowerSaveWhitelistExceptIdleAppInternal(String packageName) {
1511 synchronized (this) {
1512 return mPowerSaveWhitelistAppsExceptIdle.containsKey(packageName)
1513 || mPowerSaveWhitelistUserApps.containsKey(packageName);
1514 }
1515 }
1516
Amith Yamasani06bf8242015-05-08 16:36:21 -07001517 public boolean isPowerSaveWhitelistAppInternal(String packageName) {
1518 synchronized (this) {
1519 return mPowerSaveWhitelistApps.containsKey(packageName)
1520 || mPowerSaveWhitelistUserApps.containsKey(packageName);
1521 }
1522 }
1523
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001524 public int[] getAppIdWhitelistExceptIdleInternal() {
1525 synchronized (this) {
1526 return mPowerSaveWhitelistExceptIdleAppIdArray;
1527 }
1528 }
1529
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001530 public int[] getAppIdWhitelistInternal() {
1531 synchronized (this) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001532 return mPowerSaveWhitelistAllAppIdArray;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001533 }
1534 }
1535
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001536 public int[] getAppIdUserWhitelistInternal() {
1537 synchronized (this) {
1538 return mPowerSaveWhitelistUserAppIdArray;
1539 }
1540 }
1541
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001542 public int[] getAppIdTempWhitelistInternal() {
1543 synchronized (this) {
1544 return mTempWhitelistAppIdArray;
1545 }
1546 }
1547
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001548 void addPowerSaveTempWhitelistAppChecked(String packageName, long duration,
1549 int userId, String reason) throws RemoteException {
1550 getContext().enforceCallingPermission(
1551 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
1552 "No permission to change device idle whitelist");
1553 final int callingUid = Binder.getCallingUid();
1554 userId = ActivityManagerNative.getDefault().handleIncomingUser(
1555 Binder.getCallingPid(),
1556 callingUid,
1557 userId,
1558 /*allowAll=*/ false,
1559 /*requireFull=*/ false,
1560 "addPowerSaveTempWhitelistApp", null);
1561 final long token = Binder.clearCallingIdentity();
1562 try {
1563 addPowerSaveTempWhitelistAppInternal(callingUid,
1564 packageName, duration, userId, true, reason);
1565 } finally {
1566 Binder.restoreCallingIdentity(token);
1567 }
1568 }
1569
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001570 /**
1571 * Adds an app to the temporary whitelist and resets the endTime for granting the
1572 * app an exemption to access network and acquire wakelocks.
1573 */
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001574 void addPowerSaveTempWhitelistAppInternal(int callingUid, String packageName,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001575 long duration, int userId, boolean sync, String reason) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001576 try {
Jeff Sharkeye06b4d12016-01-06 14:51:50 -07001577 int uid = getContext().getPackageManager().getPackageUidAsUser(packageName, userId);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001578 int appId = UserHandle.getAppId(uid);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001579 addPowerSaveTempWhitelistAppDirectInternal(callingUid, appId, duration, sync, reason);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001580 } catch (NameNotFoundException e) {
1581 }
1582 }
1583
Dianne Hackborna750a632015-06-16 17:18:23 -07001584 /**
1585 * Adds an app to the temporary whitelist and resets the endTime for granting the
1586 * app an exemption to access network and acquire wakelocks.
1587 */
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07001588 void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int appId,
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001589 long duration, boolean sync, String reason) {
Dianne Hackborna750a632015-06-16 17:18:23 -07001590 final long timeNow = SystemClock.elapsedRealtime();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001591 Runnable networkPolicyTempWhitelistCallback = null;
Dianne Hackborna750a632015-06-16 17:18:23 -07001592 synchronized (this) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07001593 int callingAppId = UserHandle.getAppId(callingUid);
1594 if (callingAppId >= Process.FIRST_APPLICATION_UID) {
1595 if (!mPowerSaveWhitelistSystemAppIds.get(callingAppId)) {
1596 throw new SecurityException("Calling app " + UserHandle.formatUid(callingUid)
1597 + " is not on whitelist");
1598 }
1599 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001600 duration = Math.min(duration, mConstants.MAX_TEMP_APP_WHITELIST_DURATION);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001601 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId);
1602 final boolean newEntry = entry == null;
Dianne Hackborna750a632015-06-16 17:18:23 -07001603 // Set the new end time
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001604 if (newEntry) {
1605 entry = new Pair<>(new MutableLong(0), reason);
1606 mTempWhitelistAppIdEndTimes.put(appId, entry);
1607 }
1608 entry.first.value = timeNow + duration;
Dianne Hackborna750a632015-06-16 17:18:23 -07001609 if (DEBUG) {
1610 Slog.d(TAG, "Adding AppId " + appId + " to temp whitelist");
1611 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001612 if (newEntry) {
Dianne Hackborna750a632015-06-16 17:18:23 -07001613 // No pending timeout for the app id, post a delayed message
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001614 try {
1615 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_START,
1616 reason, appId);
1617 } catch (RemoteException e) {
1618 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001619 postTempActiveTimeoutMessage(appId, duration);
1620 updateTempWhitelistAppIdsLocked();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001621 if (mNetworkPolicyTempWhitelistCallback != null) {
1622 if (!sync) {
1623 mHandler.post(mNetworkPolicyTempWhitelistCallback);
1624 } else {
1625 networkPolicyTempWhitelistCallback = mNetworkPolicyTempWhitelistCallback;
1626 }
1627 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001628 reportTempWhitelistChangedLocked();
1629 }
1630 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001631 if (networkPolicyTempWhitelistCallback != null) {
1632 networkPolicyTempWhitelistCallback.run();
1633 }
1634 }
1635
1636 public void setNetworkPolicyTempWhitelistCallbackInternal(Runnable callback) {
1637 synchronized (this) {
1638 mNetworkPolicyTempWhitelistCallback = callback;
1639 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001640 }
1641
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001642 private void postTempActiveTimeoutMessage(int uid, long delay) {
1643 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, uid, 0),
1644 delay);
1645 }
1646
1647 void checkTempAppWhitelistTimeout(int uid) {
Dianne Hackborna750a632015-06-16 17:18:23 -07001648 final long timeNow = SystemClock.elapsedRealtime();
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001649 synchronized (this) {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001650 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(uid);
1651 if (entry == null) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001652 // Nothing to do
1653 return;
1654 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001655 if (timeNow >= entry.first.value) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001656 mTempWhitelistAppIdEndTimes.delete(uid);
1657 if (DEBUG) {
1658 Slog.d(TAG, "Removing UID " + uid + " from temp whitelist");
1659 }
1660 updateTempWhitelistAppIdsLocked();
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001661 if (mNetworkPolicyTempWhitelistCallback != null) {
1662 mHandler.post(mNetworkPolicyTempWhitelistCallback);
1663 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001664 reportTempWhitelistChangedLocked();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001665 try {
1666 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH,
1667 entry.second, uid);
1668 } catch (RemoteException e) {
1669 }
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001670 } else {
1671 // Need more time
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001672 postTempActiveTimeoutMessage(uid, entry.first.value - timeNow);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07001673 }
1674 }
1675 }
1676
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001677 public void exitIdleInternal(String reason) {
1678 synchronized (this) {
1679 becomeActiveLocked(reason, Binder.getCallingUid());
1680 }
1681 }
1682
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001683 void updateDisplayLocked() {
1684 mCurDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
1685 // We consider any situation where the display is showing something to be it on,
1686 // because if there is anything shown we are going to be updating it at some
1687 // frequency so can't be allowed to go into deep sleeps.
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001688 boolean screenOn = mCurDisplay.getState() == Display.STATE_ON;
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001689 if (DEBUG) Slog.d(TAG, "updateDisplayLocked: screenOn=" + screenOn);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001690 if (!screenOn && mScreenOn) {
1691 mScreenOn = false;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001692 if (!mForceIdle) {
1693 becomeInactiveIfAppropriateLocked();
1694 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001695 } else if (screenOn) {
1696 mScreenOn = true;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001697 if (!mForceIdle) {
1698 becomeActiveLocked("screen", Process.myUid());
1699 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001700 }
1701 }
1702
1703 void updateChargingLocked(boolean charging) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001704 if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001705 if (!charging && mCharging) {
1706 mCharging = false;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001707 if (!mForceIdle) {
1708 becomeInactiveIfAppropriateLocked();
1709 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001710 } else if (charging) {
1711 mCharging = charging;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001712 if (!mForceIdle) {
1713 becomeActiveLocked("charging", Process.myUid());
1714 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001715 }
1716 }
1717
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001718 void scheduleReportActiveLocked(String activeReason, int activeUid) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001719 Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid, 0, activeReason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001720 mHandler.sendMessage(msg);
1721 }
1722
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001723 void becomeActiveLocked(String activeReason, int activeUid) {
1724 if (DEBUG) Slog.i(TAG, "becomeActiveLocked, reason = " + activeReason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001725 if (mState != STATE_ACTIVE || mLightState != STATE_ACTIVE) {
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001726 EventLogTags.writeDeviceIdle(STATE_ACTIVE, activeReason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001727 EventLogTags.writeDeviceIdleLight(LIGHT_STATE_ACTIVE, activeReason);
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001728 scheduleReportActiveLocked(activeReason, activeUid);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001729 mState = STATE_ACTIVE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001730 mLightState = LIGHT_STATE_ACTIVE;
Adam Lesinski31c05d12015-06-09 17:34:04 -07001731 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001732 mCurIdleBudget = 0;
1733 mMaintenanceStartTime = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001734 resetIdleManagementLocked();
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001735 resetLightIdleManagementLocked();
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001736 addEvent(EVENT_NORMAL);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001737 }
1738 }
1739
1740 void becomeInactiveIfAppropriateLocked() {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001741 if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()");
Dianne Hackbornb6843652016-02-22 12:20:13 -08001742 if ((!mScreenOn && !mCharging) || mForceIdle) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001743 // Screen has turned off; we are now going to become inactive and start
1744 // waiting to see if we will ultimately go idle.
Dianne Hackbornb6843652016-02-22 12:20:13 -08001745 if (mState == STATE_ACTIVE && mDeepEnabled) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001746 mState = STATE_INACTIVE;
1747 if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE");
1748 resetIdleManagementLocked();
1749 scheduleAlarmLocked(mInactiveTimeout, false);
1750 EventLogTags.writeDeviceIdle(mState, "no activity");
1751 }
Dianne Hackbornb6843652016-02-22 12:20:13 -08001752 if (mLightState == LIGHT_STATE_ACTIVE && mLightEnabled) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001753 mLightState = LIGHT_STATE_INACTIVE;
1754 if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE");
1755 resetLightIdleManagementLocked();
Dianne Hackborn953fc942016-03-29 15:36:24 -07001756 scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001757 EventLogTags.writeDeviceIdleLight(mLightState, "no activity");
1758 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001759 }
1760 }
1761
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001762 void resetIdleManagementLocked() {
1763 mNextIdlePendingDelay = 0;
1764 mNextIdleDelay = 0;
Dianne Hackborn953fc942016-03-29 15:36:24 -07001765 mNextLightIdleDelay = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001766 cancelAlarmLocked();
Kevin Gabayan92f15e62016-04-04 17:52:22 -07001767 cancelSensingTimeoutAlarmLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001768 cancelLocatingLocked();
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001769 stopMonitoringMotionLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001770 mAnyMotionDetector.stop();
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001771 }
1772
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001773 void resetLightIdleManagementLocked() {
1774 cancelLightAlarmLocked();
1775 }
1776
Dianne Hackborn4a503b12015-08-06 22:19:06 -07001777 void exitForceIdleLocked() {
1778 if (mForceIdle) {
1779 mForceIdle = false;
1780 if (mScreenOn || mCharging) {
1781 becomeActiveLocked("exit-force-idle", Process.myUid());
1782 }
1783 }
1784 }
1785
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001786 void stepLightIdleStateLocked(String reason) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001787 if (mLightState == LIGHT_STATE_OVERRIDE) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08001788 // If we are already in deep device idle mode, then
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001789 // there is nothing left to do for light mode.
1790 return;
1791 }
1792
1793 if (DEBUG) Slog.d(TAG, "stepLightIdleStateLocked: mLightState=" + mLightState);
1794 EventLogTags.writeDeviceIdleLightStep();
1795
1796 switch (mLightState) {
1797 case LIGHT_STATE_INACTIVE:
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001798 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
Dianne Hackborn953fc942016-03-29 15:36:24 -07001799 // Reset the upcoming idle delays.
1800 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001801 mMaintenanceStartTime = 0;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001802 if (!isOpsInactiveLocked()) {
1803 // We have some active ops going on... give them a chance to finish
1804 // before going in to our first idle.
1805 mLightState = LIGHT_STATE_PRE_IDLE;
1806 EventLogTags.writeDeviceIdleLight(mLightState, reason);
1807 scheduleLightAlarmLocked(mConstants.LIGHT_PRE_IDLE_TIMEOUT);
1808 break;
1809 }
1810 // Nothing active, fall through to immediately idle.
1811 case LIGHT_STATE_PRE_IDLE:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001812 case LIGHT_STATE_IDLE_MAINTENANCE:
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001813 if (mMaintenanceStartTime != 0) {
1814 long duration = SystemClock.elapsedRealtime() - mMaintenanceStartTime;
1815 if (duration < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
1816 // We didn't use up all of our minimum budget; add this to the reserve.
1817 mCurIdleBudget += (mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET-duration);
1818 } else {
1819 // We used more than our minimum budget; this comes out of the reserve.
1820 mCurIdleBudget -= (duration-mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET);
1821 }
1822 }
1823 mMaintenanceStartTime = 0;
Dianne Hackborn953fc942016-03-29 15:36:24 -07001824 scheduleLightAlarmLocked(mNextLightIdleDelay);
1825 mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT,
1826 (long)(mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR));
1827 if (mNextLightIdleDelay < mConstants.LIGHT_IDLE_TIMEOUT) {
1828 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT;
1829 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001830 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_STATE_IDLE.");
1831 mLightState = LIGHT_STATE_IDLE;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001832 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001833 addEvent(EVENT_LIGHT_IDLE);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001834 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON_LIGHT);
1835 break;
1836 case LIGHT_STATE_IDLE:
1837 // We have been idling long enough, now it is time to do some work.
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001838 mActiveIdleOpCount = 1;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001839 mActiveIdleWakeLock.acquire();
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001840 mMaintenanceStartTime = SystemClock.elapsedRealtime();
1841 if (mCurIdleBudget < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
1842 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
1843 } else if (mCurIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) {
1844 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
1845 }
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001846 scheduleLightAlarmLocked(mCurIdleBudget);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001847 if (DEBUG) Slog.d(TAG,
1848 "Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE.");
1849 mLightState = LIGHT_STATE_IDLE_MAINTENANCE;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001850 EventLogTags.writeDeviceIdleLight(mLightState, reason);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08001851 addEvent(EVENT_LIGHT_MAINTENANCE);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001852 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
1853 break;
1854 }
1855 }
1856
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001857 void stepIdleStateLocked(String reason) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001858 if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001859 EventLogTags.writeDeviceIdleStep();
1860
1861 final long now = SystemClock.elapsedRealtime();
Adam Lesinski31c05d12015-06-09 17:34:04 -07001862 if ((now+mConstants.MIN_TIME_TO_ALARM) > mAlarmManager.getNextWakeFromIdleTime()) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001863 // Whoops, there is an upcoming alarm. We don't actually want to go idle.
1864 if (mState != STATE_ACTIVE) {
Dianne Hackbornb6683c42015-06-18 17:40:33 -07001865 becomeActiveLocked("alarm", Process.myUid());
Koji Fukui27b33302015-12-16 19:43:01 +09001866 becomeInactiveIfAppropriateLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001867 }
1868 return;
1869 }
1870
1871 switch (mState) {
1872 case STATE_INACTIVE:
1873 // We have now been inactive long enough, it is time to start looking
Nick Vaccaro20feaea2015-09-17 17:22:44 -07001874 // for motion and sleep some more while doing so.
1875 startMonitoringMotionLocked();
Adam Lesinski31c05d12015-06-09 17:34:04 -07001876 scheduleAlarmLocked(mConstants.IDLE_AFTER_INACTIVE_TIMEOUT, false);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001877 // Reset the upcoming idle delays.
Adam Lesinski31c05d12015-06-09 17:34:04 -07001878 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
1879 mNextIdleDelay = mConstants.IDLE_TIMEOUT;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001880 mState = STATE_IDLE_PENDING;
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001881 if (DEBUG) Slog.d(TAG, "Moved from STATE_INACTIVE to STATE_IDLE_PENDING.");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001882 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001883 break;
1884 case STATE_IDLE_PENDING:
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001885 mState = STATE_SENSING;
1886 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING.");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001887 EventLogTags.writeDeviceIdle(mState, reason);
Kevin Gabayan92f15e62016-04-04 17:52:22 -07001888 scheduleSensingTimeoutAlarmLocked(mConstants.SENSING_TIMEOUT);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001889 cancelLocatingLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001890 mNotMoving = false;
1891 mLocated = false;
1892 mLastGenericLocation = null;
1893 mLastGpsLocation = null;
Kevin Gabayan92f15e62016-04-04 17:52:22 -07001894 mAnyMotionDetector.checkForAnyMotion();
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001895 break;
1896 case STATE_SENSING:
Kevin Gabayan92f15e62016-04-04 17:52:22 -07001897 cancelSensingTimeoutAlarmLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001898 mState = STATE_LOCATING;
1899 if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING.");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001900 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001901 scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT, false);
Joe LaPenna23d681b2015-08-27 15:12:11 -07001902 if (mLocationManager != null
1903 && mLocationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
1904 mLocationManager.requestLocationUpdates(mLocationRequest,
1905 mGenericLocationListener, mHandler.getLooper());
1906 mLocating = true;
1907 } else {
1908 mHasNetworkLocation = false;
1909 }
1910 if (mLocationManager != null
1911 && mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
1912 mHasGps = true;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001913 mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5,
1914 mGpsLocationListener, mHandler.getLooper());
Joe LaPenna23d681b2015-08-27 15:12:11 -07001915 mLocating = true;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001916 } else {
Joe LaPenna23d681b2015-08-27 15:12:11 -07001917 mHasGps = false;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001918 }
Joe LaPenna23d681b2015-08-27 15:12:11 -07001919 // If we have a location provider, we're all set, the listeners will move state
1920 // forward.
1921 if (mLocating) {
1922 break;
1923 }
1924
1925 // Otherwise, we have to move from locating into idle maintenance.
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001926 case STATE_LOCATING:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001927 cancelAlarmLocked();
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07001928 cancelLocatingLocked();
1929 mAnyMotionDetector.stop();
Dianne Hackborn953fc942016-03-29 15:36:24 -07001930
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001931 case STATE_IDLE_MAINTENANCE:
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001932 scheduleAlarmLocked(mNextIdleDelay, true);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001933 if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay +
1934 " ms.");
Adam Lesinski31c05d12015-06-09 17:34:04 -07001935 mNextIdleDelay = (long)(mNextIdleDelay * mConstants.IDLE_FACTOR);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001936 if (DEBUG) Slog.d(TAG, "Setting mNextIdleDelay = " + mNextIdleDelay);
Adam Lesinski31c05d12015-06-09 17:34:04 -07001937 mNextIdleDelay = Math.min(mNextIdleDelay, mConstants.MAX_IDLE_TIMEOUT);
Dianne Hackborn953fc942016-03-29 15:36:24 -07001938 if (mNextIdleDelay < mConstants.IDLE_TIMEOUT) {
1939 mNextIdleDelay = mConstants.IDLE_TIMEOUT;
1940 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001941 mState = STATE_IDLE;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001942 if (mLightState != LIGHT_STATE_OVERRIDE) {
1943 mLightState = LIGHT_STATE_OVERRIDE;
1944 cancelLightAlarmLocked();
1945 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001946 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackbornb6843652016-02-22 12:20:13 -08001947 addEvent(EVENT_DEEP_IDLE);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001948 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON);
1949 break;
1950 case STATE_IDLE:
1951 // We have been idling long enough, now it is time to do some work.
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001952 mActiveIdleOpCount = 1;
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001953 mActiveIdleWakeLock.acquire();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001954 scheduleAlarmLocked(mNextIdlePendingDelay, false);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07001955 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE to STATE_IDLE_MAINTENANCE. " +
1956 "Next alarm in " + mNextIdlePendingDelay + " ms.");
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07001957 mMaintenanceStartTime = SystemClock.elapsedRealtime();
Adam Lesinski31c05d12015-06-09 17:34:04 -07001958 mNextIdlePendingDelay = Math.min(mConstants.MAX_IDLE_PENDING_TIMEOUT,
1959 (long)(mNextIdlePendingDelay * mConstants.IDLE_PENDING_FACTOR));
Dianne Hackborn953fc942016-03-29 15:36:24 -07001960 if (mNextIdlePendingDelay < mConstants.IDLE_PENDING_TIMEOUT) {
1961 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
1962 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001963 mState = STATE_IDLE_MAINTENANCE;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001964 EventLogTags.writeDeviceIdle(mState, reason);
Dianne Hackbornb6843652016-02-22 12:20:13 -08001965 addEvent(EVENT_DEEP_MAINTENANCE);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001966 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
1967 break;
1968 }
1969 }
1970
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001971 void incActiveIdleOps() {
1972 synchronized (this) {
1973 mActiveIdleOpCount++;
1974 }
1975 }
1976
1977 void decActiveIdleOps() {
1978 synchronized (this) {
1979 mActiveIdleOpCount--;
1980 if (mActiveIdleOpCount <= 0) {
1981 exitMaintenanceEarlyIfNeededLocked();
Dianne Hackborn945c9c92016-03-30 14:55:00 -07001982 mActiveIdleWakeLock.release();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001983 }
1984 }
1985 }
1986
1987 void downloadServiceActive(IBinder token) {
1988 synchronized (this) {
1989 mDownloadServiceActive = token;
Yao Chenca5edbb2016-01-13 14:44:36 -08001990 reportMaintenanceActivityIfNeededLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001991 try {
1992 token.linkToDeath(new IBinder.DeathRecipient() {
1993 @Override public void binderDied() {
1994 downloadServiceInactive();
1995 }
1996 }, 0);
1997 } catch (RemoteException e) {
1998 mDownloadServiceActive = null;
1999 }
2000 }
2001 }
2002
2003 void downloadServiceInactive() {
2004 synchronized (this) {
2005 mDownloadServiceActive = null;
Yao Chenca5edbb2016-01-13 14:44:36 -08002006 reportMaintenanceActivityIfNeededLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002007 exitMaintenanceEarlyIfNeededLocked();
2008 }
2009 }
2010
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002011 void setJobsActive(boolean active) {
2012 synchronized (this) {
2013 mJobsActive = active;
Yao Chenca5edbb2016-01-13 14:44:36 -08002014 reportMaintenanceActivityIfNeededLocked();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002015 if (!active) {
2016 exitMaintenanceEarlyIfNeededLocked();
2017 }
2018 }
2019 }
2020
2021 void setAlarmsActive(boolean active) {
2022 synchronized (this) {
2023 mAlarmsActive = active;
2024 if (!active) {
2025 exitMaintenanceEarlyIfNeededLocked();
2026 }
2027 }
2028 }
2029
Yao Chenca5edbb2016-01-13 14:44:36 -08002030 boolean registerMaintenanceActivityListener(IMaintenanceActivityListener listener) {
2031 synchronized (this) {
2032 mMaintenanceActivityListeners.register(listener);
2033 return mReportedMaintenanceActivity;
2034 }
2035 }
2036
2037 void unregisterMaintenanceActivityListener(IMaintenanceActivityListener listener) {
2038 synchronized (this) {
2039 mMaintenanceActivityListeners.unregister(listener);
2040 }
2041 }
2042
2043 void reportMaintenanceActivityIfNeededLocked() {
Amith Yamasanicb926fc2016-03-14 17:15:20 -07002044 boolean active = mJobsActive | (mDownloadServiceActive != null);
Yao Chenca5edbb2016-01-13 14:44:36 -08002045 if (active == mReportedMaintenanceActivity) {
2046 return;
2047 }
2048 mReportedMaintenanceActivity = active;
2049 Message msg = mHandler.obtainMessage(MSG_REPORT_MAINTENANCE_ACTIVITY,
2050 mReportedMaintenanceActivity ? 1 : 0, 0);
2051 mHandler.sendMessage(msg);
2052 }
2053
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002054 boolean isOpsInactiveLocked() {
2055 return mActiveIdleOpCount <= 0 && mDownloadServiceActive == null
2056 && !mJobsActive && !mAlarmsActive;
2057 }
2058
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002059 void exitMaintenanceEarlyIfNeededLocked() {
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002060 if (mState == STATE_IDLE_MAINTENANCE || mLightState == LIGHT_STATE_IDLE_MAINTENANCE
2061 || mLightState == LIGHT_STATE_PRE_IDLE) {
2062 if (isOpsInactiveLocked()) {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002063 final long now = SystemClock.elapsedRealtime();
2064 if (DEBUG) {
2065 StringBuilder sb = new StringBuilder();
2066 sb.append("Exit: start=");
2067 TimeUtils.formatDuration(mMaintenanceStartTime, sb);
2068 sb.append(" now=");
2069 TimeUtils.formatDuration(now, sb);
2070 Slog.d(TAG, sb.toString());
2071 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002072 if (mState == STATE_IDLE_MAINTENANCE) {
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002073 stepIdleStateLocked("s:early");
2074 } else if (mLightState == LIGHT_STATE_PRE_IDLE) {
2075 stepLightIdleStateLocked("s:predone");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002076 } else {
Dianne Hackborn945c9c92016-03-30 14:55:00 -07002077 stepLightIdleStateLocked("s:early");
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002078 }
2079 }
2080 }
2081 }
2082
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002083 void motionLocked() {
2084 if (DEBUG) Slog.d(TAG, "motionLocked()");
2085 // The motion sensor will have been disabled at this point
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002086 handleMotionDetectedLocked(mConstants.MOTION_INACTIVE_TIMEOUT, "motion");
2087 }
2088
2089 void handleMotionDetectedLocked(long timeout, String type) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002090 // The device is not yet active, so we want to go back to the pending idle
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002091 // state to wait again for no motion. Note that we only monitor for motion
2092 // after moving out of the inactive state, so no need to worry about that.
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002093 boolean becomeInactive = false;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002094 if (mState != STATE_ACTIVE) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002095 scheduleReportActiveLocked(type, Process.myUid());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002096 mState = STATE_ACTIVE;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002097 mInactiveTimeout = timeout;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002098 mCurIdleBudget = 0;
2099 mMaintenanceStartTime = 0;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002100 EventLogTags.writeDeviceIdle(mState, type);
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002101 addEvent(EVENT_NORMAL);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002102 becomeInactive = true;
2103 }
2104 if (mLightState == LIGHT_STATE_OVERRIDE) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08002105 // We went out of light idle mode because we had started deep idle mode... let's
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002106 // now go back and reset things so we resume light idling if appropriate.
2107 mLightState = STATE_ACTIVE;
2108 EventLogTags.writeDeviceIdleLight(mLightState, type);
2109 becomeInactive = true;
2110 }
2111 if (becomeInactive) {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002112 becomeInactiveIfAppropriateLocked();
2113 }
2114 }
2115
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002116 void receivedGenericLocationLocked(Location location) {
2117 if (mState != STATE_LOCATING) {
2118 cancelLocatingLocked();
2119 return;
2120 }
2121 if (DEBUG) Slog.d(TAG, "Generic location: " + location);
2122 mLastGenericLocation = new Location(location);
Joe LaPenna23d681b2015-08-27 15:12:11 -07002123 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHasGps) {
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002124 return;
2125 }
2126 mLocated = true;
2127 if (mNotMoving) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002128 stepIdleStateLocked("s:location");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002129 }
2130 }
2131
2132 void receivedGpsLocationLocked(Location location) {
2133 if (mState != STATE_LOCATING) {
2134 cancelLocatingLocked();
2135 return;
2136 }
2137 if (DEBUG) Slog.d(TAG, "GPS location: " + location);
2138 mLastGpsLocation = new Location(location);
2139 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY) {
2140 return;
2141 }
2142 mLocated = true;
2143 if (mNotMoving) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002144 stepIdleStateLocked("s:gps");
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002145 }
2146 }
2147
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002148 void startMonitoringMotionLocked() {
2149 if (DEBUG) Slog.d(TAG, "startMonitoringMotionLocked()");
2150 if (mMotionSensor != null && !mMotionListener.active) {
2151 mMotionListener.registerLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002152 }
2153 }
2154
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002155 void stopMonitoringMotionLocked() {
2156 if (DEBUG) Slog.d(TAG, "stopMonitoringMotionLocked()");
2157 if (mMotionSensor != null && mMotionListener.active) {
2158 mMotionListener.unregisterLocked();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002159 }
2160 }
2161
2162 void cancelAlarmLocked() {
2163 if (mNextAlarmTime != 0) {
2164 mNextAlarmTime = 0;
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002165 mAlarmManager.cancel(mDeepAlarmListener);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002166 }
2167 }
2168
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002169 void cancelLightAlarmLocked() {
2170 if (mNextLightAlarmTime != 0) {
2171 mNextLightAlarmTime = 0;
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002172 mAlarmManager.cancel(mLightAlarmListener);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002173 }
2174 }
2175
2176 void cancelLocatingLocked() {
2177 if (mLocating) {
2178 mLocationManager.removeUpdates(mGenericLocationListener);
2179 mLocationManager.removeUpdates(mGpsLocationListener);
2180 mLocating = false;
2181 }
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002182 }
2183
Kevin Gabayan92f15e62016-04-04 17:52:22 -07002184 void cancelSensingTimeoutAlarmLocked() {
2185 if (mNextSensingTimeoutAlarmTime != 0) {
2186 mNextSensingTimeoutAlarmTime = 0;
2187 mAlarmManager.cancel(mSensingTimeoutAlarmListener);
2188 }
2189 }
2190
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002191 void scheduleAlarmLocked(long delay, boolean idleUntil) {
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002192 if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")");
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002193 if (mMotionSensor == null) {
Joe LaPenna23d681b2015-08-27 15:12:11 -07002194 // If there is no motion sensor on this device, then we won't schedule
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002195 // alarms, because we can't determine if the device is not moving. This effectively
Joe LaPenna23d681b2015-08-27 15:12:11 -07002196 // turns off normal execution of device idling, although it is still possible to
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002197 // manually poke it by pretending like the alarm is going off.
2198 return;
2199 }
2200 mNextAlarmTime = SystemClock.elapsedRealtime() + delay;
2201 if (idleUntil) {
2202 mAlarmManager.setIdleUntil(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002203 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002204 } else {
2205 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002206 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002207 }
2208 }
2209
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002210 void scheduleLightAlarmLocked(long delay) {
2211 if (DEBUG) Slog.d(TAG, "scheduleLightAlarmLocked(" + delay + ")");
2212 if (mMotionSensor == null) {
2213 // If there is no motion sensor on this device, then we won't schedule
2214 // alarms, because we can't determine if the device is not moving. This effectively
2215 // turns off normal execution of device idling, although it is still possible to
2216 // manually poke it by pretending like the alarm is going off.
2217 return;
2218 }
2219 mNextLightAlarmTime = SystemClock.elapsedRealtime() + delay;
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002220 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002221 mNextLightAlarmTime, "DeviceIdleController.light", mLightAlarmListener, mHandler);
Kevin Gabayan89ecf822015-05-18 12:10:07 -07002222 }
2223
Kevin Gabayan92f15e62016-04-04 17:52:22 -07002224 void scheduleSensingTimeoutAlarmLocked(long delay) {
2225 if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")");
2226 mNextSensingTimeoutAlarmTime = SystemClock.elapsedRealtime() + delay;
2227 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextSensingTimeoutAlarmTime,
2228 "DeviceIdleController.sensing", mSensingTimeoutAlarmListener, mHandler);
2229 }
2230
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002231 private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps,
2232 ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds) {
2233 outAppIds.clear();
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002234 if (systemApps != null) {
2235 for (int i = 0; i < systemApps.size(); i++) {
2236 outAppIds.put(systemApps.valueAt(i), true);
2237 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002238 }
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002239 if (userApps != null) {
2240 for (int i = 0; i < userApps.size(); i++) {
2241 outAppIds.put(userApps.valueAt(i), true);
2242 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002243 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002244 int size = outAppIds.size();
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002245 int[] appids = new int[size];
2246 for (int i = 0; i < size; i++) {
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002247 appids[i] = outAppIds.keyAt(i);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002248 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002249 return appids;
2250 }
2251
2252 private void updateWhitelistAppIdsLocked() {
2253 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(mPowerSaveWhitelistAppsExceptIdle,
2254 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistExceptIdleAppIds);
2255 mPowerSaveWhitelistAllAppIdArray = buildAppIdArray(mPowerSaveWhitelistApps,
2256 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistAllAppIds);
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002257 mPowerSaveWhitelistUserAppIdArray = buildAppIdArray(null,
2258 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistUserAppIds);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002259 if (mLocalPowerManager != null) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002260 if (DEBUG) {
2261 Slog.d(TAG, "Setting wakelock whitelist to "
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002262 + Arrays.toString(mPowerSaveWhitelistAllAppIdArray));
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002263 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002264 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002265 }
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002266 if (mLocalAlarmManager != null) {
2267 if (DEBUG) {
2268 Slog.d(TAG, "Setting alarm whitelist to "
2269 + Arrays.toString(mPowerSaveWhitelistUserAppIdArray));
2270 }
2271 mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray);
2272 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002273 }
2274
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002275 private void updateTempWhitelistAppIdsLocked() {
2276 final int size = mTempWhitelistAppIdEndTimes.size();
2277 if (mTempWhitelistAppIdArray.length != size) {
2278 mTempWhitelistAppIdArray = new int[size];
2279 }
2280 for (int i = 0; i < size; i++) {
2281 mTempWhitelistAppIdArray[i] = mTempWhitelistAppIdEndTimes.keyAt(i);
2282 }
2283 if (mLocalPowerManager != null) {
2284 if (DEBUG) {
2285 Slog.d(TAG, "Setting wakelock temp whitelist to "
2286 + Arrays.toString(mTempWhitelistAppIdArray));
2287 }
2288 mLocalPowerManager.setDeviceIdleTempWhitelist(mTempWhitelistAppIdArray);
2289 }
2290 }
2291
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002292 private void reportPowerSaveWhitelistChangedLocked() {
2293 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
2294 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Xiaohui Chene4de5a02015-09-22 15:33:31 -07002295 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002296 }
2297
2298 private void reportTempWhitelistChangedLocked() {
2299 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED);
2300 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Xiaohui Chene4de5a02015-09-22 15:33:31 -07002301 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002302 }
2303
2304 void readConfigFileLocked() {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002305 if (DEBUG) Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002306 mPowerSaveWhitelistUserApps.clear();
2307 FileInputStream stream;
2308 try {
2309 stream = mConfigFile.openRead();
2310 } catch (FileNotFoundException e) {
2311 return;
2312 }
2313 try {
2314 XmlPullParser parser = Xml.newPullParser();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01002315 parser.setInput(stream, StandardCharsets.UTF_8.name());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002316 readConfigFileLocked(parser);
2317 } catch (XmlPullParserException e) {
2318 } finally {
2319 try {
2320 stream.close();
2321 } catch (IOException e) {
2322 }
2323 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002324 }
2325
2326 private void readConfigFileLocked(XmlPullParser parser) {
2327 final PackageManager pm = getContext().getPackageManager();
2328
2329 try {
2330 int type;
2331 while ((type = parser.next()) != XmlPullParser.START_TAG
2332 && type != XmlPullParser.END_DOCUMENT) {
2333 ;
2334 }
2335
2336 if (type != XmlPullParser.START_TAG) {
2337 throw new IllegalStateException("no start tag found");
2338 }
2339
2340 int outerDepth = parser.getDepth();
2341 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2342 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2343 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2344 continue;
2345 }
2346
2347 String tagName = parser.getName();
2348 if (tagName.equals("wl")) {
2349 String name = parser.getAttributeValue(null, "n");
2350 if (name != null) {
2351 try {
Dianne Hackborn1b79ad72015-10-12 10:59:47 -07002352 ApplicationInfo ai = pm.getApplicationInfo(name,
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07002353 PackageManager.MATCH_UNINSTALLED_PACKAGES);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002354 mPowerSaveWhitelistUserApps.put(ai.packageName,
2355 UserHandle.getAppId(ai.uid));
2356 } catch (PackageManager.NameNotFoundException e) {
2357 }
2358 }
2359 } else {
2360 Slog.w(TAG, "Unknown element under <config>: "
2361 + parser.getName());
2362 XmlUtils.skipCurrentTag(parser);
2363 }
2364 }
2365
2366 } catch (IllegalStateException e) {
2367 Slog.w(TAG, "Failed parsing config " + e);
2368 } catch (NullPointerException e) {
2369 Slog.w(TAG, "Failed parsing config " + e);
2370 } catch (NumberFormatException e) {
2371 Slog.w(TAG, "Failed parsing config " + e);
2372 } catch (XmlPullParserException e) {
2373 Slog.w(TAG, "Failed parsing config " + e);
2374 } catch (IOException e) {
2375 Slog.w(TAG, "Failed parsing config " + e);
2376 } catch (IndexOutOfBoundsException e) {
2377 Slog.w(TAG, "Failed parsing config " + e);
2378 }
2379 }
2380
2381 void writeConfigFileLocked() {
2382 mHandler.removeMessages(MSG_WRITE_CONFIG);
2383 mHandler.sendEmptyMessageDelayed(MSG_WRITE_CONFIG, 5000);
2384 }
2385
2386 void handleWriteConfigFile() {
2387 final ByteArrayOutputStream memStream = new ByteArrayOutputStream();
2388
2389 try {
2390 synchronized (this) {
2391 XmlSerializer out = new FastXmlSerializer();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01002392 out.setOutput(memStream, StandardCharsets.UTF_8.name());
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002393 writeConfigFileLocked(out);
2394 }
2395 } catch (IOException e) {
2396 }
2397
2398 synchronized (mConfigFile) {
2399 FileOutputStream stream = null;
2400 try {
2401 stream = mConfigFile.startWrite();
2402 memStream.writeTo(stream);
2403 stream.flush();
2404 FileUtils.sync(stream);
2405 stream.close();
2406 mConfigFile.finishWrite(stream);
2407 } catch (IOException e) {
2408 Slog.w(TAG, "Error writing config file", e);
2409 mConfigFile.failWrite(stream);
2410 }
2411 }
2412 }
2413
2414 void writeConfigFileLocked(XmlSerializer out) throws IOException {
2415 out.startDocument(null, true);
2416 out.startTag(null, "config");
2417 for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) {
2418 String name = mPowerSaveWhitelistUserApps.keyAt(i);
2419 out.startTag(null, "wl");
2420 out.attribute(null, "n", name);
2421 out.endTag(null, "wl");
2422 }
2423 out.endTag(null, "config");
2424 out.endDocument();
2425 }
2426
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002427 static void dumpHelp(PrintWriter pw) {
2428 pw.println("Device idle controller (deviceidle) commands:");
2429 pw.println(" help");
2430 pw.println(" Print this help text.");
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002431 pw.println(" step [light|deep]");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002432 pw.println(" Immediately step to next state, without waiting for alarm.");
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002433 pw.println(" force-idle");
2434 pw.println(" Force directly into idle mode, regardless of other device state.");
2435 pw.println(" Use \"step\" to get out.");
Dianne Hackbornb6843652016-02-22 12:20:13 -08002436 pw.println(" disable [light|deep|all]");
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002437 pw.println(" Completely disable device idle mode.");
Dianne Hackbornb6843652016-02-22 12:20:13 -08002438 pw.println(" enable [light|deep|all]");
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002439 pw.println(" Re-enable device idle mode after it had previously been disabled.");
Dianne Hackbornb6843652016-02-22 12:20:13 -08002440 pw.println(" enabled [light|deep|all]");
Dianne Hackborn92617032015-06-19 15:32:19 -07002441 pw.println(" Print 1 if device idle mode is currently enabled, else 0.");
Dianne Hackborn1b139682015-07-06 15:13:37 -07002442 pw.println(" whitelist");
2443 pw.println(" Print currently whitelisted apps.");
Dianne Hackborn92617032015-06-19 15:32:19 -07002444 pw.println(" whitelist [package ...]");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002445 pw.println(" Add (prefix with +) or remove (prefix with -) packages.");
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002446 pw.println(" tempwhitelist [-u] [package ..]");
Dianne Hackborn92617032015-06-19 15:32:19 -07002447 pw.println(" Temporarily place packages in whitelist for 10 seconds.");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002448 }
2449
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002450 class Shell extends ShellCommand {
2451 int userId = UserHandle.USER_SYSTEM;
2452
2453 @Override
2454 public int onCommand(String cmd) {
2455 return onShellCommand(this, cmd);
2456 }
2457
2458 @Override
2459 public void onHelp() {
2460 PrintWriter pw = getOutPrintWriter();
2461 dumpHelp(pw);
2462 }
2463 }
2464
2465 int onShellCommand(Shell shell, String cmd) {
2466 PrintWriter pw = shell.getOutPrintWriter();
2467 if ("step".equals(cmd)) {
2468 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
2469 null);
2470 synchronized (this) {
2471 long token = Binder.clearCallingIdentity();
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002472 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002473 try {
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07002474 if (arg == null || "deep".equals(arg)) {
2475 exitForceIdleLocked();
2476 stepIdleStateLocked("s:shell");
2477 pw.print("Stepped to deep: ");
2478 pw.println(stateToString(mState));
2479 } else if ("light".equals(arg)) {
2480 exitForceIdleLocked();
2481 stepLightIdleStateLocked("s:shell");
2482 pw.print("Stepped to light: "); pw.println(lightStateToString(mLightState));
2483 } else {
2484 pw.println("Unknown idle mode: " + arg);
2485 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002486 } finally {
2487 Binder.restoreCallingIdentity(token);
2488 }
2489 }
2490 } else if ("force-idle".equals(cmd)) {
2491 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
2492 null);
2493 synchronized (this) {
2494 long token = Binder.clearCallingIdentity();
2495 try {
Dianne Hackbornb6843652016-02-22 12:20:13 -08002496 if (!mDeepEnabled) {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002497 pw.println("Unable to go idle; not enabled");
2498 return -1;
2499 }
2500 mForceIdle = true;
2501 becomeInactiveIfAppropriateLocked();
2502 int curState = mState;
2503 while (curState != STATE_IDLE) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002504 stepIdleStateLocked("s:shell");
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002505 if (curState == mState) {
2506 pw.print("Unable to go idle; stopped at ");
2507 pw.println(stateToString(mState));
2508 exitForceIdleLocked();
2509 return -1;
2510 }
2511 curState = mState;
2512 }
2513 pw.println("Now forced in to idle mode");
2514 } finally {
2515 Binder.restoreCallingIdentity(token);
2516 }
2517 }
2518 } else if ("disable".equals(cmd)) {
2519 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
2520 null);
2521 synchronized (this) {
2522 long token = Binder.clearCallingIdentity();
Dianne Hackbornb6843652016-02-22 12:20:13 -08002523 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002524 try {
Dianne Hackbornb6843652016-02-22 12:20:13 -08002525 boolean becomeActive = false;
2526 boolean valid = false;
2527 if (arg == null || "deep".equals(arg) || "all".equals(arg)) {
2528 valid = true;
2529 if (mDeepEnabled) {
2530 mDeepEnabled = false;
2531 becomeActive = true;
2532 pw.println("Deep idle mode disabled");
2533 }
2534 }
2535 if (arg == null || "light".equals(arg) || "all".equals(arg)) {
2536 valid = true;
2537 if (mLightEnabled) {
2538 mLightEnabled = false;
2539 becomeActive = true;
2540 pw.println("Light idle mode disabled");
2541 }
2542 }
2543 if (becomeActive) {
2544 becomeActiveLocked((arg == null ? "all" : arg) + "-disabled",
2545 Process.myUid());
2546 }
2547 if (!valid) {
2548 pw.println("Unknown idle mode: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002549 }
2550 } finally {
2551 Binder.restoreCallingIdentity(token);
2552 }
2553 }
2554 } else if ("enable".equals(cmd)) {
2555 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
2556 null);
2557 synchronized (this) {
2558 long token = Binder.clearCallingIdentity();
Dianne Hackbornb6843652016-02-22 12:20:13 -08002559 String arg = shell.getNextArg();
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002560 try {
Dianne Hackbornb6843652016-02-22 12:20:13 -08002561 boolean becomeInactive = false;
2562 boolean valid = false;
2563 if (arg == null || "deep".equals(arg) || "all".equals(arg)) {
2564 valid = true;
2565 if (!mDeepEnabled) {
2566 mDeepEnabled = true;
2567 becomeInactive = true;
2568 pw.println("Deep idle mode enabled");
2569 }
2570 }
2571 if (arg == null || "light".equals(arg) || "all".equals(arg)) {
2572 valid = true;
2573 if (!mLightEnabled) {
2574 mLightEnabled = true;
2575 becomeInactive = true;
2576 pw.println("Light idle mode enable");
2577 }
2578 }
2579 if (becomeInactive) {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002580 becomeInactiveIfAppropriateLocked();
Dianne Hackbornb6843652016-02-22 12:20:13 -08002581 }
2582 if (!valid) {
2583 pw.println("Unknown idle mode: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002584 }
2585 } finally {
2586 Binder.restoreCallingIdentity(token);
2587 }
2588 }
2589 } else if ("enabled".equals(cmd)) {
2590 synchronized (this) {
Dianne Hackbornb6843652016-02-22 12:20:13 -08002591 String arg = shell.getNextArg();
2592 if (arg == null || "all".equals(arg)) {
2593 pw.println(mDeepEnabled && mLightEnabled ? "1" : 0);
2594 } else if ("deep".equals(arg)) {
2595 pw.println(mDeepEnabled ? "1" : 0);
2596 } else if ("light".equals(arg)) {
2597 pw.println(mLightEnabled ? "1" : 0);
2598 } else {
2599 pw.println("Unknown idle mode: " + arg);
2600 }
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002601 }
2602 } else if ("whitelist".equals(cmd)) {
2603 long token = Binder.clearCallingIdentity();
2604 try {
2605 String arg = shell.getNextArg();
2606 if (arg != null) {
2607 getContext().enforceCallingOrSelfPermission(
2608 android.Manifest.permission.DEVICE_POWER, null);
2609 do {
2610 if (arg.length() < 1 || (arg.charAt(0) != '-'
Felipe Lemef8a46232016-02-10 13:51:54 -08002611 && arg.charAt(0) != '+' && arg.charAt(0) != '=')) {
2612 pw.println("Package must be prefixed with +, -, or =: " + arg);
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002613 return -1;
2614 }
2615 char op = arg.charAt(0);
2616 String pkg = arg.substring(1);
2617 if (op == '+') {
2618 if (addPowerSaveWhitelistAppInternal(pkg)) {
2619 pw.println("Added: " + pkg);
2620 } else {
2621 pw.println("Unknown package: " + pkg);
2622 }
Felipe Lemef8a46232016-02-10 13:51:54 -08002623 } else if (op == '-') {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002624 if (removePowerSaveWhitelistAppInternal(pkg)) {
2625 pw.println("Removed: " + pkg);
2626 }
Felipe Lemef8a46232016-02-10 13:51:54 -08002627 } else {
2628 pw.println(getPowerSaveWhitelistAppInternal(pkg));
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002629 }
2630 } while ((arg=shell.getNextArg()) != null);
2631 } else {
2632 synchronized (this) {
2633 for (int j=0; j<mPowerSaveWhitelistAppsExceptIdle.size(); j++) {
2634 pw.print("system-excidle,");
2635 pw.print(mPowerSaveWhitelistAppsExceptIdle.keyAt(j));
2636 pw.print(",");
2637 pw.println(mPowerSaveWhitelistAppsExceptIdle.valueAt(j));
2638 }
2639 for (int j=0; j<mPowerSaveWhitelistApps.size(); j++) {
2640 pw.print("system,");
2641 pw.print(mPowerSaveWhitelistApps.keyAt(j));
2642 pw.print(",");
2643 pw.println(mPowerSaveWhitelistApps.valueAt(j));
2644 }
2645 for (int j=0; j<mPowerSaveWhitelistUserApps.size(); j++) {
2646 pw.print("user,");
2647 pw.print(mPowerSaveWhitelistUserApps.keyAt(j));
2648 pw.print(",");
2649 pw.println(mPowerSaveWhitelistUserApps.valueAt(j));
2650 }
2651 }
2652 }
2653 } finally {
2654 Binder.restoreCallingIdentity(token);
2655 }
2656 } else if ("tempwhitelist".equals(cmd)) {
2657 String opt;
2658 while ((opt=shell.getNextOption()) != null) {
2659 if ("-u".equals(opt)) {
2660 opt = shell.getNextArg();
2661 if (opt == null) {
2662 pw.println("-u requires a user number");
2663 return -1;
2664 }
2665 shell.userId = Integer.parseInt(opt);
2666 }
2667 }
2668 String arg = shell.getNextArg();
2669 if (arg != null) {
2670 try {
2671 addPowerSaveTempWhitelistAppChecked(arg, 10000L, shell.userId, "shell");
2672 } catch (RemoteException re) {
2673 pw.println("Failed: " + re);
2674 }
2675 } else {
2676 pw.println("At least one package name must be specified");
2677 return -1;
2678 }
2679 } else {
2680 return shell.handleDefaultCommands(cmd);
2681 }
2682 return 0;
2683 }
2684
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002685 void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2686 if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
2687 != PackageManager.PERMISSION_GRANTED) {
2688 pw.println("Permission Denial: can't dump DeviceIdleController from from pid="
2689 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2690 + " without permission " + android.Manifest.permission.DUMP);
2691 return;
2692 }
2693
2694 if (args != null) {
Xiaohui Chen7c696362015-09-16 09:56:14 -07002695 int userId = UserHandle.USER_SYSTEM;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002696 for (int i=0; i<args.length; i++) {
2697 String arg = args[i];
2698 if ("-h".equals(arg)) {
2699 dumpHelp(pw);
2700 return;
Amith Yamasaniaf575b92015-05-29 15:35:26 -07002701 } else if ("-u".equals(arg)) {
2702 i++;
2703 if (i < args.length) {
2704 arg = args[i];
2705 userId = Integer.parseInt(arg);
2706 }
Dianne Hackborn8d66b3f2015-05-08 17:21:48 -07002707 } else if ("-a".equals(arg)) {
2708 // Ignore, we always dump all.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002709 } else if (arg.length() > 0 && arg.charAt(0) == '-'){
2710 pw.println("Unknown option: " + arg);
2711 return;
2712 } else {
Dianne Hackborn9461b6f2015-10-07 17:33:16 -07002713 Shell shell = new Shell();
2714 shell.userId = userId;
2715 String[] newArgs = new String[args.length-i];
2716 System.arraycopy(args, i, newArgs, 0, args.length-i);
2717 shell.exec(mBinderService, null, fd, null, newArgs, new ResultReceiver(null));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002718 return;
2719 }
2720 }
2721 }
2722
2723 synchronized (this) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002724 mConstants.dump(pw);
2725
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002726 if (mEventCmds[0] != EVENT_NULL) {
2727 pw.println(" Idling history:");
2728 long now = SystemClock.elapsedRealtime();
2729 for (int i=EVENT_BUFFER_SIZE-1; i>=0; i--) {
2730 int cmd = mEventCmds[i];
2731 if (cmd == EVENT_NULL) {
2732 continue;
2733 }
2734 String label;
2735 switch (mEventCmds[i]) {
2736 case EVENT_NORMAL: label = " normal"; break;
2737 case EVENT_LIGHT_IDLE: label = " light-idle"; break;
2738 case EVENT_LIGHT_MAINTENANCE: label = "light-maint"; break;
Dianne Hackbornb6843652016-02-22 12:20:13 -08002739 case EVENT_DEEP_IDLE: label = " deep-idle"; break;
2740 case EVENT_DEEP_MAINTENANCE: label = " deep-maint"; break;
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002741 default: label = " ??"; break;
2742 }
2743 pw.print(" ");
2744 pw.print(label);
2745 pw.print(": ");
2746 TimeUtils.formatDuration(mEventTimes[i], now, pw);;
2747 pw.println();
2748 }
2749 }
2750
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002751 int size = mPowerSaveWhitelistAppsExceptIdle.size();
2752 if (size > 0) {
2753 pw.println(" Whitelist (except idle) system apps:");
2754 for (int i = 0; i < size; i++) {
2755 pw.print(" ");
2756 pw.println(mPowerSaveWhitelistAppsExceptIdle.keyAt(i));
2757 }
2758 }
2759 size = mPowerSaveWhitelistApps.size();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002760 if (size > 0) {
2761 pw.println(" Whitelist system apps:");
2762 for (int i = 0; i < size; i++) {
2763 pw.print(" ");
2764 pw.println(mPowerSaveWhitelistApps.keyAt(i));
2765 }
2766 }
2767 size = mPowerSaveWhitelistUserApps.size();
2768 if (size > 0) {
2769 pw.println(" Whitelist user apps:");
2770 for (int i = 0; i < size; i++) {
2771 pw.print(" ");
2772 pw.println(mPowerSaveWhitelistUserApps.keyAt(i));
2773 }
2774 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002775 size = mPowerSaveWhitelistExceptIdleAppIds.size();
2776 if (size > 0) {
2777 pw.println(" Whitelist (except idle) all app ids:");
2778 for (int i = 0; i < size; i++) {
2779 pw.print(" ");
2780 pw.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
2781 pw.println();
2782 }
2783 }
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08002784 size = mPowerSaveWhitelistUserAppIds.size();
2785 if (size > 0) {
2786 pw.println(" Whitelist user app ids:");
2787 for (int i = 0; i < size; i++) {
2788 pw.print(" ");
2789 pw.print(mPowerSaveWhitelistUserAppIds.keyAt(i));
2790 pw.println();
2791 }
2792 }
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002793 size = mPowerSaveWhitelistAllAppIds.size();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002794 if (size > 0) {
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002795 pw.println(" Whitelist all app ids:");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002796 for (int i = 0; i < size; i++) {
Dianne Hackborna750a632015-06-16 17:18:23 -07002797 pw.print(" ");
Dianne Hackborn3b16cf42015-07-01 15:05:04 -07002798 pw.print(mPowerSaveWhitelistAllAppIds.keyAt(i));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002799 pw.println();
2800 }
2801 }
Dianne Hackborna750a632015-06-16 17:18:23 -07002802 size = mTempWhitelistAppIdEndTimes.size();
2803 if (size > 0) {
2804 pw.println(" Temp whitelist schedule:");
2805 final long timeNow = SystemClock.elapsedRealtime();
2806 for (int i = 0; i < size; i++) {
2807 pw.print(" UID=");
2808 pw.print(mTempWhitelistAppIdEndTimes.keyAt(i));
2809 pw.print(": ");
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07002810 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.valueAt(i);
2811 TimeUtils.formatDuration(entry.first.value, timeNow, pw);
2812 pw.print(" - ");
2813 pw.println(entry.second);
Dianne Hackborna750a632015-06-16 17:18:23 -07002814 }
2815 }
2816 size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0;
2817 if (size > 0) {
2818 pw.println(" Temp whitelist app ids:");
2819 for (int i = 0; i < size; i++) {
2820 pw.print(" ");
2821 pw.print(mTempWhitelistAppIdArray[i]);
2822 pw.println();
2823 }
2824 }
Adam Lesinski31c05d12015-06-09 17:34:04 -07002825
Dianne Hackbornb6843652016-02-22 12:20:13 -08002826 pw.print(" mLightEnabled="); pw.print(mLightEnabled);
2827 pw.print(" mDeepEnabled="); pw.println(mDeepEnabled);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07002828 pw.print(" mForceIdle="); pw.println(mForceIdle);
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002829 pw.print(" mMotionSensor="); pw.println(mMotionSensor);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002830 pw.print(" mCurDisplay="); pw.println(mCurDisplay);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002831 pw.print(" mScreenOn="); pw.println(mScreenOn);
2832 pw.print(" mCharging="); pw.println(mCharging);
Nick Vaccaro20feaea2015-09-17 17:22:44 -07002833 pw.print(" mMotionActive="); pw.println(mMotionListener.active);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002834 pw.print(" mNotMoving="); pw.println(mNotMoving);
Joe LaPenna23d681b2015-08-27 15:12:11 -07002835 pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHasGps=");
2836 pw.print(mHasGps); pw.print(" mHasNetwork=");
2837 pw.print(mHasNetworkLocation); pw.print(" mLocated="); pw.println(mLocated);
Dianne Hackborn42df4fb2015-08-14 16:43:14 -07002838 if (mLastGenericLocation != null) {
2839 pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation);
2840 }
2841 if (mLastGpsLocation != null) {
2842 pw.print(" mLastGpsLocation="); pw.println(mLastGpsLocation);
2843 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002844 pw.print(" mState="); pw.print(stateToString(mState));
2845 pw.print(" mLightState=");
2846 pw.println(lightStateToString(mLightState));
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002847 pw.print(" mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw);
2848 pw.println();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002849 if (mActiveIdleOpCount != 0) {
2850 pw.print(" mActiveIdleOpCount="); pw.println(mActiveIdleOpCount);
2851 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002852 if (mNextAlarmTime != 0) {
2853 pw.print(" mNextAlarmTime=");
2854 TimeUtils.formatDuration(mNextAlarmTime, SystemClock.elapsedRealtime(), pw);
2855 pw.println();
2856 }
2857 if (mNextIdlePendingDelay != 0) {
2858 pw.print(" mNextIdlePendingDelay=");
2859 TimeUtils.formatDuration(mNextIdlePendingDelay, pw);
2860 pw.println();
2861 }
2862 if (mNextIdleDelay != 0) {
2863 pw.print(" mNextIdleDelay=");
2864 TimeUtils.formatDuration(mNextIdleDelay, pw);
2865 pw.println();
2866 }
Dianne Hackborn953fc942016-03-29 15:36:24 -07002867 if (mNextLightIdleDelay != 0) {
2868 pw.print(" mNextIdleDelay=");
2869 TimeUtils.formatDuration(mNextLightIdleDelay, pw);
2870 pw.println();
2871 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07002872 if (mNextLightAlarmTime != 0) {
2873 pw.print(" mNextLightAlarmTime=");
2874 TimeUtils.formatDuration(mNextLightAlarmTime, SystemClock.elapsedRealtime(), pw);
2875 pw.println();
2876 }
Dianne Hackborn8ed2b972015-11-18 14:52:04 -08002877 if (mCurIdleBudget != 0) {
2878 pw.print(" mCurIdleBudget=");
2879 TimeUtils.formatDuration(mCurIdleBudget, pw);
2880 pw.println();
2881 }
2882 if (mMaintenanceStartTime != 0) {
2883 pw.print(" mMaintenanceStartTime=");
2884 TimeUtils.formatDuration(mMaintenanceStartTime, SystemClock.elapsedRealtime(), pw);
2885 pw.println();
2886 }
Dianne Hackborn627dfa12015-11-11 18:10:30 -08002887 if (mJobsActive) {
2888 pw.print(" mJobsActive="); pw.println(mJobsActive);
2889 }
2890 if (mAlarmsActive) {
2891 pw.print(" mAlarmsActive="); pw.println(mAlarmsActive);
2892 }
2893 if (mDownloadServiceActive != null) {
2894 pw.print(" mDownloadServiceActive="); pw.println(mDownloadServiceActive);
2895 }
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07002896 }
2897 }
2898}