1 /* 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 17 package com.android.server; 18 19 import android.Manifest; 20 import android.app.ActivityManager; 21 import android.app.ActivityManagerInternal; 22 import android.app.AlarmManager; 23 import android.content.BroadcastReceiver; 24 import android.content.ContentResolver; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.content.IntentFilter; 28 import android.content.pm.ApplicationInfo; 29 import android.content.pm.PackageManager; 30 import android.content.pm.PackageManager.NameNotFoundException; 31 import android.database.ContentObserver; 32 import android.hardware.Sensor; 33 import android.hardware.SensorEvent; 34 import android.hardware.SensorEventListener; 35 import android.hardware.SensorManager; 36 import android.hardware.TriggerEvent; 37 import android.hardware.TriggerEventListener; 38 import android.location.Location; 39 import android.location.LocationListener; 40 import android.location.LocationManager; 41 import android.location.LocationRequest; 42 import android.net.ConnectivityManager; 43 import android.net.INetworkPolicyManager; 44 import android.net.NetworkInfo; 45 import android.net.Uri; 46 import android.os.BatteryManager; 47 import android.os.BatteryStats; 48 import android.os.Binder; 49 import android.os.Bundle; 50 import android.os.Environment; 51 import android.os.FileUtils; 52 import android.os.Handler; 53 import android.os.IDeviceIdleController; 54 import android.os.IMaintenanceActivityListener; 55 import android.os.Looper; 56 import android.os.Message; 57 import android.os.PowerManager; 58 import android.os.PowerManager.ServiceType; 59 import android.os.PowerManagerInternal; 60 import android.os.Process; 61 import android.os.RemoteCallbackList; 62 import android.os.RemoteException; 63 import android.os.ResultReceiver; 64 import android.os.ServiceManager; 65 import android.os.ShellCallback; 66 import android.os.ShellCommand; 67 import android.os.SystemClock; 68 import android.os.UserHandle; 69 import android.provider.Settings; 70 import android.util.ArrayMap; 71 import android.util.ArraySet; 72 import android.util.KeyValueListParser; 73 import android.util.MutableLong; 74 import android.util.Pair; 75 import android.util.Slog; 76 import android.util.SparseArray; 77 import android.util.SparseBooleanArray; 78 import android.util.TimeUtils; 79 import android.util.Xml; 80 81 import com.android.internal.annotations.GuardedBy; 82 import com.android.internal.annotations.VisibleForTesting; 83 import com.android.internal.app.IBatteryStats; 84 import com.android.internal.os.AtomicFile; 85 import com.android.internal.os.BackgroundThread; 86 import com.android.internal.util.DumpUtils; 87 import com.android.internal.util.FastXmlSerializer; 88 import com.android.internal.util.XmlUtils; 89 import com.android.server.am.BatteryStatsService; 90 import com.android.server.deviceidle.ConstraintController; 91 import com.android.server.deviceidle.DeviceIdleConstraintTracker; 92 import com.android.server.deviceidle.IDeviceIdleConstraint; 93 import com.android.server.deviceidle.TvConstraintController; 94 import com.android.server.net.NetworkPolicyManagerInternal; 95 import com.android.server.wm.ActivityTaskManagerInternal; 96 97 import org.xmlpull.v1.XmlPullParser; 98 import org.xmlpull.v1.XmlPullParserException; 99 import org.xmlpull.v1.XmlSerializer; 100 101 import java.io.ByteArrayOutputStream; 102 import java.io.File; 103 import java.io.FileDescriptor; 104 import java.io.FileInputStream; 105 import java.io.FileNotFoundException; 106 import java.io.FileOutputStream; 107 import java.io.IOException; 108 import java.io.PrintWriter; 109 import java.nio.charset.StandardCharsets; 110 import java.util.Arrays; 111 import java.util.stream.Collectors; 112 113 /** 114 * Keeps track of device idleness and drives low power mode based on that. 115 * 116 * Test: atest com.android.server.DeviceIdleControllerTest 117 * 118 * Current idling state machine (as of Android Q). This can be visualized using Graphviz: 119 <pre> 120 121 digraph { 122 subgraph deep { 123 label="deep"; 124 125 STATE_ACTIVE [label="STATE_ACTIVE\nScreen on OR Charging OR Alarm going off soon"] 126 STATE_INACTIVE [label="STATE_INACTIVE\nScreen off AND Not charging"] 127 STATE_QUICK_DOZE_DELAY [ 128 label="STATE_QUICK_DOZE_DELAY\n" 129 + "Screen off AND Not charging\n" 130 + "Location, motion detection, and significant motion monitoring turned off" 131 ] 132 STATE_IDLE_PENDING [ 133 label="STATE_IDLE_PENDING\nSignificant motion monitoring turned on" 134 ] 135 STATE_SENSING [label="STATE_SENSING\nMonitoring for ANY motion"] 136 STATE_LOCATING [ 137 label="STATE_LOCATING\nRequesting location, motion monitoring still on" 138 ] 139 STATE_IDLE [ 140 label="STATE_IDLE\nLocation and motion detection turned off\n" 141 + "Significant motion monitoring state unchanged" 142 ] 143 STATE_IDLE_MAINTENANCE [label="STATE_IDLE_MAINTENANCE\n"] 144 145 STATE_ACTIVE -> STATE_INACTIVE [ 146 label="becomeInactiveIfAppropriateLocked() AND Quick Doze not enabled" 147 ] 148 STATE_ACTIVE -> STATE_QUICK_DOZE_DELAY [ 149 label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled" 150 ] 151 152 STATE_INACTIVE -> STATE_ACTIVE [ 153 label="handleMotionDetectedLocked(), becomeActiveLocked()" 154 ] 155 STATE_INACTIVE -> STATE_IDLE_PENDING [label="stepIdleStateLocked()"] 156 STATE_INACTIVE -> STATE_QUICK_DOZE_DELAY [ 157 label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled" 158 ] 159 160 STATE_IDLE_PENDING -> STATE_ACTIVE [ 161 label="handleMotionDetectedLocked(), becomeActiveLocked()" 162 ] 163 STATE_IDLE_PENDING -> STATE_SENSING [label="stepIdleStateLocked()"] 164 STATE_IDLE_PENDING -> STATE_QUICK_DOZE_DELAY [ 165 label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled" 166 ] 167 168 STATE_SENSING -> STATE_ACTIVE [ 169 label="handleMotionDetectedLocked(), becomeActiveLocked()" 170 ] 171 STATE_SENSING -> STATE_LOCATING [label="stepIdleStateLocked()"] 172 STATE_SENSING -> STATE_QUICK_DOZE_DELAY [ 173 label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled" 174 ] 175 STATE_SENSING -> STATE_IDLE [ 176 label="stepIdleStateLocked()\n" 177 + "No Location Manager OR (no Network provider AND no GPS provider)" 178 ] 179 180 STATE_LOCATING -> STATE_ACTIVE [ 181 label="handleMotionDetectedLocked(), becomeActiveLocked()" 182 ] 183 STATE_LOCATING -> STATE_QUICK_DOZE_DELAY [ 184 label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled" 185 ] 186 STATE_LOCATING -> STATE_IDLE [label="stepIdleStateLocked()"] 187 188 STATE_QUICK_DOZE_DELAY -> STATE_ACTIVE [ 189 label="handleMotionDetectedLocked(), becomeActiveLocked()" 190 ] 191 STATE_QUICK_DOZE_DELAY -> STATE_IDLE [label="stepIdleStateLocked()"] 192 193 STATE_IDLE -> STATE_ACTIVE [label="handleMotionDetectedLocked(), becomeActiveLocked()"] 194 STATE_IDLE -> STATE_IDLE_MAINTENANCE [label="stepIdleStateLocked()"] 195 196 STATE_IDLE_MAINTENANCE -> STATE_ACTIVE [ 197 label="handleMotionDetectedLocked(), becomeActiveLocked()" 198 ] 199 STATE_IDLE_MAINTENANCE -> STATE_IDLE [ 200 label="stepIdleStateLocked(), exitMaintenanceEarlyIfNeededLocked()" 201 ] 202 } 203 204 subgraph light { 205 label="light" 206 207 LIGHT_STATE_ACTIVE [ 208 label="LIGHT_STATE_ACTIVE\nScreen on OR Charging OR Alarm going off soon" 209 ] 210 LIGHT_STATE_INACTIVE [label="LIGHT_STATE_INACTIVE\nScreen off AND Not charging"] 211 LIGHT_STATE_PRE_IDLE [ 212 label="LIGHT_STATE_PRE_IDLE\n" 213 + "Delay going into LIGHT_STATE_IDLE due to some running jobs or alarms" 214 ] 215 LIGHT_STATE_IDLE [label="LIGHT_STATE_IDLE\n"] 216 LIGHT_STATE_WAITING_FOR_NETWORK [ 217 label="LIGHT_STATE_WAITING_FOR_NETWORK\n" 218 + "Coming out of LIGHT_STATE_IDLE, waiting for network" 219 ] 220 LIGHT_STATE_IDLE_MAINTENANCE [label="LIGHT_STATE_IDLE_MAINTENANCE\n"] 221 LIGHT_STATE_OVERRIDE [ 222 label="LIGHT_STATE_OVERRIDE\nDevice in deep doze, light no longer changing states" 223 ] 224 225 LIGHT_STATE_ACTIVE -> LIGHT_STATE_INACTIVE [ 226 label="becomeInactiveIfAppropriateLocked()" 227 ] 228 LIGHT_STATE_ACTIVE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"] 229 230 LIGHT_STATE_INACTIVE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"] 231 LIGHT_STATE_INACTIVE -> LIGHT_STATE_PRE_IDLE [label="active jobs"] 232 LIGHT_STATE_INACTIVE -> LIGHT_STATE_IDLE [label="no active jobs"] 233 LIGHT_STATE_INACTIVE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"] 234 235 LIGHT_STATE_PRE_IDLE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"] 236 LIGHT_STATE_PRE_IDLE -> LIGHT_STATE_IDLE [ 237 label="stepLightIdleStateLocked(), exitMaintenanceEarlyIfNeededLocked()" 238 ] 239 LIGHT_STATE_PRE_IDLE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"] 240 241 LIGHT_STATE_IDLE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"] 242 LIGHT_STATE_IDLE -> LIGHT_STATE_WAITING_FOR_NETWORK [label="no network"] 243 LIGHT_STATE_IDLE -> LIGHT_STATE_IDLE_MAINTENANCE 244 LIGHT_STATE_IDLE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"] 245 246 LIGHT_STATE_WAITING_FOR_NETWORK -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"] 247 LIGHT_STATE_WAITING_FOR_NETWORK -> LIGHT_STATE_IDLE_MAINTENANCE 248 LIGHT_STATE_WAITING_FOR_NETWORK -> LIGHT_STATE_OVERRIDE [ 249 label="deep goes to STATE_IDLE" 250 ] 251 252 LIGHT_STATE_IDLE_MAINTENANCE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"] 253 LIGHT_STATE_IDLE_MAINTENANCE -> LIGHT_STATE_IDLE [ 254 label="stepLightIdleStateLocked(), exitMaintenanceEarlyIfNeededLocked()" 255 ] 256 LIGHT_STATE_IDLE_MAINTENANCE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"] 257 258 LIGHT_STATE_OVERRIDE -> LIGHT_STATE_ACTIVE [ 259 label="handleMotionDetectedLocked(), becomeActiveLocked()" 260 ] 261 } 262 } 263 </pre> 264 */ 265 public class DeviceIdleController extends SystemService 266 implements AnyMotionDetector.DeviceIdleCallback { 267 private static final String TAG = "DeviceIdleController"; 268 269 private static final boolean DEBUG = false; 270 271 private static final boolean COMPRESS_TIME = false; 272 273 private static final int EVENT_BUFFER_SIZE = 100; 274 275 private AlarmManager mAlarmManager; 276 private AlarmManagerInternal mLocalAlarmManager; 277 private IBatteryStats mBatteryStats; 278 private ActivityManagerInternal mLocalActivityManager; 279 private ActivityTaskManagerInternal mLocalActivityTaskManager; 280 private PowerManagerInternal mLocalPowerManager; 281 private PowerManager mPowerManager; 282 private INetworkPolicyManager mNetworkPolicyManager; 283 private SensorManager mSensorManager; 284 private final boolean mUseMotionSensor; 285 private Sensor mMotionSensor; 286 private LocationRequest mLocationRequest; 287 private Intent mIdleIntent; 288 private Intent mLightIdleIntent; 289 private AnyMotionDetector mAnyMotionDetector; 290 private final AppStateTracker mAppStateTracker; 291 private boolean mLightEnabled; 292 private boolean mDeepEnabled; 293 private boolean mQuickDozeActivated; 294 private boolean mForceIdle; 295 private boolean mNetworkConnected; 296 private boolean mScreenOn; 297 private boolean mCharging; 298 private boolean mNotMoving; 299 private boolean mLocating; 300 private boolean mLocated; 301 private boolean mHasGps; 302 private boolean mHasNetworkLocation; 303 private Location mLastGenericLocation; 304 private Location mLastGpsLocation; 305 // Current locked state of the screen 306 private boolean mScreenLocked; 307 private int mNumBlockingConstraints = 0; 308 309 /** 310 * Constraints are the "handbrakes" that stop the device from moving into a lower state until 311 * every one is released at the same time. 312 * 313 * @see #registerDeviceIdleConstraintInternal(IDeviceIdleConstraint, String, int) 314 */ 315 private final ArrayMap<IDeviceIdleConstraint, DeviceIdleConstraintTracker> 316 mConstraints = new ArrayMap<>(); 317 private ConstraintController mConstraintController; 318 319 /** Device is currently active. */ 320 @VisibleForTesting 321 static final int STATE_ACTIVE = 0; 322 /** Device is inactive (screen off, no motion) and we are waiting to for idle. */ 323 @VisibleForTesting 324 static final int STATE_INACTIVE = 1; 325 /** Device is past the initial inactive period, and waiting for the next idle period. */ 326 @VisibleForTesting 327 static final int STATE_IDLE_PENDING = 2; 328 /** Device is currently sensing motion. */ 329 @VisibleForTesting 330 static final int STATE_SENSING = 3; 331 /** Device is currently finding location (and may still be sensing). */ 332 @VisibleForTesting 333 static final int STATE_LOCATING = 4; 334 /** Device is in the idle state, trying to stay asleep as much as possible. */ 335 @VisibleForTesting 336 static final int STATE_IDLE = 5; 337 /** Device is in the idle state, but temporarily out of idle to do regular maintenance. */ 338 @VisibleForTesting 339 static final int STATE_IDLE_MAINTENANCE = 6; 340 /** 341 * Device is inactive and should go straight into idle (foregoing motion and location 342 * monitoring), but allow some time for current work to complete first. 343 */ 344 @VisibleForTesting 345 static final int STATE_QUICK_DOZE_DELAY = 7; 346 347 private static final int ACTIVE_REASON_UNKNOWN = 0; 348 private static final int ACTIVE_REASON_MOTION = 1; 349 private static final int ACTIVE_REASON_SCREEN = 2; 350 private static final int ACTIVE_REASON_CHARGING = 3; 351 private static final int ACTIVE_REASON_UNLOCKED = 4; 352 private static final int ACTIVE_REASON_FROM_BINDER_CALL = 5; 353 private static final int ACTIVE_REASON_FORCED = 6; 354 private static final int ACTIVE_REASON_ALARM = 7; 355 @VisibleForTesting 356 static final int SET_IDLE_FACTOR_RESULT_UNINIT = -1; 357 @VisibleForTesting 358 static final int SET_IDLE_FACTOR_RESULT_IGNORED = 0; 359 @VisibleForTesting 360 static final int SET_IDLE_FACTOR_RESULT_OK = 1; 361 @VisibleForTesting 362 static final int SET_IDLE_FACTOR_RESULT_NOT_SUPPORT = 2; 363 @VisibleForTesting 364 static final int SET_IDLE_FACTOR_RESULT_INVALID = 3; 365 @VisibleForTesting 366 static final long MIN_STATE_STEP_ALARM_CHANGE = 60 * 1000; 367 @VisibleForTesting 368 static final float MIN_PRE_IDLE_FACTOR_CHANGE = 0.05f; 369 370 @VisibleForTesting stateToString(int state)371 static String stateToString(int state) { 372 switch (state) { 373 case STATE_ACTIVE: return "ACTIVE"; 374 case STATE_INACTIVE: return "INACTIVE"; 375 case STATE_IDLE_PENDING: return "IDLE_PENDING"; 376 case STATE_SENSING: return "SENSING"; 377 case STATE_LOCATING: return "LOCATING"; 378 case STATE_IDLE: return "IDLE"; 379 case STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE"; 380 case STATE_QUICK_DOZE_DELAY: return "QUICK_DOZE_DELAY"; 381 default: return Integer.toString(state); 382 } 383 } 384 385 /** Device is currently active. */ 386 @VisibleForTesting 387 static final int LIGHT_STATE_ACTIVE = 0; 388 /** Device is inactive (screen off) and we are waiting to for the first light idle. */ 389 @VisibleForTesting 390 static final int LIGHT_STATE_INACTIVE = 1; 391 /** Device is about to go idle for the first time, wait for current work to complete. */ 392 @VisibleForTesting 393 static final int LIGHT_STATE_PRE_IDLE = 3; 394 /** Device is in the light idle state, trying to stay asleep as much as possible. */ 395 @VisibleForTesting 396 static final int LIGHT_STATE_IDLE = 4; 397 /** Device is in the light idle state, we want to go in to idle maintenance but are 398 * waiting for network connectivity before doing so. */ 399 @VisibleForTesting 400 static final int LIGHT_STATE_WAITING_FOR_NETWORK = 5; 401 /** Device is in the light idle state, but temporarily out of idle to do regular maintenance. */ 402 @VisibleForTesting 403 static final int LIGHT_STATE_IDLE_MAINTENANCE = 6; 404 /** Device light idle state is overriden, now applying deep doze state. */ 405 @VisibleForTesting 406 static final int LIGHT_STATE_OVERRIDE = 7; 407 408 @VisibleForTesting lightStateToString(int state)409 static String lightStateToString(int state) { 410 switch (state) { 411 case LIGHT_STATE_ACTIVE: return "ACTIVE"; 412 case LIGHT_STATE_INACTIVE: return "INACTIVE"; 413 case LIGHT_STATE_PRE_IDLE: return "PRE_IDLE"; 414 case LIGHT_STATE_IDLE: return "IDLE"; 415 case LIGHT_STATE_WAITING_FOR_NETWORK: return "WAITING_FOR_NETWORK"; 416 case LIGHT_STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE"; 417 case LIGHT_STATE_OVERRIDE: return "OVERRIDE"; 418 default: return Integer.toString(state); 419 } 420 } 421 422 private int mState; 423 private int mLightState; 424 425 private long mInactiveTimeout; 426 private long mNextAlarmTime; 427 private long mNextIdlePendingDelay; 428 private long mNextIdleDelay; 429 private long mNextLightIdleDelay; 430 private long mNextLightAlarmTime; 431 private long mNextSensingTimeoutAlarmTime; 432 private long mCurIdleBudget; 433 private long mMaintenanceStartTime; 434 private long mIdleStartTime; 435 436 private int mActiveIdleOpCount; 437 private PowerManager.WakeLock mActiveIdleWakeLock; // held when there are operations in progress 438 private PowerManager.WakeLock mGoingIdleWakeLock; // held when we are going idle so hardware 439 // (especially NetworkPolicyManager) can shut 440 // down. 441 private boolean mJobsActive; 442 private boolean mAlarmsActive; 443 private boolean mReportedMaintenanceActivity; 444 445 /* Factor to apply to INACTIVE_TIMEOUT and IDLE_AFTER_INACTIVE_TIMEOUT in order to enter 446 * STATE_IDLE faster or slower. Don't apply this to SENSING_TIMEOUT or LOCATING_TIMEOUT because: 447 * - Both of them are shorter 448 * - Device sensor might take time be to become be stabilized 449 * Also don't apply the factor if the device is in motion because device motion provides a 450 * stronger signal than a prediction algorithm. 451 */ 452 private float mPreIdleFactor; 453 private float mLastPreIdleFactor; 454 private int mActiveReason; 455 456 public final AtomicFile mConfigFile; 457 458 private final RemoteCallbackList<IMaintenanceActivityListener> mMaintenanceActivityListeners = 459 new RemoteCallbackList<IMaintenanceActivityListener>(); 460 461 /** 462 * Package names the system has white-listed to opt out of power save restrictions, 463 * except for device idle mode. 464 */ 465 private final ArrayMap<String, Integer> mPowerSaveWhitelistAppsExceptIdle = new ArrayMap<>(); 466 467 /** 468 * Package names the user has white-listed using commandline option to opt out of 469 * power save restrictions, except for device idle mode. 470 */ 471 private final ArraySet<String> mPowerSaveWhitelistUserAppsExceptIdle = new ArraySet<>(); 472 473 /** 474 * Package names the system has white-listed to opt out of power save restrictions for 475 * all modes. 476 */ 477 private final ArrayMap<String, Integer> mPowerSaveWhitelistApps = new ArrayMap<>(); 478 479 /** 480 * Package names the user has white-listed to opt out of power save restrictions. 481 */ 482 private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>(); 483 484 /** 485 * App IDs of built-in system apps that have been white-listed except for idle modes. 486 */ 487 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIdsExceptIdle 488 = new SparseBooleanArray(); 489 490 /** 491 * App IDs of built-in system apps that have been white-listed. 492 */ 493 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray(); 494 495 /** 496 * App IDs that have been white-listed to opt out of power save restrictions, except 497 * for device idle modes. 498 */ 499 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray(); 500 501 /** 502 * Current app IDs that are in the complete power save white list, but shouldn't be 503 * excluded from idle modes. This array can be shared with others because it will not be 504 * modified once set. 505 */ 506 private int[] mPowerSaveWhitelistExceptIdleAppIdArray = new int[0]; 507 508 /** 509 * App IDs that have been white-listed to opt out of power save restrictions. 510 */ 511 private final SparseBooleanArray mPowerSaveWhitelistAllAppIds = new SparseBooleanArray(); 512 513 /** 514 * Current app IDs that are in the complete power save white list. This array can 515 * be shared with others because it will not be modified once set. 516 */ 517 private int[] mPowerSaveWhitelistAllAppIdArray = new int[0]; 518 519 /** 520 * App IDs that have been white-listed by the user to opt out of power save restrictions. 521 */ 522 private final SparseBooleanArray mPowerSaveWhitelistUserAppIds = new SparseBooleanArray(); 523 524 /** 525 * Current app IDs that are in the user power save white list. This array can 526 * be shared with others because it will not be modified once set. 527 */ 528 private int[] mPowerSaveWhitelistUserAppIdArray = new int[0]; 529 530 /** 531 * List of end times for UIDs that are temporarily marked as being allowed to access 532 * the network and acquire wakelocks. Times are in milliseconds. 533 */ 534 private final SparseArray<Pair<MutableLong, String>> mTempWhitelistAppIdEndTimes 535 = new SparseArray<>(); 536 537 private NetworkPolicyManagerInternal mNetworkPolicyManagerInternal; 538 539 /** 540 * Current app IDs of temporarily whitelist apps for high-priority messages. 541 */ 542 private int[] mTempWhitelistAppIdArray = new int[0]; 543 544 /** 545 * Apps in the system whitelist that have been taken out (probably because the user wanted to). 546 * They can be restored back by calling restoreAppToSystemWhitelist(String). 547 */ 548 private ArrayMap<String, Integer> mRemovedFromSystemWhitelistApps = new ArrayMap<>(); 549 550 private static final int EVENT_NULL = 0; 551 private static final int EVENT_NORMAL = 1; 552 private static final int EVENT_LIGHT_IDLE = 2; 553 private static final int EVENT_LIGHT_MAINTENANCE = 3; 554 private static final int EVENT_DEEP_IDLE = 4; 555 private static final int EVENT_DEEP_MAINTENANCE = 5; 556 557 private final int[] mEventCmds = new int[EVENT_BUFFER_SIZE]; 558 private final long[] mEventTimes = new long[EVENT_BUFFER_SIZE]; 559 private final String[] mEventReasons = new String[EVENT_BUFFER_SIZE]; 560 addEvent(int cmd, String reason)561 private void addEvent(int cmd, String reason) { 562 if (mEventCmds[0] != cmd) { 563 System.arraycopy(mEventCmds, 0, mEventCmds, 1, EVENT_BUFFER_SIZE - 1); 564 System.arraycopy(mEventTimes, 0, mEventTimes, 1, EVENT_BUFFER_SIZE - 1); 565 System.arraycopy(mEventReasons, 0, mEventReasons, 1, EVENT_BUFFER_SIZE - 1); 566 mEventCmds[0] = cmd; 567 mEventTimes[0] = SystemClock.elapsedRealtime(); 568 mEventReasons[0] = reason; 569 } 570 } 571 572 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 573 @Override public void onReceive(Context context, Intent intent) { 574 switch (intent.getAction()) { 575 case ConnectivityManager.CONNECTIVITY_ACTION: { 576 updateConnectivityState(intent); 577 } break; 578 case Intent.ACTION_BATTERY_CHANGED: { 579 boolean present = intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, true); 580 boolean plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0; 581 synchronized (DeviceIdleController.this) { 582 updateChargingLocked(present && plugged); 583 } 584 } break; 585 case Intent.ACTION_PACKAGE_REMOVED: { 586 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 587 Uri data = intent.getData(); 588 String ssp; 589 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 590 removePowerSaveWhitelistAppInternal(ssp); 591 } 592 } 593 } break; 594 } 595 } 596 }; 597 598 private final AlarmManager.OnAlarmListener mLightAlarmListener 599 = new AlarmManager.OnAlarmListener() { 600 @Override 601 public void onAlarm() { 602 synchronized (DeviceIdleController.this) { 603 stepLightIdleStateLocked("s:alarm"); 604 } 605 } 606 }; 607 608 private final AlarmManager.OnAlarmListener mSensingTimeoutAlarmListener 609 = new AlarmManager.OnAlarmListener() { 610 @Override 611 public void onAlarm() { 612 if (mState == STATE_SENSING) { 613 synchronized (DeviceIdleController.this) { 614 // Restart the device idle progression in case the device moved but the screen 615 // didn't turn on. 616 becomeInactiveIfAppropriateLocked(); 617 } 618 } 619 } 620 }; 621 622 @VisibleForTesting 623 final AlarmManager.OnAlarmListener mDeepAlarmListener 624 = new AlarmManager.OnAlarmListener() { 625 @Override 626 public void onAlarm() { 627 synchronized (DeviceIdleController.this) { 628 stepIdleStateLocked("s:alarm"); 629 } 630 } 631 }; 632 633 private final BroadcastReceiver mIdleStartedDoneReceiver = new BroadcastReceiver() { 634 @Override public void onReceive(Context context, Intent intent) { 635 // When coming out of a deep idle, we will add in some delay before we allow 636 // the system to settle down and finish the maintenance window. This is 637 // to give a chance for any pending work to be scheduled. 638 if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(intent.getAction())) { 639 mHandler.sendEmptyMessageDelayed(MSG_FINISH_IDLE_OP, 640 mConstants.MIN_DEEP_MAINTENANCE_TIME); 641 } else { 642 mHandler.sendEmptyMessageDelayed(MSG_FINISH_IDLE_OP, 643 mConstants.MIN_LIGHT_MAINTENANCE_TIME); 644 } 645 } 646 }; 647 648 private final BroadcastReceiver mInteractivityReceiver = new BroadcastReceiver() { 649 @Override 650 public void onReceive(Context context, Intent intent) { 651 synchronized (DeviceIdleController.this) { 652 updateInteractivityLocked(); 653 } 654 } 655 }; 656 657 @VisibleForTesting 658 final class MotionListener extends TriggerEventListener 659 implements SensorEventListener { 660 661 boolean active = false; 662 isActive()663 public boolean isActive() { 664 return active; 665 } 666 667 @Override onTrigger(TriggerEvent event)668 public void onTrigger(TriggerEvent event) { 669 synchronized (DeviceIdleController.this) { 670 active = false; 671 motionLocked(); 672 } 673 } 674 675 @Override onSensorChanged(SensorEvent event)676 public void onSensorChanged(SensorEvent event) { 677 synchronized (DeviceIdleController.this) { 678 mSensorManager.unregisterListener(this, mMotionSensor); 679 active = false; 680 motionLocked(); 681 } 682 } 683 684 @Override onAccuracyChanged(Sensor sensor, int accuracy)685 public void onAccuracyChanged(Sensor sensor, int accuracy) {} 686 registerLocked()687 public boolean registerLocked() { 688 boolean success; 689 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) { 690 success = mSensorManager.requestTriggerSensor(mMotionListener, mMotionSensor); 691 } else { 692 success = mSensorManager.registerListener( 693 mMotionListener, mMotionSensor, SensorManager.SENSOR_DELAY_NORMAL); 694 } 695 if (success) { 696 active = true; 697 } else { 698 Slog.e(TAG, "Unable to register for " + mMotionSensor); 699 } 700 return success; 701 } 702 unregisterLocked()703 public void unregisterLocked() { 704 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) { 705 mSensorManager.cancelTriggerSensor(mMotionListener, mMotionSensor); 706 } else { 707 mSensorManager.unregisterListener(mMotionListener); 708 } 709 active = false; 710 } 711 } 712 @VisibleForTesting final MotionListener mMotionListener = new MotionListener(); 713 714 private final LocationListener mGenericLocationListener = new LocationListener() { 715 @Override 716 public void onLocationChanged(Location location) { 717 synchronized (DeviceIdleController.this) { 718 receivedGenericLocationLocked(location); 719 } 720 } 721 722 @Override 723 public void onStatusChanged(String provider, int status, Bundle extras) { 724 } 725 726 @Override 727 public void onProviderEnabled(String provider) { 728 } 729 730 @Override 731 public void onProviderDisabled(String provider) { 732 } 733 }; 734 735 private final LocationListener mGpsLocationListener = new LocationListener() { 736 @Override 737 public void onLocationChanged(Location location) { 738 synchronized (DeviceIdleController.this) { 739 receivedGpsLocationLocked(location); 740 } 741 } 742 743 @Override 744 public void onStatusChanged(String provider, int status, Bundle extras) { 745 } 746 747 @Override 748 public void onProviderEnabled(String provider) { 749 } 750 751 @Override 752 public void onProviderDisabled(String provider) { 753 } 754 }; 755 756 /** 757 * All times are in milliseconds. These constants are kept synchronized with the system 758 * global Settings. Any access to this class or its fields should be done while 759 * holding the DeviceIdleController lock. 760 */ 761 public final class Constants extends ContentObserver { 762 // Key names stored in the settings value. 763 private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT 764 = "light_after_inactive_to"; 765 private static final String KEY_LIGHT_PRE_IDLE_TIMEOUT = "light_pre_idle_to"; 766 private static final String KEY_LIGHT_IDLE_TIMEOUT = "light_idle_to"; 767 private static final String KEY_LIGHT_IDLE_FACTOR = "light_idle_factor"; 768 private static final String KEY_LIGHT_MAX_IDLE_TIMEOUT = "light_max_idle_to"; 769 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET 770 = "light_idle_maintenance_min_budget"; 771 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET 772 = "light_idle_maintenance_max_budget"; 773 private static final String KEY_MIN_LIGHT_MAINTENANCE_TIME = "min_light_maintenance_time"; 774 private static final String KEY_MIN_DEEP_MAINTENANCE_TIME = "min_deep_maintenance_time"; 775 private static final String KEY_INACTIVE_TIMEOUT = "inactive_to"; 776 private static final String KEY_SENSING_TIMEOUT = "sensing_to"; 777 private static final String KEY_LOCATING_TIMEOUT = "locating_to"; 778 private static final String KEY_LOCATION_ACCURACY = "location_accuracy"; 779 private static final String KEY_MOTION_INACTIVE_TIMEOUT = "motion_inactive_to"; 780 private static final String KEY_IDLE_AFTER_INACTIVE_TIMEOUT = "idle_after_inactive_to"; 781 private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to"; 782 private static final String KEY_MAX_IDLE_PENDING_TIMEOUT = "max_idle_pending_to"; 783 private static final String KEY_IDLE_PENDING_FACTOR = "idle_pending_factor"; 784 private static final String KEY_QUICK_DOZE_DELAY_TIMEOUT = "quick_doze_delay_to"; 785 private static final String KEY_IDLE_TIMEOUT = "idle_to"; 786 private static final String KEY_MAX_IDLE_TIMEOUT = "max_idle_to"; 787 private static final String KEY_IDLE_FACTOR = "idle_factor"; 788 private static final String KEY_MIN_TIME_TO_ALARM = "min_time_to_alarm"; 789 private static final String KEY_MAX_TEMP_APP_WHITELIST_DURATION = 790 "max_temp_app_whitelist_duration"; 791 private static final String KEY_MMS_TEMP_APP_WHITELIST_DURATION = 792 "mms_temp_app_whitelist_duration"; 793 private static final String KEY_SMS_TEMP_APP_WHITELIST_DURATION = 794 "sms_temp_app_whitelist_duration"; 795 private static final String KEY_NOTIFICATION_WHITELIST_DURATION = 796 "notification_whitelist_duration"; 797 /** 798 * Whether to wait for the user to unlock the device before causing screen-on to 799 * exit doze. Default = true 800 */ 801 private static final String KEY_WAIT_FOR_UNLOCK = "wait_for_unlock"; 802 private static final String KEY_PRE_IDLE_FACTOR_LONG = 803 "pre_idle_factor_long"; 804 private static final String KEY_PRE_IDLE_FACTOR_SHORT = 805 "pre_idle_factor_short"; 806 807 /** 808 * This is the time, after becoming inactive, that we go in to the first 809 * light-weight idle mode. 810 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 811 * @see #KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT 812 */ 813 public long LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT; 814 815 /** 816 * This is amount of time we will wait from the point where we decide we would 817 * like to go idle until we actually do, while waiting for jobs and other current 818 * activity to finish. 819 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 820 * @see #KEY_LIGHT_PRE_IDLE_TIMEOUT 821 */ 822 public long LIGHT_PRE_IDLE_TIMEOUT; 823 824 /** 825 * This is the initial time that we will run in idle maintenance mode. 826 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 827 * @see #KEY_LIGHT_IDLE_TIMEOUT 828 */ 829 public long LIGHT_IDLE_TIMEOUT; 830 831 /** 832 * Scaling factor to apply to the light idle mode time each time we complete a cycle. 833 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 834 * @see #KEY_LIGHT_IDLE_FACTOR 835 */ 836 public float LIGHT_IDLE_FACTOR; 837 838 /** 839 * This is the maximum time we will run in idle maintenance mode. 840 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 841 * @see #KEY_LIGHT_MAX_IDLE_TIMEOUT 842 */ 843 public long LIGHT_MAX_IDLE_TIMEOUT; 844 845 /** 846 * This is the minimum amount of time we want to make available for maintenance mode 847 * when lightly idling. That is, we will always have at least this amount of time 848 * available maintenance before timing out and cutting off maintenance mode. 849 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 850 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET 851 */ 852 public long LIGHT_IDLE_MAINTENANCE_MIN_BUDGET; 853 854 /** 855 * This is the maximum amount of time we want to make available for maintenance mode 856 * when lightly idling. That is, if the system isn't using up its minimum maintenance 857 * budget and this time is being added to the budget reserve, this is the maximum 858 * reserve size we will allow to grow and thus the maximum amount of time we will 859 * allow for the maintenance window. 860 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 861 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET 862 */ 863 public long LIGHT_IDLE_MAINTENANCE_MAX_BUDGET; 864 865 /** 866 * This is the minimum amount of time that we will stay in maintenance mode after 867 * a light doze. We have this minimum to allow various things to respond to switching 868 * in to maintenance mode and scheduling their work -- otherwise we may 869 * see there is nothing to do (no jobs pending) and go out of maintenance 870 * mode immediately. 871 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 872 * @see #KEY_MIN_LIGHT_MAINTENANCE_TIME 873 */ 874 public long MIN_LIGHT_MAINTENANCE_TIME; 875 876 /** 877 * This is the minimum amount of time that we will stay in maintenance mode after 878 * a full doze. We have this minimum to allow various things to respond to switching 879 * in to maintenance mode and scheduling their work -- otherwise we may 880 * see there is nothing to do (no jobs pending) and go out of maintenance 881 * mode immediately. 882 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 883 * @see #KEY_MIN_DEEP_MAINTENANCE_TIME 884 */ 885 public long MIN_DEEP_MAINTENANCE_TIME; 886 887 /** 888 * This is the time, after becoming inactive, at which we start looking at the 889 * motion sensor to determine if the device is being left alone. We don't do this 890 * immediately after going inactive just because we don't want to be continually running 891 * the motion sensor whenever the screen is off. 892 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 893 * @see #KEY_INACTIVE_TIMEOUT 894 */ 895 public long INACTIVE_TIMEOUT; 896 897 /** 898 * If we don't receive a callback from AnyMotion in this amount of time + 899 * {@link #LOCATING_TIMEOUT}, we will change from 900 * STATE_SENSING to STATE_INACTIVE, and any AnyMotion callbacks while not in STATE_SENSING 901 * will be ignored. 902 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 903 * @see #KEY_SENSING_TIMEOUT 904 */ 905 public long SENSING_TIMEOUT; 906 907 /** 908 * This is how long we will wait to try to get a good location fix before going in to 909 * idle mode. 910 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 911 * @see #KEY_LOCATING_TIMEOUT 912 */ 913 public long LOCATING_TIMEOUT; 914 915 /** 916 * The desired maximum accuracy (in meters) we consider the location to be good enough to go 917 * on to idle. We will be trying to get an accuracy fix at least this good or until 918 * {@link #LOCATING_TIMEOUT} expires. 919 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 920 * @see #KEY_LOCATION_ACCURACY 921 */ 922 public float LOCATION_ACCURACY; 923 924 /** 925 * This is the time, after seeing motion, that we wait after becoming inactive from 926 * that until we start looking for motion again. 927 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 928 * @see #KEY_MOTION_INACTIVE_TIMEOUT 929 */ 930 public long MOTION_INACTIVE_TIMEOUT; 931 932 /** 933 * This is the time, after the inactive timeout elapses, that we will wait looking 934 * for motion until we truly consider the device to be idle. 935 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 936 * @see #KEY_IDLE_AFTER_INACTIVE_TIMEOUT 937 */ 938 public long IDLE_AFTER_INACTIVE_TIMEOUT; 939 940 /** 941 * This is the initial time, after being idle, that we will allow ourself to be back 942 * in the IDLE_MAINTENANCE state allowing the system to run normally until we return to 943 * idle. 944 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 945 * @see #KEY_IDLE_PENDING_TIMEOUT 946 */ 947 public long IDLE_PENDING_TIMEOUT; 948 949 /** 950 * Maximum pending idle timeout (time spent running) we will be allowed to use. 951 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 952 * @see #KEY_MAX_IDLE_PENDING_TIMEOUT 953 */ 954 public long MAX_IDLE_PENDING_TIMEOUT; 955 956 /** 957 * Scaling factor to apply to current pending idle timeout each time we cycle through 958 * that state. 959 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 960 * @see #KEY_IDLE_PENDING_FACTOR 961 */ 962 public float IDLE_PENDING_FACTOR; 963 964 /** 965 * This is amount of time we will wait from the point where we go into 966 * STATE_QUICK_DOZE_DELAY until we actually go into STATE_IDLE, while waiting for jobs 967 * and other current activity to finish. 968 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 969 * @see #KEY_QUICK_DOZE_DELAY_TIMEOUT 970 */ 971 public long QUICK_DOZE_DELAY_TIMEOUT; 972 973 /** 974 * This is the initial time that we want to sit in the idle state before waking up 975 * again to return to pending idle and allowing normal work to run. 976 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 977 * @see #KEY_IDLE_TIMEOUT 978 */ 979 public long IDLE_TIMEOUT; 980 981 /** 982 * Maximum idle duration we will be allowed to use. 983 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 984 * @see #KEY_MAX_IDLE_TIMEOUT 985 */ 986 public long MAX_IDLE_TIMEOUT; 987 988 /** 989 * Scaling factor to apply to current idle timeout each time we cycle through that state. 990 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 991 * @see #KEY_IDLE_FACTOR 992 */ 993 public float IDLE_FACTOR; 994 995 /** 996 * This is the minimum time we will allow until the next upcoming alarm for us to 997 * actually go in to idle mode. 998 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 999 * @see #KEY_MIN_TIME_TO_ALARM 1000 */ 1001 public long MIN_TIME_TO_ALARM; 1002 1003 /** 1004 * Max amount of time to temporarily whitelist an app when it receives a high priority 1005 * tickle. 1006 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 1007 * @see #KEY_MAX_TEMP_APP_WHITELIST_DURATION 1008 */ 1009 public long MAX_TEMP_APP_WHITELIST_DURATION; 1010 1011 /** 1012 * Amount of time we would like to whitelist an app that is receiving an MMS. 1013 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 1014 * @see #KEY_MMS_TEMP_APP_WHITELIST_DURATION 1015 */ 1016 public long MMS_TEMP_APP_WHITELIST_DURATION; 1017 1018 /** 1019 * Amount of time we would like to whitelist an app that is receiving an SMS. 1020 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 1021 * @see #KEY_SMS_TEMP_APP_WHITELIST_DURATION 1022 */ 1023 public long SMS_TEMP_APP_WHITELIST_DURATION; 1024 1025 /** 1026 * Amount of time we would like to whitelist an app that is handling a 1027 * {@link android.app.PendingIntent} triggered by a {@link android.app.Notification}. 1028 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 1029 * @see #KEY_NOTIFICATION_WHITELIST_DURATION 1030 */ 1031 public long NOTIFICATION_WHITELIST_DURATION; 1032 1033 /** 1034 * Pre idle time factor use to make idle delay longer 1035 */ 1036 public float PRE_IDLE_FACTOR_LONG; 1037 1038 /** 1039 * Pre idle time factor use to make idle delay shorter 1040 */ 1041 public float PRE_IDLE_FACTOR_SHORT; 1042 1043 public boolean WAIT_FOR_UNLOCK; 1044 1045 private final ContentResolver mResolver; 1046 private final boolean mSmallBatteryDevice; 1047 private final KeyValueListParser mParser = new KeyValueListParser(','); 1048 Constants(Handler handler, ContentResolver resolver)1049 public Constants(Handler handler, ContentResolver resolver) { 1050 super(handler); 1051 mResolver = resolver; 1052 mSmallBatteryDevice = ActivityManager.isSmallBatteryDevice(); 1053 mResolver.registerContentObserver( 1054 Settings.Global.getUriFor(Settings.Global.DEVICE_IDLE_CONSTANTS), 1055 false, this); 1056 updateConstants(); 1057 } 1058 1059 @Override onChange(boolean selfChange, Uri uri)1060 public void onChange(boolean selfChange, Uri uri) { 1061 updateConstants(); 1062 } 1063 updateConstants()1064 private void updateConstants() { 1065 synchronized (DeviceIdleController.this) { 1066 try { 1067 mParser.setString(Settings.Global.getString(mResolver, 1068 Settings.Global.DEVICE_IDLE_CONSTANTS)); 1069 } catch (IllegalArgumentException e) { 1070 // Failed to parse the settings string, log this and move on 1071 // with defaults. 1072 Slog.e(TAG, "Bad device idle settings", e); 1073 } 1074 1075 LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getDurationMillis( 1076 KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT, 1077 !COMPRESS_TIME ? 3 * 60 * 1000L : 15 * 1000L); 1078 LIGHT_PRE_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_LIGHT_PRE_IDLE_TIMEOUT, 1079 !COMPRESS_TIME ? 3 * 60 * 1000L : 30 * 1000L); 1080 LIGHT_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_LIGHT_IDLE_TIMEOUT, 1081 !COMPRESS_TIME ? 5 * 60 * 1000L : 15 * 1000L); 1082 LIGHT_IDLE_FACTOR = mParser.getFloat(KEY_LIGHT_IDLE_FACTOR, 1083 2f); 1084 LIGHT_MAX_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_LIGHT_MAX_IDLE_TIMEOUT, 1085 !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L); 1086 LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = mParser.getDurationMillis( 1087 KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET, 1088 !COMPRESS_TIME ? 1 * 60 * 1000L : 15 * 1000L); 1089 LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = mParser.getDurationMillis( 1090 KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET, 1091 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L); 1092 MIN_LIGHT_MAINTENANCE_TIME = mParser.getDurationMillis( 1093 KEY_MIN_LIGHT_MAINTENANCE_TIME, 1094 !COMPRESS_TIME ? 5 * 1000L : 1 * 1000L); 1095 MIN_DEEP_MAINTENANCE_TIME = mParser.getDurationMillis( 1096 KEY_MIN_DEEP_MAINTENANCE_TIME, 1097 !COMPRESS_TIME ? 30 * 1000L : 5 * 1000L); 1098 long inactiveTimeoutDefault = (mSmallBatteryDevice ? 15 : 30) * 60 * 1000L; 1099 INACTIVE_TIMEOUT = mParser.getDurationMillis(KEY_INACTIVE_TIMEOUT, 1100 !COMPRESS_TIME ? inactiveTimeoutDefault : (inactiveTimeoutDefault / 10)); 1101 SENSING_TIMEOUT = mParser.getDurationMillis(KEY_SENSING_TIMEOUT, 1102 !COMPRESS_TIME ? 4 * 60 * 1000L : 60 * 1000L); 1103 LOCATING_TIMEOUT = mParser.getDurationMillis(KEY_LOCATING_TIMEOUT, 1104 !COMPRESS_TIME ? 30 * 1000L : 15 * 1000L); 1105 LOCATION_ACCURACY = mParser.getFloat(KEY_LOCATION_ACCURACY, 20); 1106 MOTION_INACTIVE_TIMEOUT = mParser.getDurationMillis(KEY_MOTION_INACTIVE_TIMEOUT, 1107 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L); 1108 long idleAfterInactiveTimeout = (mSmallBatteryDevice ? 15 : 30) * 60 * 1000L; 1109 IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getDurationMillis( 1110 KEY_IDLE_AFTER_INACTIVE_TIMEOUT, 1111 !COMPRESS_TIME ? idleAfterInactiveTimeout 1112 : (idleAfterInactiveTimeout / 10)); 1113 IDLE_PENDING_TIMEOUT = mParser.getDurationMillis(KEY_IDLE_PENDING_TIMEOUT, 1114 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L); 1115 MAX_IDLE_PENDING_TIMEOUT = mParser.getDurationMillis(KEY_MAX_IDLE_PENDING_TIMEOUT, 1116 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L); 1117 IDLE_PENDING_FACTOR = mParser.getFloat(KEY_IDLE_PENDING_FACTOR, 1118 2f); 1119 QUICK_DOZE_DELAY_TIMEOUT = mParser.getDurationMillis( 1120 KEY_QUICK_DOZE_DELAY_TIMEOUT, !COMPRESS_TIME ? 60 * 1000L : 15 * 1000L); 1121 IDLE_TIMEOUT = mParser.getDurationMillis(KEY_IDLE_TIMEOUT, 1122 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L); 1123 MAX_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_MAX_IDLE_TIMEOUT, 1124 !COMPRESS_TIME ? 6 * 60 * 60 * 1000L : 30 * 60 * 1000L); 1125 IDLE_FACTOR = mParser.getFloat(KEY_IDLE_FACTOR, 1126 2f); 1127 MIN_TIME_TO_ALARM = mParser.getDurationMillis(KEY_MIN_TIME_TO_ALARM, 1128 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L); 1129 MAX_TEMP_APP_WHITELIST_DURATION = mParser.getDurationMillis( 1130 KEY_MAX_TEMP_APP_WHITELIST_DURATION, 5 * 60 * 1000L); 1131 MMS_TEMP_APP_WHITELIST_DURATION = mParser.getDurationMillis( 1132 KEY_MMS_TEMP_APP_WHITELIST_DURATION, 60 * 1000L); 1133 SMS_TEMP_APP_WHITELIST_DURATION = mParser.getDurationMillis( 1134 KEY_SMS_TEMP_APP_WHITELIST_DURATION, 20 * 1000L); 1135 NOTIFICATION_WHITELIST_DURATION = mParser.getDurationMillis( 1136 KEY_NOTIFICATION_WHITELIST_DURATION, 30 * 1000L); 1137 WAIT_FOR_UNLOCK = mParser.getBoolean(KEY_WAIT_FOR_UNLOCK, true); 1138 PRE_IDLE_FACTOR_LONG = mParser.getFloat(KEY_PRE_IDLE_FACTOR_LONG, 1.67f); 1139 PRE_IDLE_FACTOR_SHORT = mParser.getFloat(KEY_PRE_IDLE_FACTOR_SHORT, 0.33f); 1140 } 1141 } 1142 dump(PrintWriter pw)1143 void dump(PrintWriter pw) { 1144 pw.println(" Settings:"); 1145 1146 pw.print(" "); pw.print(KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("="); 1147 TimeUtils.formatDuration(LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT, pw); 1148 pw.println(); 1149 1150 pw.print(" "); pw.print(KEY_LIGHT_PRE_IDLE_TIMEOUT); pw.print("="); 1151 TimeUtils.formatDuration(LIGHT_PRE_IDLE_TIMEOUT, pw); 1152 pw.println(); 1153 1154 pw.print(" "); pw.print(KEY_LIGHT_IDLE_TIMEOUT); pw.print("="); 1155 TimeUtils.formatDuration(LIGHT_IDLE_TIMEOUT, pw); 1156 pw.println(); 1157 1158 pw.print(" "); pw.print(KEY_LIGHT_IDLE_FACTOR); pw.print("="); 1159 pw.print(LIGHT_IDLE_FACTOR); 1160 pw.println(); 1161 1162 pw.print(" "); pw.print(KEY_LIGHT_MAX_IDLE_TIMEOUT); pw.print("="); 1163 TimeUtils.formatDuration(LIGHT_MAX_IDLE_TIMEOUT, pw); 1164 pw.println(); 1165 1166 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET); pw.print("="); 1167 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MIN_BUDGET, pw); 1168 pw.println(); 1169 1170 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET); pw.print("="); 1171 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MAX_BUDGET, pw); 1172 pw.println(); 1173 1174 pw.print(" "); pw.print(KEY_MIN_LIGHT_MAINTENANCE_TIME); pw.print("="); 1175 TimeUtils.formatDuration(MIN_LIGHT_MAINTENANCE_TIME, pw); 1176 pw.println(); 1177 1178 pw.print(" "); pw.print(KEY_MIN_DEEP_MAINTENANCE_TIME); pw.print("="); 1179 TimeUtils.formatDuration(MIN_DEEP_MAINTENANCE_TIME, pw); 1180 pw.println(); 1181 1182 pw.print(" "); pw.print(KEY_INACTIVE_TIMEOUT); pw.print("="); 1183 TimeUtils.formatDuration(INACTIVE_TIMEOUT, pw); 1184 pw.println(); 1185 1186 pw.print(" "); pw.print(KEY_SENSING_TIMEOUT); pw.print("="); 1187 TimeUtils.formatDuration(SENSING_TIMEOUT, pw); 1188 pw.println(); 1189 1190 pw.print(" "); pw.print(KEY_LOCATING_TIMEOUT); pw.print("="); 1191 TimeUtils.formatDuration(LOCATING_TIMEOUT, pw); 1192 pw.println(); 1193 1194 pw.print(" "); pw.print(KEY_LOCATION_ACCURACY); pw.print("="); 1195 pw.print(LOCATION_ACCURACY); pw.print("m"); 1196 pw.println(); 1197 1198 pw.print(" "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT); pw.print("="); 1199 TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT, pw); 1200 pw.println(); 1201 1202 pw.print(" "); pw.print(KEY_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("="); 1203 TimeUtils.formatDuration(IDLE_AFTER_INACTIVE_TIMEOUT, pw); 1204 pw.println(); 1205 1206 pw.print(" "); pw.print(KEY_IDLE_PENDING_TIMEOUT); pw.print("="); 1207 TimeUtils.formatDuration(IDLE_PENDING_TIMEOUT, pw); 1208 pw.println(); 1209 1210 pw.print(" "); pw.print(KEY_MAX_IDLE_PENDING_TIMEOUT); pw.print("="); 1211 TimeUtils.formatDuration(MAX_IDLE_PENDING_TIMEOUT, pw); 1212 pw.println(); 1213 1214 pw.print(" "); pw.print(KEY_IDLE_PENDING_FACTOR); pw.print("="); 1215 pw.println(IDLE_PENDING_FACTOR); 1216 1217 pw.print(" "); pw.print(KEY_QUICK_DOZE_DELAY_TIMEOUT); pw.print("="); 1218 TimeUtils.formatDuration(QUICK_DOZE_DELAY_TIMEOUT, pw); 1219 pw.println(); 1220 1221 pw.print(" "); pw.print(KEY_IDLE_TIMEOUT); pw.print("="); 1222 TimeUtils.formatDuration(IDLE_TIMEOUT, pw); 1223 pw.println(); 1224 1225 pw.print(" "); pw.print(KEY_MAX_IDLE_TIMEOUT); pw.print("="); 1226 TimeUtils.formatDuration(MAX_IDLE_TIMEOUT, pw); 1227 pw.println(); 1228 1229 pw.print(" "); pw.print(KEY_IDLE_FACTOR); pw.print("="); 1230 pw.println(IDLE_FACTOR); 1231 1232 pw.print(" "); pw.print(KEY_MIN_TIME_TO_ALARM); pw.print("="); 1233 TimeUtils.formatDuration(MIN_TIME_TO_ALARM, pw); 1234 pw.println(); 1235 1236 pw.print(" "); pw.print(KEY_MAX_TEMP_APP_WHITELIST_DURATION); pw.print("="); 1237 TimeUtils.formatDuration(MAX_TEMP_APP_WHITELIST_DURATION, pw); 1238 pw.println(); 1239 1240 pw.print(" "); pw.print(KEY_MMS_TEMP_APP_WHITELIST_DURATION); pw.print("="); 1241 TimeUtils.formatDuration(MMS_TEMP_APP_WHITELIST_DURATION, pw); 1242 pw.println(); 1243 1244 pw.print(" "); pw.print(KEY_SMS_TEMP_APP_WHITELIST_DURATION); pw.print("="); 1245 TimeUtils.formatDuration(SMS_TEMP_APP_WHITELIST_DURATION, pw); 1246 pw.println(); 1247 1248 pw.print(" "); pw.print(KEY_NOTIFICATION_WHITELIST_DURATION); pw.print("="); 1249 TimeUtils.formatDuration(NOTIFICATION_WHITELIST_DURATION, pw); 1250 pw.println(); 1251 1252 pw.print(" "); pw.print(KEY_WAIT_FOR_UNLOCK); pw.print("="); 1253 pw.println(WAIT_FOR_UNLOCK); 1254 1255 pw.print(" "); pw.print(KEY_PRE_IDLE_FACTOR_LONG); pw.print("="); 1256 pw.println(PRE_IDLE_FACTOR_LONG); 1257 1258 pw.print(" "); pw.print(KEY_PRE_IDLE_FACTOR_SHORT); pw.print("="); 1259 pw.println(PRE_IDLE_FACTOR_SHORT); 1260 } 1261 } 1262 1263 private Constants mConstants; 1264 1265 @Override onAnyMotionResult(int result)1266 public void onAnyMotionResult(int result) { 1267 if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")"); 1268 if (result != AnyMotionDetector.RESULT_UNKNOWN) { 1269 synchronized (this) { 1270 cancelSensingTimeoutAlarmLocked(); 1271 } 1272 } 1273 if ((result == AnyMotionDetector.RESULT_MOVED) || 1274 (result == AnyMotionDetector.RESULT_UNKNOWN)) { 1275 synchronized (this) { 1276 handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "non_stationary"); 1277 } 1278 } else if (result == AnyMotionDetector.RESULT_STATIONARY) { 1279 if (mState == STATE_SENSING) { 1280 // If we are currently sensing, it is time to move to locating. 1281 synchronized (this) { 1282 mNotMoving = true; 1283 stepIdleStateLocked("s:stationary"); 1284 } 1285 } else if (mState == STATE_LOCATING) { 1286 // If we are currently locating, note that we are not moving and step 1287 // if we have located the position. 1288 synchronized (this) { 1289 mNotMoving = true; 1290 if (mLocated) { 1291 stepIdleStateLocked("s:stationary"); 1292 } 1293 } 1294 } 1295 } 1296 } 1297 1298 private static final int MSG_WRITE_CONFIG = 1; 1299 private static final int MSG_REPORT_IDLE_ON = 2; 1300 private static final int MSG_REPORT_IDLE_ON_LIGHT = 3; 1301 private static final int MSG_REPORT_IDLE_OFF = 4; 1302 private static final int MSG_REPORT_ACTIVE = 5; 1303 private static final int MSG_TEMP_APP_WHITELIST_TIMEOUT = 6; 1304 private static final int MSG_REPORT_MAINTENANCE_ACTIVITY = 7; 1305 private static final int MSG_FINISH_IDLE_OP = 8; 1306 private static final int MSG_REPORT_TEMP_APP_WHITELIST_CHANGED = 9; 1307 private static final int MSG_SEND_CONSTRAINT_MONITORING = 10; 1308 private static final int MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR = 11; 1309 private static final int MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR = 12; 1310 1311 final class MyHandler extends Handler { MyHandler(Looper looper)1312 MyHandler(Looper looper) { 1313 super(looper); 1314 } 1315 handleMessage(Message msg)1316 @Override public void handleMessage(Message msg) { 1317 if (DEBUG) Slog.d(TAG, "handleMessage(" + msg.what + ")"); 1318 switch (msg.what) { 1319 case MSG_WRITE_CONFIG: { 1320 // Does not hold a wakelock. Just let this happen whenever. 1321 handleWriteConfigFile(); 1322 } break; 1323 case MSG_REPORT_IDLE_ON: 1324 case MSG_REPORT_IDLE_ON_LIGHT: { 1325 // mGoingIdleWakeLock is held at this point 1326 EventLogTags.writeDeviceIdleOnStart(); 1327 final boolean deepChanged; 1328 final boolean lightChanged; 1329 if (msg.what == MSG_REPORT_IDLE_ON) { 1330 deepChanged = mLocalPowerManager.setDeviceIdleMode(true); 1331 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false); 1332 } else { 1333 deepChanged = mLocalPowerManager.setDeviceIdleMode(false); 1334 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(true); 1335 } 1336 try { 1337 mNetworkPolicyManager.setDeviceIdleMode(true); 1338 mBatteryStats.noteDeviceIdleMode(msg.what == MSG_REPORT_IDLE_ON 1339 ? BatteryStats.DEVICE_IDLE_MODE_DEEP 1340 : BatteryStats.DEVICE_IDLE_MODE_LIGHT, null, Process.myUid()); 1341 } catch (RemoteException e) { 1342 } 1343 if (deepChanged) { 1344 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL); 1345 } 1346 if (lightChanged) { 1347 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL); 1348 } 1349 EventLogTags.writeDeviceIdleOnComplete(); 1350 mGoingIdleWakeLock.release(); 1351 } break; 1352 case MSG_REPORT_IDLE_OFF: { 1353 // mActiveIdleWakeLock is held at this point 1354 EventLogTags.writeDeviceIdleOffStart("unknown"); 1355 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false); 1356 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false); 1357 try { 1358 mNetworkPolicyManager.setDeviceIdleMode(false); 1359 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF, 1360 null, Process.myUid()); 1361 } catch (RemoteException e) { 1362 } 1363 if (deepChanged) { 1364 incActiveIdleOps(); 1365 getContext().sendOrderedBroadcastAsUser(mIdleIntent, UserHandle.ALL, 1366 null, mIdleStartedDoneReceiver, null, 0, null, null); 1367 } 1368 if (lightChanged) { 1369 incActiveIdleOps(); 1370 getContext().sendOrderedBroadcastAsUser(mLightIdleIntent, UserHandle.ALL, 1371 null, mIdleStartedDoneReceiver, null, 0, null, null); 1372 } 1373 // Always start with one active op for the message being sent here. 1374 // Now we are done! 1375 decActiveIdleOps(); 1376 EventLogTags.writeDeviceIdleOffComplete(); 1377 } break; 1378 case MSG_REPORT_ACTIVE: { 1379 // The device is awake at this point, so no wakelock necessary. 1380 String activeReason = (String)msg.obj; 1381 int activeUid = msg.arg1; 1382 EventLogTags.writeDeviceIdleOffStart( 1383 activeReason != null ? activeReason : "unknown"); 1384 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false); 1385 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false); 1386 try { 1387 mNetworkPolicyManager.setDeviceIdleMode(false); 1388 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF, 1389 activeReason, activeUid); 1390 } catch (RemoteException e) { 1391 } 1392 if (deepChanged) { 1393 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL); 1394 } 1395 if (lightChanged) { 1396 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL); 1397 } 1398 EventLogTags.writeDeviceIdleOffComplete(); 1399 } break; 1400 case MSG_TEMP_APP_WHITELIST_TIMEOUT: { 1401 // TODO: What is keeping the device awake at this point? Does it need to be? 1402 int appId = msg.arg1; 1403 checkTempAppWhitelistTimeout(appId); 1404 } break; 1405 case MSG_REPORT_MAINTENANCE_ACTIVITY: { 1406 // TODO: What is keeping the device awake at this point? Does it need to be? 1407 boolean active = (msg.arg1 == 1); 1408 final int size = mMaintenanceActivityListeners.beginBroadcast(); 1409 try { 1410 for (int i = 0; i < size; i++) { 1411 try { 1412 mMaintenanceActivityListeners.getBroadcastItem(i) 1413 .onMaintenanceActivityChanged(active); 1414 } catch (RemoteException ignored) { 1415 } 1416 } 1417 } finally { 1418 mMaintenanceActivityListeners.finishBroadcast(); 1419 } 1420 } break; 1421 case MSG_FINISH_IDLE_OP: { 1422 // mActiveIdleWakeLock is held at this point 1423 decActiveIdleOps(); 1424 } break; 1425 case MSG_REPORT_TEMP_APP_WHITELIST_CHANGED: { 1426 final int appId = msg.arg1; 1427 final boolean added = (msg.arg2 == 1); 1428 mNetworkPolicyManagerInternal.onTempPowerSaveWhitelistChange(appId, added); 1429 } break; 1430 case MSG_SEND_CONSTRAINT_MONITORING: { 1431 final IDeviceIdleConstraint constraint = (IDeviceIdleConstraint) msg.obj; 1432 final boolean monitoring = (msg.arg1 == 1); 1433 if (monitoring) { 1434 constraint.startMonitoring(); 1435 } else { 1436 constraint.stopMonitoring(); 1437 } 1438 } break; 1439 case MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR: { 1440 updatePreIdleFactor(); 1441 } break; 1442 case MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR: { 1443 updatePreIdleFactor(); 1444 maybeDoImmediateMaintenance(); 1445 } break; 1446 } 1447 } 1448 } 1449 1450 final MyHandler mHandler; 1451 1452 BinderService mBinderService; 1453 1454 private final class BinderService extends IDeviceIdleController.Stub { addPowerSaveWhitelistApp(String name)1455 @Override public void addPowerSaveWhitelistApp(String name) { 1456 if (DEBUG) { 1457 Slog.i(TAG, "addPowerSaveWhitelistApp(name = " + name + ")"); 1458 } 1459 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 1460 null); 1461 long ident = Binder.clearCallingIdentity(); 1462 try { 1463 addPowerSaveWhitelistAppInternal(name); 1464 } finally { 1465 Binder.restoreCallingIdentity(ident); 1466 } 1467 } 1468 removePowerSaveWhitelistApp(String name)1469 @Override public void removePowerSaveWhitelistApp(String name) { 1470 if (DEBUG) { 1471 Slog.i(TAG, "removePowerSaveWhitelistApp(name = " + name + ")"); 1472 } 1473 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 1474 null); 1475 long ident = Binder.clearCallingIdentity(); 1476 try { 1477 removePowerSaveWhitelistAppInternal(name); 1478 } finally { 1479 Binder.restoreCallingIdentity(ident); 1480 } 1481 } 1482 removeSystemPowerWhitelistApp(String name)1483 @Override public void removeSystemPowerWhitelistApp(String name) { 1484 if (DEBUG) { 1485 Slog.d(TAG, "removeAppFromSystemWhitelist(name = " + name + ")"); 1486 } 1487 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 1488 null); 1489 long ident = Binder.clearCallingIdentity(); 1490 try { 1491 removeSystemPowerWhitelistAppInternal(name); 1492 } finally { 1493 Binder.restoreCallingIdentity(ident); 1494 } 1495 } 1496 restoreSystemPowerWhitelistApp(String name)1497 @Override public void restoreSystemPowerWhitelistApp(String name) { 1498 if (DEBUG) { 1499 Slog.d(TAG, "restoreAppToSystemWhitelist(name = " + name + ")"); 1500 } 1501 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 1502 null); 1503 long ident = Binder.clearCallingIdentity(); 1504 try { 1505 restoreSystemPowerWhitelistAppInternal(name); 1506 } finally { 1507 Binder.restoreCallingIdentity(ident); 1508 } 1509 } 1510 getRemovedSystemPowerWhitelistApps()1511 public String[] getRemovedSystemPowerWhitelistApps() { 1512 return getRemovedSystemPowerWhitelistAppsInternal(); 1513 } 1514 getSystemPowerWhitelistExceptIdle()1515 @Override public String[] getSystemPowerWhitelistExceptIdle() { 1516 return getSystemPowerWhitelistExceptIdleInternal(); 1517 } 1518 getSystemPowerWhitelist()1519 @Override public String[] getSystemPowerWhitelist() { 1520 return getSystemPowerWhitelistInternal(); 1521 } 1522 getUserPowerWhitelist()1523 @Override public String[] getUserPowerWhitelist() { 1524 return getUserPowerWhitelistInternal(); 1525 } 1526 getFullPowerWhitelistExceptIdle()1527 @Override public String[] getFullPowerWhitelistExceptIdle() { 1528 return getFullPowerWhitelistExceptIdleInternal(); 1529 } 1530 getFullPowerWhitelist()1531 @Override public String[] getFullPowerWhitelist() { 1532 return getFullPowerWhitelistInternal(); 1533 } 1534 getAppIdWhitelistExceptIdle()1535 @Override public int[] getAppIdWhitelistExceptIdle() { 1536 return getAppIdWhitelistExceptIdleInternal(); 1537 } 1538 getAppIdWhitelist()1539 @Override public int[] getAppIdWhitelist() { 1540 return getAppIdWhitelistInternal(); 1541 } 1542 getAppIdUserWhitelist()1543 @Override public int[] getAppIdUserWhitelist() { 1544 return getAppIdUserWhitelistInternal(); 1545 } 1546 getAppIdTempWhitelist()1547 @Override public int[] getAppIdTempWhitelist() { 1548 return getAppIdTempWhitelistInternal(); 1549 } 1550 isPowerSaveWhitelistExceptIdleApp(String name)1551 @Override public boolean isPowerSaveWhitelistExceptIdleApp(String name) { 1552 return isPowerSaveWhitelistExceptIdleAppInternal(name); 1553 } 1554 isPowerSaveWhitelistApp(String name)1555 @Override public boolean isPowerSaveWhitelistApp(String name) { 1556 return isPowerSaveWhitelistAppInternal(name); 1557 } 1558 addPowerSaveTempWhitelistApp(String packageName, long duration, int userId, String reason)1559 @Override public void addPowerSaveTempWhitelistApp(String packageName, long duration, 1560 int userId, String reason) throws RemoteException { 1561 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason); 1562 } 1563 addPowerSaveTempWhitelistAppForMms(String packageName, int userId, String reason)1564 @Override public long addPowerSaveTempWhitelistAppForMms(String packageName, 1565 int userId, String reason) throws RemoteException { 1566 long duration = mConstants.MMS_TEMP_APP_WHITELIST_DURATION; 1567 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason); 1568 return duration; 1569 } 1570 addPowerSaveTempWhitelistAppForSms(String packageName, int userId, String reason)1571 @Override public long addPowerSaveTempWhitelistAppForSms(String packageName, 1572 int userId, String reason) throws RemoteException { 1573 long duration = mConstants.SMS_TEMP_APP_WHITELIST_DURATION; 1574 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason); 1575 return duration; 1576 } 1577 exitIdle(String reason)1578 @Override public void exitIdle(String reason) { 1579 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER, 1580 null); 1581 long ident = Binder.clearCallingIdentity(); 1582 try { 1583 exitIdleInternal(reason); 1584 } finally { 1585 Binder.restoreCallingIdentity(ident); 1586 } 1587 } 1588 registerMaintenanceActivityListener( IMaintenanceActivityListener listener)1589 @Override public boolean registerMaintenanceActivityListener( 1590 IMaintenanceActivityListener listener) { 1591 return DeviceIdleController.this.registerMaintenanceActivityListener(listener); 1592 } 1593 unregisterMaintenanceActivityListener( IMaintenanceActivityListener listener)1594 @Override public void unregisterMaintenanceActivityListener( 1595 IMaintenanceActivityListener listener) { 1596 DeviceIdleController.this.unregisterMaintenanceActivityListener(listener); 1597 } 1598 setPreIdleTimeoutMode(int mode)1599 @Override public int setPreIdleTimeoutMode(int mode) { 1600 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER, 1601 null); 1602 long ident = Binder.clearCallingIdentity(); 1603 try { 1604 return DeviceIdleController.this.setPreIdleTimeoutMode(mode); 1605 } finally { 1606 Binder.restoreCallingIdentity(ident); 1607 } 1608 } 1609 resetPreIdleTimeoutMode()1610 @Override public void resetPreIdleTimeoutMode() { 1611 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER, 1612 null); 1613 long ident = Binder.clearCallingIdentity(); 1614 try { 1615 DeviceIdleController.this.resetPreIdleTimeoutMode(); 1616 } finally { 1617 Binder.restoreCallingIdentity(ident); 1618 } 1619 } 1620 dump(FileDescriptor fd, PrintWriter pw, String[] args)1621 @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1622 DeviceIdleController.this.dump(fd, pw, args); 1623 } 1624 onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)1625 @Override public void onShellCommand(FileDescriptor in, FileDescriptor out, 1626 FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) { 1627 (new Shell()).exec(this, in, out, err, args, callback, resultReceiver); 1628 } 1629 } 1630 1631 public class LocalService { onConstraintStateChanged(IDeviceIdleConstraint constraint, boolean active)1632 public void onConstraintStateChanged(IDeviceIdleConstraint constraint, boolean active) { 1633 synchronized (DeviceIdleController.this) { 1634 onConstraintStateChangedLocked(constraint, active); 1635 } 1636 } 1637 registerDeviceIdleConstraint(IDeviceIdleConstraint constraint, String name, @IDeviceIdleConstraint.MinimumState int minState)1638 public void registerDeviceIdleConstraint(IDeviceIdleConstraint constraint, String name, 1639 @IDeviceIdleConstraint.MinimumState int minState) { 1640 registerDeviceIdleConstraintInternal(constraint, name, minState); 1641 } 1642 unregisterDeviceIdleConstraint(IDeviceIdleConstraint constraint)1643 public void unregisterDeviceIdleConstraint(IDeviceIdleConstraint constraint) { 1644 unregisterDeviceIdleConstraintInternal(constraint); 1645 } 1646 exitIdle(String reason)1647 public void exitIdle(String reason) { 1648 exitIdleInternal(reason); 1649 } 1650 1651 // duration in milliseconds addPowerSaveTempWhitelistApp(int callingUid, String packageName, long duration, int userId, boolean sync, String reason)1652 public void addPowerSaveTempWhitelistApp(int callingUid, String packageName, 1653 long duration, int userId, boolean sync, String reason) { 1654 addPowerSaveTempWhitelistAppInternal(callingUid, packageName, duration, 1655 userId, sync, reason); 1656 } 1657 1658 // duration in milliseconds addPowerSaveTempWhitelistAppDirect(int uid, long duration, boolean sync, String reason)1659 public void addPowerSaveTempWhitelistAppDirect(int uid, long duration, boolean sync, 1660 String reason) { 1661 addPowerSaveTempWhitelistAppDirectInternal(0, uid, duration, sync, reason); 1662 } 1663 1664 // duration in milliseconds getNotificationWhitelistDuration()1665 public long getNotificationWhitelistDuration() { 1666 return mConstants.NOTIFICATION_WHITELIST_DURATION; 1667 } 1668 setJobsActive(boolean active)1669 public void setJobsActive(boolean active) { 1670 DeviceIdleController.this.setJobsActive(active); 1671 } 1672 1673 // Up-call from alarm manager. setAlarmsActive(boolean active)1674 public void setAlarmsActive(boolean active) { 1675 DeviceIdleController.this.setAlarmsActive(active); 1676 } 1677 1678 /** Is the app on any of the power save whitelists, whether system or user? */ isAppOnWhitelist(int appid)1679 public boolean isAppOnWhitelist(int appid) { 1680 return DeviceIdleController.this.isAppOnWhitelistInternal(appid); 1681 } 1682 1683 /** 1684 * Returns the array of app ids whitelisted by user. Take care not to 1685 * modify this, as it is a reference to the original copy. But the reference 1686 * can change when the list changes, so it needs to be re-acquired when 1687 * {@link PowerManager#ACTION_POWER_SAVE_WHITELIST_CHANGED} is sent. 1688 */ getPowerSaveWhitelistUserAppIds()1689 public int[] getPowerSaveWhitelistUserAppIds() { 1690 return DeviceIdleController.this.getPowerSaveWhitelistUserAppIds(); 1691 } 1692 getPowerSaveTempWhitelistAppIds()1693 public int[] getPowerSaveTempWhitelistAppIds() { 1694 return DeviceIdleController.this.getAppIdTempWhitelistInternal(); 1695 } 1696 } 1697 1698 static class Injector { 1699 private final Context mContext; 1700 private ConnectivityService mConnectivityService; 1701 private Constants mConstants; 1702 private LocationManager mLocationManager; 1703 Injector(Context ctx)1704 Injector(Context ctx) { 1705 mContext = ctx; 1706 } 1707 getAlarmManager()1708 AlarmManager getAlarmManager() { 1709 return mContext.getSystemService(AlarmManager.class); 1710 } 1711 getAnyMotionDetector(Handler handler, SensorManager sm, AnyMotionDetector.DeviceIdleCallback callback, float angleThreshold)1712 AnyMotionDetector getAnyMotionDetector(Handler handler, SensorManager sm, 1713 AnyMotionDetector.DeviceIdleCallback callback, float angleThreshold) { 1714 return new AnyMotionDetector(getPowerManager(), handler, sm, callback, angleThreshold); 1715 } 1716 getAppStateTracker(Context ctx, Looper looper)1717 AppStateTracker getAppStateTracker(Context ctx, Looper looper) { 1718 return new AppStateTracker(ctx, looper); 1719 } 1720 getConnectivityService()1721 ConnectivityService getConnectivityService() { 1722 if (mConnectivityService == null) { 1723 mConnectivityService = (ConnectivityService) ServiceManager.getService( 1724 Context.CONNECTIVITY_SERVICE); 1725 } 1726 return mConnectivityService; 1727 } 1728 getConstants(DeviceIdleController controller, Handler handler, ContentResolver resolver)1729 Constants getConstants(DeviceIdleController controller, Handler handler, 1730 ContentResolver resolver) { 1731 if (mConstants == null) { 1732 mConstants = controller.new Constants(handler, resolver); 1733 } 1734 return mConstants; 1735 } 1736 getLocationManager()1737 LocationManager getLocationManager() { 1738 if (mLocationManager == null) { 1739 mLocationManager = mContext.getSystemService(LocationManager.class); 1740 } 1741 return mLocationManager; 1742 } 1743 getHandler(DeviceIdleController controller)1744 MyHandler getHandler(DeviceIdleController controller) { 1745 return controller.new MyHandler(BackgroundThread.getHandler().getLooper()); 1746 } 1747 getPowerManager()1748 PowerManager getPowerManager() { 1749 return mContext.getSystemService(PowerManager.class); 1750 } 1751 getSensorManager()1752 SensorManager getSensorManager() { 1753 return mContext.getSystemService(SensorManager.class); 1754 } 1755 getConstraintController(Handler handler, LocalService localService)1756 ConstraintController getConstraintController(Handler handler, LocalService localService) { 1757 if (mContext.getPackageManager() 1758 .hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY)) { 1759 return new TvConstraintController(mContext, handler); 1760 } 1761 return null; 1762 } 1763 useMotionSensor()1764 boolean useMotionSensor() { 1765 return mContext.getResources().getBoolean( 1766 com.android.internal.R.bool.config_autoPowerModeUseMotionSensor); 1767 } 1768 } 1769 1770 private final Injector mInjector; 1771 1772 private ActivityTaskManagerInternal.ScreenObserver mScreenObserver = 1773 new ActivityTaskManagerInternal.ScreenObserver() { 1774 @Override 1775 public void onAwakeStateChanged(boolean isAwake) { } 1776 1777 @Override 1778 public void onKeyguardStateChanged(boolean isShowing) { 1779 synchronized (DeviceIdleController.this) { 1780 DeviceIdleController.this.keyguardShowingLocked(isShowing); 1781 } 1782 } 1783 }; 1784 DeviceIdleController(Context context, Injector injector)1785 @VisibleForTesting DeviceIdleController(Context context, Injector injector) { 1786 super(context); 1787 mInjector = injector; 1788 mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml")); 1789 mHandler = mInjector.getHandler(this); 1790 mAppStateTracker = mInjector.getAppStateTracker(context, FgThread.get().getLooper()); 1791 LocalServices.addService(AppStateTracker.class, mAppStateTracker); 1792 mUseMotionSensor = mInjector.useMotionSensor(); 1793 } 1794 DeviceIdleController(Context context)1795 public DeviceIdleController(Context context) { 1796 this(context, new Injector(context)); 1797 } 1798 isAppOnWhitelistInternal(int appid)1799 boolean isAppOnWhitelistInternal(int appid) { 1800 synchronized (this) { 1801 return Arrays.binarySearch(mPowerSaveWhitelistAllAppIdArray, appid) >= 0; 1802 } 1803 } 1804 getPowerSaveWhitelistUserAppIds()1805 int[] getPowerSaveWhitelistUserAppIds() { 1806 synchronized (this) { 1807 return mPowerSaveWhitelistUserAppIdArray; 1808 } 1809 } 1810 getSystemDir()1811 private static File getSystemDir() { 1812 return new File(Environment.getDataDirectory(), "system"); 1813 } 1814 1815 @Override onStart()1816 public void onStart() { 1817 final PackageManager pm = getContext().getPackageManager(); 1818 1819 synchronized (this) { 1820 mLightEnabled = mDeepEnabled = getContext().getResources().getBoolean( 1821 com.android.internal.R.bool.config_enableAutoPowerModes); 1822 SystemConfig sysConfig = SystemConfig.getInstance(); 1823 ArraySet<String> allowPowerExceptIdle = sysConfig.getAllowInPowerSaveExceptIdle(); 1824 for (int i=0; i<allowPowerExceptIdle.size(); i++) { 1825 String pkg = allowPowerExceptIdle.valueAt(i); 1826 try { 1827 ApplicationInfo ai = pm.getApplicationInfo(pkg, 1828 PackageManager.MATCH_SYSTEM_ONLY); 1829 int appid = UserHandle.getAppId(ai.uid); 1830 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid); 1831 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true); 1832 } catch (PackageManager.NameNotFoundException e) { 1833 } 1834 } 1835 ArraySet<String> allowPower = sysConfig.getAllowInPowerSave(); 1836 for (int i=0; i<allowPower.size(); i++) { 1837 String pkg = allowPower.valueAt(i); 1838 try { 1839 ApplicationInfo ai = pm.getApplicationInfo(pkg, 1840 PackageManager.MATCH_SYSTEM_ONLY); 1841 int appid = UserHandle.getAppId(ai.uid); 1842 // These apps are on both the whitelist-except-idle as well 1843 // as the full whitelist, so they apply in all cases. 1844 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid); 1845 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true); 1846 mPowerSaveWhitelistApps.put(ai.packageName, appid); 1847 mPowerSaveWhitelistSystemAppIds.put(appid, true); 1848 } catch (PackageManager.NameNotFoundException e) { 1849 } 1850 } 1851 1852 mConstants = mInjector.getConstants(this, mHandler, getContext().getContentResolver()); 1853 1854 readConfigFileLocked(); 1855 updateWhitelistAppIdsLocked(); 1856 1857 mNetworkConnected = true; 1858 mScreenOn = true; 1859 mScreenLocked = false; 1860 // Start out assuming we are charging. If we aren't, we will at least get 1861 // a battery update the next time the level drops. 1862 mCharging = true; 1863 mActiveReason = ACTIVE_REASON_UNKNOWN; 1864 mState = STATE_ACTIVE; 1865 mLightState = LIGHT_STATE_ACTIVE; 1866 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT; 1867 mPreIdleFactor = 1.0f; 1868 mLastPreIdleFactor = 1.0f; 1869 } 1870 1871 mBinderService = new BinderService(); 1872 publishBinderService(Context.DEVICE_IDLE_CONTROLLER, mBinderService); 1873 publishLocalService(LocalService.class, new LocalService()); 1874 } 1875 1876 @Override onBootPhase(int phase)1877 public void onBootPhase(int phase) { 1878 if (phase == PHASE_SYSTEM_SERVICES_READY) { 1879 synchronized (this) { 1880 mAlarmManager = mInjector.getAlarmManager(); 1881 mLocalAlarmManager = getLocalService(AlarmManagerInternal.class); 1882 mBatteryStats = BatteryStatsService.getService(); 1883 mLocalActivityManager = getLocalService(ActivityManagerInternal.class); 1884 mLocalActivityTaskManager = getLocalService(ActivityTaskManagerInternal.class); 1885 mLocalPowerManager = getLocalService(PowerManagerInternal.class); 1886 mPowerManager = mInjector.getPowerManager(); 1887 mActiveIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 1888 "deviceidle_maint"); 1889 mActiveIdleWakeLock.setReferenceCounted(false); 1890 mGoingIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 1891 "deviceidle_going_idle"); 1892 mGoingIdleWakeLock.setReferenceCounted(true); 1893 mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface( 1894 ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)); 1895 mNetworkPolicyManagerInternal = getLocalService(NetworkPolicyManagerInternal.class); 1896 mSensorManager = mInjector.getSensorManager(); 1897 1898 if (mUseMotionSensor) { 1899 int sigMotionSensorId = getContext().getResources().getInteger( 1900 com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor); 1901 if (sigMotionSensorId > 0) { 1902 mMotionSensor = mSensorManager.getDefaultSensor(sigMotionSensorId, true); 1903 } 1904 if (mMotionSensor == null && getContext().getResources().getBoolean( 1905 com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) { 1906 mMotionSensor = mSensorManager.getDefaultSensor( 1907 Sensor.TYPE_WRIST_TILT_GESTURE, true); 1908 } 1909 if (mMotionSensor == null) { 1910 // As a last ditch, fall back to SMD. 1911 mMotionSensor = mSensorManager.getDefaultSensor( 1912 Sensor.TYPE_SIGNIFICANT_MOTION, true); 1913 } 1914 } 1915 1916 if (getContext().getResources().getBoolean( 1917 com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) { 1918 mLocationRequest = new LocationRequest() 1919 .setQuality(LocationRequest.ACCURACY_FINE) 1920 .setInterval(0) 1921 .setFastestInterval(0) 1922 .setNumUpdates(1); 1923 } 1924 1925 mConstraintController = mInjector.getConstraintController( 1926 mHandler, getLocalService(LocalService.class)); 1927 if (mConstraintController != null) { 1928 mConstraintController.start(); 1929 } 1930 1931 float angleThreshold = getContext().getResources().getInteger( 1932 com.android.internal.R.integer.config_autoPowerModeThresholdAngle) / 100f; 1933 mAnyMotionDetector = mInjector.getAnyMotionDetector(mHandler, mSensorManager, this, 1934 angleThreshold); 1935 1936 mAppStateTracker.onSystemServicesReady(); 1937 1938 mIdleIntent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); 1939 mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1940 | Intent.FLAG_RECEIVER_FOREGROUND); 1941 mLightIdleIntent = new Intent(PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED); 1942 mLightIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1943 | Intent.FLAG_RECEIVER_FOREGROUND); 1944 1945 IntentFilter filter = new IntentFilter(); 1946 filter.addAction(Intent.ACTION_BATTERY_CHANGED); 1947 getContext().registerReceiver(mReceiver, filter); 1948 1949 filter = new IntentFilter(); 1950 filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 1951 filter.addDataScheme("package"); 1952 getContext().registerReceiver(mReceiver, filter); 1953 1954 filter = new IntentFilter(); 1955 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 1956 getContext().registerReceiver(mReceiver, filter); 1957 1958 filter = new IntentFilter(); 1959 filter.addAction(Intent.ACTION_SCREEN_OFF); 1960 filter.addAction(Intent.ACTION_SCREEN_ON); 1961 getContext().registerReceiver(mInteractivityReceiver, filter); 1962 1963 mLocalActivityManager.setDeviceIdleWhitelist( 1964 mPowerSaveWhitelistAllAppIdArray, mPowerSaveWhitelistExceptIdleAppIdArray); 1965 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); 1966 1967 mLocalPowerManager.registerLowPowerModeObserver(ServiceType.QUICK_DOZE, 1968 state -> { 1969 synchronized (DeviceIdleController.this) { 1970 updateQuickDozeFlagLocked(state.batterySaverEnabled); 1971 } 1972 }); 1973 updateQuickDozeFlagLocked( 1974 mLocalPowerManager.getLowPowerState( 1975 ServiceType.QUICK_DOZE).batterySaverEnabled); 1976 1977 mLocalActivityTaskManager.registerScreenObserver(mScreenObserver); 1978 1979 passWhiteListsToForceAppStandbyTrackerLocked(); 1980 updateInteractivityLocked(); 1981 } 1982 updateConnectivityState(null); 1983 } 1984 } 1985 1986 @VisibleForTesting hasMotionSensor()1987 boolean hasMotionSensor() { 1988 return mUseMotionSensor && mMotionSensor != null; 1989 } 1990 registerDeviceIdleConstraintInternal(IDeviceIdleConstraint constraint, final String name, final int type)1991 private void registerDeviceIdleConstraintInternal(IDeviceIdleConstraint constraint, 1992 final String name, final int type) { 1993 final int minState; 1994 switch (type) { 1995 case IDeviceIdleConstraint.ACTIVE: 1996 minState = STATE_ACTIVE; 1997 break; 1998 case IDeviceIdleConstraint.SENSING_OR_ABOVE: 1999 minState = STATE_SENSING; 2000 break; 2001 default: 2002 Slog.wtf(TAG, "Registering device-idle constraint with invalid type: " + type); 2003 return; 2004 } 2005 synchronized (this) { 2006 if (mConstraints.containsKey(constraint)) { 2007 Slog.e(TAG, "Re-registering device-idle constraint: " + constraint + "."); 2008 return; 2009 } 2010 DeviceIdleConstraintTracker tracker = new DeviceIdleConstraintTracker(name, minState); 2011 mConstraints.put(constraint, tracker); 2012 updateActiveConstraintsLocked(); 2013 } 2014 } 2015 unregisterDeviceIdleConstraintInternal(IDeviceIdleConstraint constraint)2016 private void unregisterDeviceIdleConstraintInternal(IDeviceIdleConstraint constraint) { 2017 synchronized (this) { 2018 // Artifically force the constraint to inactive to unblock anything waiting for it. 2019 onConstraintStateChangedLocked(constraint, /* active= */ false); 2020 2021 // Let the constraint know that we are not listening to it any more. 2022 setConstraintMonitoringLocked(constraint, /* monitoring= */ false); 2023 mConstraints.remove(constraint); 2024 } 2025 } 2026 2027 @GuardedBy("this") onConstraintStateChangedLocked(IDeviceIdleConstraint constraint, boolean active)2028 private void onConstraintStateChangedLocked(IDeviceIdleConstraint constraint, boolean active) { 2029 DeviceIdleConstraintTracker tracker = mConstraints.get(constraint); 2030 if (tracker == null) { 2031 Slog.e(TAG, "device-idle constraint " + constraint + " has not been registered."); 2032 return; 2033 } 2034 if (active != tracker.active && tracker.monitoring) { 2035 tracker.active = active; 2036 mNumBlockingConstraints += (tracker.active ? +1 : -1); 2037 if (mNumBlockingConstraints == 0) { 2038 if (mState == STATE_ACTIVE) { 2039 becomeInactiveIfAppropriateLocked(); 2040 } else if (mNextAlarmTime == 0 || mNextAlarmTime < SystemClock.elapsedRealtime()) { 2041 stepIdleStateLocked("s:" + tracker.name); 2042 } 2043 } 2044 } 2045 } 2046 2047 @GuardedBy("this") setConstraintMonitoringLocked(IDeviceIdleConstraint constraint, boolean monitor)2048 private void setConstraintMonitoringLocked(IDeviceIdleConstraint constraint, boolean monitor) { 2049 DeviceIdleConstraintTracker tracker = mConstraints.get(constraint); 2050 if (tracker.monitoring != monitor) { 2051 tracker.monitoring = monitor; 2052 updateActiveConstraintsLocked(); 2053 // We send the callback on a separate thread instead of just relying on oneway as 2054 // the client could be in the system server with us and cause re-entry problems. 2055 mHandler.obtainMessage(MSG_SEND_CONSTRAINT_MONITORING, 2056 /* monitoring= */ monitor ? 1 : 0, 2057 /* <not used>= */ -1, 2058 /* constraint= */ constraint).sendToTarget(); 2059 } 2060 } 2061 2062 @GuardedBy("this") updateActiveConstraintsLocked()2063 private void updateActiveConstraintsLocked() { 2064 mNumBlockingConstraints = 0; 2065 for (int i = 0; i < mConstraints.size(); i++) { 2066 final IDeviceIdleConstraint constraint = mConstraints.keyAt(i); 2067 final DeviceIdleConstraintTracker tracker = mConstraints.valueAt(i); 2068 final boolean monitoring = (tracker.minState == mState); 2069 if (monitoring != tracker.monitoring) { 2070 setConstraintMonitoringLocked(constraint, monitoring); 2071 tracker.active = monitoring; 2072 } 2073 if (tracker.monitoring && tracker.active) { 2074 mNumBlockingConstraints++; 2075 } 2076 } 2077 } 2078 addPowerSaveWhitelistAppInternal(String name)2079 public boolean addPowerSaveWhitelistAppInternal(String name) { 2080 synchronized (this) { 2081 try { 2082 ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name, 2083 PackageManager.MATCH_ANY_USER); 2084 if (mPowerSaveWhitelistUserApps.put(name, UserHandle.getAppId(ai.uid)) == null) { 2085 reportPowerSaveWhitelistChangedLocked(); 2086 updateWhitelistAppIdsLocked(); 2087 writeConfigFileLocked(); 2088 } 2089 return true; 2090 } catch (PackageManager.NameNotFoundException e) { 2091 return false; 2092 } 2093 } 2094 } 2095 removePowerSaveWhitelistAppInternal(String name)2096 public boolean removePowerSaveWhitelistAppInternal(String name) { 2097 synchronized (this) { 2098 if (mPowerSaveWhitelistUserApps.remove(name) != null) { 2099 reportPowerSaveWhitelistChangedLocked(); 2100 updateWhitelistAppIdsLocked(); 2101 writeConfigFileLocked(); 2102 return true; 2103 } 2104 } 2105 return false; 2106 } 2107 getPowerSaveWhitelistAppInternal(String name)2108 public boolean getPowerSaveWhitelistAppInternal(String name) { 2109 synchronized (this) { 2110 return mPowerSaveWhitelistUserApps.containsKey(name); 2111 } 2112 } 2113 resetSystemPowerWhitelistInternal()2114 void resetSystemPowerWhitelistInternal() { 2115 synchronized (this) { 2116 mPowerSaveWhitelistApps.putAll(mRemovedFromSystemWhitelistApps); 2117 mRemovedFromSystemWhitelistApps.clear(); 2118 reportPowerSaveWhitelistChangedLocked(); 2119 updateWhitelistAppIdsLocked(); 2120 writeConfigFileLocked(); 2121 } 2122 } 2123 restoreSystemPowerWhitelistAppInternal(String name)2124 public boolean restoreSystemPowerWhitelistAppInternal(String name) { 2125 synchronized (this) { 2126 if (!mRemovedFromSystemWhitelistApps.containsKey(name)) { 2127 return false; 2128 } 2129 mPowerSaveWhitelistApps.put(name, mRemovedFromSystemWhitelistApps.remove(name)); 2130 reportPowerSaveWhitelistChangedLocked(); 2131 updateWhitelistAppIdsLocked(); 2132 writeConfigFileLocked(); 2133 return true; 2134 } 2135 } 2136 removeSystemPowerWhitelistAppInternal(String name)2137 public boolean removeSystemPowerWhitelistAppInternal(String name) { 2138 synchronized (this) { 2139 if (!mPowerSaveWhitelistApps.containsKey(name)) { 2140 return false; 2141 } 2142 mRemovedFromSystemWhitelistApps.put(name, mPowerSaveWhitelistApps.remove(name)); 2143 reportPowerSaveWhitelistChangedLocked(); 2144 updateWhitelistAppIdsLocked(); 2145 writeConfigFileLocked(); 2146 return true; 2147 } 2148 } 2149 addPowerSaveWhitelistExceptIdleInternal(String name)2150 public boolean addPowerSaveWhitelistExceptIdleInternal(String name) { 2151 synchronized (this) { 2152 try { 2153 final ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name, 2154 PackageManager.MATCH_ANY_USER); 2155 if (mPowerSaveWhitelistAppsExceptIdle.put(name, UserHandle.getAppId(ai.uid)) 2156 == null) { 2157 mPowerSaveWhitelistUserAppsExceptIdle.add(name); 2158 reportPowerSaveWhitelistChangedLocked(); 2159 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray( 2160 mPowerSaveWhitelistAppsExceptIdle, mPowerSaveWhitelistUserApps, 2161 mPowerSaveWhitelistExceptIdleAppIds); 2162 2163 passWhiteListsToForceAppStandbyTrackerLocked(); 2164 } 2165 return true; 2166 } catch (PackageManager.NameNotFoundException e) { 2167 return false; 2168 } 2169 } 2170 } 2171 resetPowerSaveWhitelistExceptIdleInternal()2172 public void resetPowerSaveWhitelistExceptIdleInternal() { 2173 synchronized (this) { 2174 if (mPowerSaveWhitelistAppsExceptIdle.removeAll( 2175 mPowerSaveWhitelistUserAppsExceptIdle)) { 2176 reportPowerSaveWhitelistChangedLocked(); 2177 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray( 2178 mPowerSaveWhitelistAppsExceptIdle, mPowerSaveWhitelistUserApps, 2179 mPowerSaveWhitelistExceptIdleAppIds); 2180 mPowerSaveWhitelistUserAppsExceptIdle.clear(); 2181 2182 passWhiteListsToForceAppStandbyTrackerLocked(); 2183 } 2184 } 2185 } 2186 getPowerSaveWhitelistExceptIdleInternal(String name)2187 public boolean getPowerSaveWhitelistExceptIdleInternal(String name) { 2188 synchronized (this) { 2189 return mPowerSaveWhitelistAppsExceptIdle.containsKey(name); 2190 } 2191 } 2192 getSystemPowerWhitelistExceptIdleInternal()2193 public String[] getSystemPowerWhitelistExceptIdleInternal() { 2194 synchronized (this) { 2195 int size = mPowerSaveWhitelistAppsExceptIdle.size(); 2196 String[] apps = new String[size]; 2197 for (int i = 0; i < size; i++) { 2198 apps[i] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i); 2199 } 2200 return apps; 2201 } 2202 } 2203 getSystemPowerWhitelistInternal()2204 public String[] getSystemPowerWhitelistInternal() { 2205 synchronized (this) { 2206 int size = mPowerSaveWhitelistApps.size(); 2207 String[] apps = new String[size]; 2208 for (int i = 0; i < size; i++) { 2209 apps[i] = mPowerSaveWhitelistApps.keyAt(i); 2210 } 2211 return apps; 2212 } 2213 } 2214 getRemovedSystemPowerWhitelistAppsInternal()2215 public String[] getRemovedSystemPowerWhitelistAppsInternal() { 2216 synchronized (this) { 2217 int size = mRemovedFromSystemWhitelistApps.size(); 2218 final String[] apps = new String[size]; 2219 for (int i = 0; i < size; i++) { 2220 apps[i] = mRemovedFromSystemWhitelistApps.keyAt(i); 2221 } 2222 return apps; 2223 } 2224 } 2225 getUserPowerWhitelistInternal()2226 public String[] getUserPowerWhitelistInternal() { 2227 synchronized (this) { 2228 int size = mPowerSaveWhitelistUserApps.size(); 2229 String[] apps = new String[size]; 2230 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) { 2231 apps[i] = mPowerSaveWhitelistUserApps.keyAt(i); 2232 } 2233 return apps; 2234 } 2235 } 2236 getFullPowerWhitelistExceptIdleInternal()2237 public String[] getFullPowerWhitelistExceptIdleInternal() { 2238 synchronized (this) { 2239 int size = mPowerSaveWhitelistAppsExceptIdle.size() + mPowerSaveWhitelistUserApps.size(); 2240 String[] apps = new String[size]; 2241 int cur = 0; 2242 for (int i = 0; i < mPowerSaveWhitelistAppsExceptIdle.size(); i++) { 2243 apps[cur] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i); 2244 cur++; 2245 } 2246 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) { 2247 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i); 2248 cur++; 2249 } 2250 return apps; 2251 } 2252 } 2253 getFullPowerWhitelistInternal()2254 public String[] getFullPowerWhitelistInternal() { 2255 synchronized (this) { 2256 int size = mPowerSaveWhitelistApps.size() + mPowerSaveWhitelistUserApps.size(); 2257 String[] apps = new String[size]; 2258 int cur = 0; 2259 for (int i = 0; i < mPowerSaveWhitelistApps.size(); i++) { 2260 apps[cur] = mPowerSaveWhitelistApps.keyAt(i); 2261 cur++; 2262 } 2263 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) { 2264 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i); 2265 cur++; 2266 } 2267 return apps; 2268 } 2269 } 2270 isPowerSaveWhitelistExceptIdleAppInternal(String packageName)2271 public boolean isPowerSaveWhitelistExceptIdleAppInternal(String packageName) { 2272 synchronized (this) { 2273 return mPowerSaveWhitelistAppsExceptIdle.containsKey(packageName) 2274 || mPowerSaveWhitelistUserApps.containsKey(packageName); 2275 } 2276 } 2277 isPowerSaveWhitelistAppInternal(String packageName)2278 public boolean isPowerSaveWhitelistAppInternal(String packageName) { 2279 synchronized (this) { 2280 return mPowerSaveWhitelistApps.containsKey(packageName) 2281 || mPowerSaveWhitelistUserApps.containsKey(packageName); 2282 } 2283 } 2284 getAppIdWhitelistExceptIdleInternal()2285 public int[] getAppIdWhitelistExceptIdleInternal() { 2286 synchronized (this) { 2287 return mPowerSaveWhitelistExceptIdleAppIdArray; 2288 } 2289 } 2290 getAppIdWhitelistInternal()2291 public int[] getAppIdWhitelistInternal() { 2292 synchronized (this) { 2293 return mPowerSaveWhitelistAllAppIdArray; 2294 } 2295 } 2296 getAppIdUserWhitelistInternal()2297 public int[] getAppIdUserWhitelistInternal() { 2298 synchronized (this) { 2299 return mPowerSaveWhitelistUserAppIdArray; 2300 } 2301 } 2302 getAppIdTempWhitelistInternal()2303 public int[] getAppIdTempWhitelistInternal() { 2304 synchronized (this) { 2305 return mTempWhitelistAppIdArray; 2306 } 2307 } 2308 addPowerSaveTempWhitelistAppChecked(String packageName, long duration, int userId, String reason)2309 void addPowerSaveTempWhitelistAppChecked(String packageName, long duration, 2310 int userId, String reason) throws RemoteException { 2311 getContext().enforceCallingPermission( 2312 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, 2313 "No permission to change device idle whitelist"); 2314 final int callingUid = Binder.getCallingUid(); 2315 userId = ActivityManager.getService().handleIncomingUser( 2316 Binder.getCallingPid(), 2317 callingUid, 2318 userId, 2319 /*allowAll=*/ false, 2320 /*requireFull=*/ false, 2321 "addPowerSaveTempWhitelistApp", null); 2322 final long token = Binder.clearCallingIdentity(); 2323 try { 2324 addPowerSaveTempWhitelistAppInternal(callingUid, 2325 packageName, duration, userId, true, reason); 2326 } finally { 2327 Binder.restoreCallingIdentity(token); 2328 } 2329 } 2330 removePowerSaveTempWhitelistAppChecked(String packageName, int userId)2331 void removePowerSaveTempWhitelistAppChecked(String packageName, int userId) 2332 throws RemoteException { 2333 getContext().enforceCallingPermission( 2334 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, 2335 "No permission to change device idle whitelist"); 2336 final int callingUid = Binder.getCallingUid(); 2337 userId = ActivityManager.getService().handleIncomingUser( 2338 Binder.getCallingPid(), 2339 callingUid, 2340 userId, 2341 /*allowAll=*/ false, 2342 /*requireFull=*/ false, 2343 "removePowerSaveTempWhitelistApp", null); 2344 final long token = Binder.clearCallingIdentity(); 2345 try { 2346 removePowerSaveTempWhitelistAppInternal(packageName, userId); 2347 } finally { 2348 Binder.restoreCallingIdentity(token); 2349 } 2350 } 2351 2352 /** 2353 * Adds an app to the temporary whitelist and resets the endTime for granting the 2354 * app an exemption to access network and acquire wakelocks. 2355 */ addPowerSaveTempWhitelistAppInternal(int callingUid, String packageName, long duration, int userId, boolean sync, String reason)2356 void addPowerSaveTempWhitelistAppInternal(int callingUid, String packageName, 2357 long duration, int userId, boolean sync, String reason) { 2358 try { 2359 int uid = getContext().getPackageManager().getPackageUidAsUser(packageName, userId); 2360 addPowerSaveTempWhitelistAppDirectInternal(callingUid, uid, duration, sync, reason); 2361 } catch (NameNotFoundException e) { 2362 } 2363 } 2364 2365 /** 2366 * Adds an app to the temporary whitelist and resets the endTime for granting the 2367 * app an exemption to access network and acquire wakelocks. 2368 */ addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int uid, long duration, boolean sync, String reason)2369 void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int uid, 2370 long duration, boolean sync, String reason) { 2371 final long timeNow = SystemClock.elapsedRealtime(); 2372 boolean informWhitelistChanged = false; 2373 int appId = UserHandle.getAppId(uid); 2374 synchronized (this) { 2375 int callingAppId = UserHandle.getAppId(callingUid); 2376 if (callingAppId >= Process.FIRST_APPLICATION_UID) { 2377 if (!mPowerSaveWhitelistSystemAppIds.get(callingAppId)) { 2378 throw new SecurityException("Calling app " + UserHandle.formatUid(callingUid) 2379 + " is not on whitelist"); 2380 } 2381 } 2382 duration = Math.min(duration, mConstants.MAX_TEMP_APP_WHITELIST_DURATION); 2383 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId); 2384 final boolean newEntry = entry == null; 2385 // Set the new end time 2386 if (newEntry) { 2387 entry = new Pair<>(new MutableLong(0), reason); 2388 mTempWhitelistAppIdEndTimes.put(appId, entry); 2389 } 2390 entry.first.value = timeNow + duration; 2391 if (DEBUG) { 2392 Slog.d(TAG, "Adding AppId " + appId + " to temp whitelist. New entry: " + newEntry); 2393 } 2394 if (newEntry) { 2395 // No pending timeout for the app id, post a delayed message 2396 try { 2397 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_START, 2398 reason, uid); 2399 } catch (RemoteException e) { 2400 } 2401 postTempActiveTimeoutMessage(appId, duration); 2402 updateTempWhitelistAppIdsLocked(appId, true); 2403 if (sync) { 2404 informWhitelistChanged = true; 2405 } else { 2406 mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED, appId, 1) 2407 .sendToTarget(); 2408 } 2409 reportTempWhitelistChangedLocked(); 2410 } 2411 } 2412 if (informWhitelistChanged) { 2413 mNetworkPolicyManagerInternal.onTempPowerSaveWhitelistChange(appId, true); 2414 } 2415 } 2416 2417 /** 2418 * Removes an app from the temporary whitelist and notifies the observers. 2419 */ removePowerSaveTempWhitelistAppInternal(String packageName, int userId)2420 private void removePowerSaveTempWhitelistAppInternal(String packageName, int userId) { 2421 try { 2422 final int uid = getContext().getPackageManager().getPackageUidAsUser( 2423 packageName, userId); 2424 final int appId = UserHandle.getAppId(uid); 2425 removePowerSaveTempWhitelistAppDirectInternal(appId); 2426 } catch (NameNotFoundException e) { 2427 } 2428 } 2429 removePowerSaveTempWhitelistAppDirectInternal(int appId)2430 private void removePowerSaveTempWhitelistAppDirectInternal(int appId) { 2431 synchronized (this) { 2432 final int idx = mTempWhitelistAppIdEndTimes.indexOfKey(appId); 2433 if (idx < 0) { 2434 // Nothing else to do 2435 return; 2436 } 2437 final String reason = mTempWhitelistAppIdEndTimes.valueAt(idx).second; 2438 mTempWhitelistAppIdEndTimes.removeAt(idx); 2439 onAppRemovedFromTempWhitelistLocked(appId, reason); 2440 } 2441 } 2442 postTempActiveTimeoutMessage(int appId, long delay)2443 private void postTempActiveTimeoutMessage(int appId, long delay) { 2444 if (DEBUG) { 2445 Slog.d(TAG, "postTempActiveTimeoutMessage: appId=" + appId + ", delay=" + delay); 2446 } 2447 mHandler.sendMessageDelayed( 2448 mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, appId, 0), delay); 2449 } 2450 checkTempAppWhitelistTimeout(int appId)2451 void checkTempAppWhitelistTimeout(int appId) { 2452 final long timeNow = SystemClock.elapsedRealtime(); 2453 if (DEBUG) { 2454 Slog.d(TAG, "checkTempAppWhitelistTimeout: appId=" + appId + ", timeNow=" + timeNow); 2455 } 2456 synchronized (this) { 2457 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId); 2458 if (entry == null) { 2459 // Nothing to do 2460 return; 2461 } 2462 if (timeNow >= entry.first.value) { 2463 mTempWhitelistAppIdEndTimes.delete(appId); 2464 onAppRemovedFromTempWhitelistLocked(appId, entry.second); 2465 } else { 2466 // Need more time 2467 if (DEBUG) { 2468 Slog.d(TAG, "Time to remove AppId " + appId + ": " + entry.first.value); 2469 } 2470 postTempActiveTimeoutMessage(appId, entry.first.value - timeNow); 2471 } 2472 } 2473 } 2474 2475 @GuardedBy("this") onAppRemovedFromTempWhitelistLocked(int appId, String reason)2476 private void onAppRemovedFromTempWhitelistLocked(int appId, String reason) { 2477 if (DEBUG) { 2478 Slog.d(TAG, "Removing appId " + appId + " from temp whitelist"); 2479 } 2480 updateTempWhitelistAppIdsLocked(appId, false); 2481 mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED, appId, 0) 2482 .sendToTarget(); 2483 reportTempWhitelistChangedLocked(); 2484 try { 2485 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH, 2486 reason, appId); 2487 } catch (RemoteException e) { 2488 } 2489 } 2490 exitIdleInternal(String reason)2491 public void exitIdleInternal(String reason) { 2492 synchronized (this) { 2493 mActiveReason = ACTIVE_REASON_FROM_BINDER_CALL; 2494 becomeActiveLocked(reason, Binder.getCallingUid()); 2495 } 2496 } 2497 2498 @VisibleForTesting isNetworkConnected()2499 boolean isNetworkConnected() { 2500 synchronized (this) { 2501 return mNetworkConnected; 2502 } 2503 } 2504 updateConnectivityState(Intent connIntent)2505 void updateConnectivityState(Intent connIntent) { 2506 ConnectivityService cm; 2507 synchronized (this) { 2508 cm = mInjector.getConnectivityService(); 2509 } 2510 if (cm == null) { 2511 return; 2512 } 2513 // Note: can't call out to ConnectivityService with our lock held. 2514 NetworkInfo ni = cm.getActiveNetworkInfo(); 2515 synchronized (this) { 2516 boolean conn; 2517 if (ni == null) { 2518 conn = false; 2519 } else { 2520 if (connIntent == null) { 2521 conn = ni.isConnected(); 2522 } else { 2523 final int networkType = 2524 connIntent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 2525 ConnectivityManager.TYPE_NONE); 2526 if (ni.getType() != networkType) { 2527 return; 2528 } 2529 conn = !connIntent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, 2530 false); 2531 } 2532 } 2533 if (conn != mNetworkConnected) { 2534 mNetworkConnected = conn; 2535 if (conn && mLightState == LIGHT_STATE_WAITING_FOR_NETWORK) { 2536 stepLightIdleStateLocked("network"); 2537 } 2538 } 2539 } 2540 } 2541 2542 @VisibleForTesting isScreenOn()2543 boolean isScreenOn() { 2544 synchronized (this) { 2545 return mScreenOn; 2546 } 2547 } 2548 updateInteractivityLocked()2549 void updateInteractivityLocked() { 2550 // The interactivity state from the power manager tells us whether the display is 2551 // in a state that we need to keep things running so they will update at a normal 2552 // frequency. 2553 boolean screenOn = mPowerManager.isInteractive(); 2554 if (DEBUG) Slog.d(TAG, "updateInteractivityLocked: screenOn=" + screenOn); 2555 if (!screenOn && mScreenOn) { 2556 mScreenOn = false; 2557 if (!mForceIdle) { 2558 becomeInactiveIfAppropriateLocked(); 2559 } 2560 } else if (screenOn) { 2561 mScreenOn = true; 2562 if (!mForceIdle && (!mScreenLocked || !mConstants.WAIT_FOR_UNLOCK)) { 2563 mActiveReason = ACTIVE_REASON_SCREEN; 2564 becomeActiveLocked("screen", Process.myUid()); 2565 } 2566 } 2567 } 2568 2569 @VisibleForTesting isCharging()2570 boolean isCharging() { 2571 synchronized (this) { 2572 return mCharging; 2573 } 2574 } 2575 updateChargingLocked(boolean charging)2576 void updateChargingLocked(boolean charging) { 2577 if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging); 2578 if (!charging && mCharging) { 2579 mCharging = false; 2580 if (!mForceIdle) { 2581 becomeInactiveIfAppropriateLocked(); 2582 } 2583 } else if (charging) { 2584 mCharging = charging; 2585 if (!mForceIdle) { 2586 mActiveReason = ACTIVE_REASON_CHARGING; 2587 becomeActiveLocked("charging", Process.myUid()); 2588 } 2589 } 2590 } 2591 2592 @VisibleForTesting isQuickDozeEnabled()2593 boolean isQuickDozeEnabled() { 2594 synchronized (this) { 2595 return mQuickDozeActivated; 2596 } 2597 } 2598 2599 /** Updates the quick doze flag and enters deep doze if appropriate. */ 2600 @VisibleForTesting updateQuickDozeFlagLocked(boolean enabled)2601 void updateQuickDozeFlagLocked(boolean enabled) { 2602 if (DEBUG) Slog.i(TAG, "updateQuickDozeFlagLocked: enabled=" + enabled); 2603 mQuickDozeActivated = enabled; 2604 if (enabled) { 2605 // If Quick Doze is enabled, see if we should go straight into it. 2606 becomeInactiveIfAppropriateLocked(); 2607 } 2608 // Going from Deep Doze to Light Idle (if quick doze becomes disabled) is tricky and 2609 // probably not worth the overhead, so leave in deep doze if that's the case until the 2610 // next natural time to come out of it. 2611 } 2612 2613 2614 /** Returns true if the screen is locked. */ 2615 @VisibleForTesting isKeyguardShowing()2616 boolean isKeyguardShowing() { 2617 synchronized (this) { 2618 return mScreenLocked; 2619 } 2620 } 2621 2622 @VisibleForTesting keyguardShowingLocked(boolean showing)2623 void keyguardShowingLocked(boolean showing) { 2624 if (DEBUG) Slog.i(TAG, "keyguardShowing=" + showing); 2625 if (mScreenLocked != showing) { 2626 mScreenLocked = showing; 2627 if (mScreenOn && !mForceIdle && !mScreenLocked) { 2628 mActiveReason = ACTIVE_REASON_UNLOCKED; 2629 becomeActiveLocked("unlocked", Process.myUid()); 2630 } 2631 } 2632 } 2633 2634 @VisibleForTesting scheduleReportActiveLocked(String activeReason, int activeUid)2635 void scheduleReportActiveLocked(String activeReason, int activeUid) { 2636 Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid, 0, activeReason); 2637 mHandler.sendMessage(msg); 2638 } 2639 becomeActiveLocked(String activeReason, int activeUid)2640 void becomeActiveLocked(String activeReason, int activeUid) { 2641 becomeActiveLocked(activeReason, activeUid, mConstants.INACTIVE_TIMEOUT, true); 2642 } 2643 becomeActiveLocked(String activeReason, int activeUid, long newInactiveTimeout, boolean changeLightIdle)2644 private void becomeActiveLocked(String activeReason, int activeUid, 2645 long newInactiveTimeout, boolean changeLightIdle) { 2646 if (DEBUG) { 2647 Slog.i(TAG, "becomeActiveLocked, reason=" + activeReason 2648 + ", changeLightIdle=" + changeLightIdle); 2649 } 2650 if (mState != STATE_ACTIVE || mLightState != STATE_ACTIVE) { 2651 EventLogTags.writeDeviceIdle(STATE_ACTIVE, activeReason); 2652 mState = STATE_ACTIVE; 2653 mInactiveTimeout = newInactiveTimeout; 2654 mCurIdleBudget = 0; 2655 mMaintenanceStartTime = 0; 2656 resetIdleManagementLocked(); 2657 2658 if (changeLightIdle) { 2659 EventLogTags.writeDeviceIdleLight(LIGHT_STATE_ACTIVE, activeReason); 2660 mLightState = LIGHT_STATE_ACTIVE; 2661 resetLightIdleManagementLocked(); 2662 // Only report active if light is also ACTIVE. 2663 scheduleReportActiveLocked(activeReason, activeUid); 2664 addEvent(EVENT_NORMAL, activeReason); 2665 } 2666 } 2667 } 2668 2669 /** Must only be used in tests. */ 2670 @VisibleForTesting setDeepEnabledForTest(boolean enabled)2671 void setDeepEnabledForTest(boolean enabled) { 2672 synchronized (this) { 2673 mDeepEnabled = enabled; 2674 } 2675 } 2676 2677 /** Must only be used in tests. */ 2678 @VisibleForTesting setLightEnabledForTest(boolean enabled)2679 void setLightEnabledForTest(boolean enabled) { 2680 synchronized (this) { 2681 mLightEnabled = enabled; 2682 } 2683 } 2684 2685 /** Sanity check to make sure DeviceIdleController and AlarmManager are on the same page. */ verifyAlarmStateLocked()2686 private void verifyAlarmStateLocked() { 2687 if (mState == STATE_ACTIVE && mNextAlarmTime != 0) { 2688 Slog.wtf(TAG, "mState=ACTIVE but mNextAlarmTime=" + mNextAlarmTime); 2689 } 2690 if (mState != STATE_IDLE && mLocalAlarmManager.isIdling()) { 2691 Slog.wtf(TAG, "mState=" + stateToString(mState) + " but AlarmManager is idling"); 2692 } 2693 if (mState == STATE_IDLE && !mLocalAlarmManager.isIdling()) { 2694 Slog.wtf(TAG, "mState=IDLE but AlarmManager is not idling"); 2695 } 2696 if (mLightState == LIGHT_STATE_ACTIVE && mNextLightAlarmTime != 0) { 2697 Slog.wtf(TAG, "mLightState=ACTIVE but mNextLightAlarmTime is " 2698 + TimeUtils.formatDuration(mNextLightAlarmTime - SystemClock.elapsedRealtime()) 2699 + " from now"); 2700 } 2701 } 2702 becomeInactiveIfAppropriateLocked()2703 void becomeInactiveIfAppropriateLocked() { 2704 verifyAlarmStateLocked(); 2705 2706 final boolean isScreenBlockingInactive = 2707 mScreenOn && (!mConstants.WAIT_FOR_UNLOCK || !mScreenLocked); 2708 if (DEBUG) { 2709 Slog.d(TAG, "becomeInactiveIfAppropriateLocked():" 2710 + " isScreenBlockingInactive=" + isScreenBlockingInactive 2711 + " (mScreenOn=" + mScreenOn 2712 + ", WAIT_FOR_UNLOCK=" + mConstants.WAIT_FOR_UNLOCK 2713 + ", mScreenLocked=" + mScreenLocked + ")" 2714 + " mCharging=" + mCharging 2715 + " mForceIdle=" + mForceIdle 2716 ); 2717 } 2718 if (!mForceIdle && (mCharging || isScreenBlockingInactive)) { 2719 return; 2720 } 2721 // Become inactive and determine if we will ultimately go idle. 2722 if (mDeepEnabled) { 2723 if (mQuickDozeActivated) { 2724 if (mState == STATE_QUICK_DOZE_DELAY || mState == STATE_IDLE 2725 || mState == STATE_IDLE_MAINTENANCE) { 2726 // Already "idling". Don't want to restart the process. 2727 // mLightState can't be LIGHT_STATE_ACTIVE if mState is any of these 3 2728 // values, so returning here is safe. 2729 return; 2730 } 2731 if (DEBUG) { 2732 Slog.d(TAG, "Moved from " 2733 + stateToString(mState) + " to STATE_QUICK_DOZE_DELAY"); 2734 } 2735 mState = STATE_QUICK_DOZE_DELAY; 2736 // Make sure any motion sensing or locating is stopped. 2737 resetIdleManagementLocked(); 2738 // Wait a small amount of time in case something (eg: background service from 2739 // recently closed app) needs to finish running. 2740 scheduleAlarmLocked(mConstants.QUICK_DOZE_DELAY_TIMEOUT, false); 2741 EventLogTags.writeDeviceIdle(mState, "no activity"); 2742 } else if (mState == STATE_ACTIVE) { 2743 mState = STATE_INACTIVE; 2744 if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE"); 2745 resetIdleManagementLocked(); 2746 long delay = mInactiveTimeout; 2747 if (shouldUseIdleTimeoutFactorLocked()) { 2748 delay = (long) (mPreIdleFactor * delay); 2749 } 2750 scheduleAlarmLocked(delay, false); 2751 EventLogTags.writeDeviceIdle(mState, "no activity"); 2752 } 2753 } 2754 if (mLightState == LIGHT_STATE_ACTIVE && mLightEnabled) { 2755 mLightState = LIGHT_STATE_INACTIVE; 2756 if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE"); 2757 resetLightIdleManagementLocked(); 2758 scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT); 2759 EventLogTags.writeDeviceIdleLight(mLightState, "no activity"); 2760 } 2761 } 2762 resetIdleManagementLocked()2763 private void resetIdleManagementLocked() { 2764 mNextIdlePendingDelay = 0; 2765 mNextIdleDelay = 0; 2766 mNextLightIdleDelay = 0; 2767 mIdleStartTime = 0; 2768 cancelAlarmLocked(); 2769 cancelSensingTimeoutAlarmLocked(); 2770 cancelLocatingLocked(); 2771 stopMonitoringMotionLocked(); 2772 mAnyMotionDetector.stop(); 2773 updateActiveConstraintsLocked(); 2774 } 2775 resetLightIdleManagementLocked()2776 private void resetLightIdleManagementLocked() { 2777 cancelLightAlarmLocked(); 2778 } 2779 exitForceIdleLocked()2780 void exitForceIdleLocked() { 2781 if (mForceIdle) { 2782 mForceIdle = false; 2783 if (mScreenOn || mCharging) { 2784 mActiveReason = ACTIVE_REASON_FORCED; 2785 becomeActiveLocked("exit-force", Process.myUid()); 2786 } 2787 } 2788 } 2789 2790 /** 2791 * Must only be used in tests. 2792 * 2793 * This sets the state value directly and thus doesn't trigger any behavioral changes. 2794 */ 2795 @VisibleForTesting setLightStateForTest(int lightState)2796 void setLightStateForTest(int lightState) { 2797 synchronized (this) { 2798 mLightState = lightState; 2799 } 2800 } 2801 2802 @VisibleForTesting getLightState()2803 int getLightState() { 2804 return mLightState; 2805 } 2806 stepLightIdleStateLocked(String reason)2807 void stepLightIdleStateLocked(String reason) { 2808 if (mLightState == LIGHT_STATE_OVERRIDE) { 2809 // If we are already in deep device idle mode, then 2810 // there is nothing left to do for light mode. 2811 return; 2812 } 2813 2814 if (DEBUG) Slog.d(TAG, "stepLightIdleStateLocked: mLightState=" + mLightState); 2815 EventLogTags.writeDeviceIdleLightStep(); 2816 2817 switch (mLightState) { 2818 case LIGHT_STATE_INACTIVE: 2819 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET; 2820 // Reset the upcoming idle delays. 2821 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT; 2822 mMaintenanceStartTime = 0; 2823 if (!isOpsInactiveLocked()) { 2824 // We have some active ops going on... give them a chance to finish 2825 // before going in to our first idle. 2826 mLightState = LIGHT_STATE_PRE_IDLE; 2827 EventLogTags.writeDeviceIdleLight(mLightState, reason); 2828 scheduleLightAlarmLocked(mConstants.LIGHT_PRE_IDLE_TIMEOUT); 2829 break; 2830 } 2831 // Nothing active, fall through to immediately idle. 2832 case LIGHT_STATE_PRE_IDLE: 2833 case LIGHT_STATE_IDLE_MAINTENANCE: 2834 if (mMaintenanceStartTime != 0) { 2835 long duration = SystemClock.elapsedRealtime() - mMaintenanceStartTime; 2836 if (duration < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) { 2837 // We didn't use up all of our minimum budget; add this to the reserve. 2838 mCurIdleBudget += (mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET-duration); 2839 } else { 2840 // We used more than our minimum budget; this comes out of the reserve. 2841 mCurIdleBudget -= (duration-mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET); 2842 } 2843 } 2844 mMaintenanceStartTime = 0; 2845 scheduleLightAlarmLocked(mNextLightIdleDelay); 2846 mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT, 2847 (long)(mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR)); 2848 if (mNextLightIdleDelay < mConstants.LIGHT_IDLE_TIMEOUT) { 2849 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT; 2850 } 2851 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_STATE_IDLE."); 2852 mLightState = LIGHT_STATE_IDLE; 2853 EventLogTags.writeDeviceIdleLight(mLightState, reason); 2854 addEvent(EVENT_LIGHT_IDLE, null); 2855 mGoingIdleWakeLock.acquire(); 2856 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON_LIGHT); 2857 break; 2858 case LIGHT_STATE_IDLE: 2859 case LIGHT_STATE_WAITING_FOR_NETWORK: 2860 if (mNetworkConnected || mLightState == LIGHT_STATE_WAITING_FOR_NETWORK) { 2861 // We have been idling long enough, now it is time to do some work. 2862 mActiveIdleOpCount = 1; 2863 mActiveIdleWakeLock.acquire(); 2864 mMaintenanceStartTime = SystemClock.elapsedRealtime(); 2865 if (mCurIdleBudget < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) { 2866 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET; 2867 } else if (mCurIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) { 2868 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET; 2869 } 2870 scheduleLightAlarmLocked(mCurIdleBudget); 2871 if (DEBUG) Slog.d(TAG, 2872 "Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE."); 2873 mLightState = LIGHT_STATE_IDLE_MAINTENANCE; 2874 EventLogTags.writeDeviceIdleLight(mLightState, reason); 2875 addEvent(EVENT_LIGHT_MAINTENANCE, null); 2876 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF); 2877 } else { 2878 // We'd like to do maintenance, but currently don't have network 2879 // connectivity... let's try to wait until the network comes back. 2880 // We'll only wait for another full idle period, however, and then give up. 2881 scheduleLightAlarmLocked(mNextLightIdleDelay); 2882 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_WAITING_FOR_NETWORK."); 2883 mLightState = LIGHT_STATE_WAITING_FOR_NETWORK; 2884 EventLogTags.writeDeviceIdleLight(mLightState, reason); 2885 } 2886 break; 2887 } 2888 } 2889 2890 @VisibleForTesting getState()2891 int getState() { 2892 return mState; 2893 } 2894 2895 @VisibleForTesting stepIdleStateLocked(String reason)2896 void stepIdleStateLocked(String reason) { 2897 if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState); 2898 EventLogTags.writeDeviceIdleStep(); 2899 2900 final long now = SystemClock.elapsedRealtime(); 2901 if ((now+mConstants.MIN_TIME_TO_ALARM) > mAlarmManager.getNextWakeFromIdleTime()) { 2902 // Whoops, there is an upcoming alarm. We don't actually want to go idle. 2903 if (mState != STATE_ACTIVE) { 2904 mActiveReason = ACTIVE_REASON_ALARM; 2905 becomeActiveLocked("alarm", Process.myUid()); 2906 becomeInactiveIfAppropriateLocked(); 2907 } 2908 return; 2909 } 2910 2911 if (mNumBlockingConstraints != 0 && !mForceIdle) { 2912 // We have some constraints from other parts of the system server preventing 2913 // us from moving to the next state. 2914 if (DEBUG) { 2915 Slog.i(TAG, "Cannot step idle state. Blocked by: " + mConstraints.values().stream() 2916 .filter(x -> x.active) 2917 .map(x -> x.name) 2918 .collect(Collectors.joining(","))); 2919 } 2920 return; 2921 } 2922 2923 switch (mState) { 2924 case STATE_INACTIVE: 2925 // We have now been inactive long enough, it is time to start looking 2926 // for motion and sleep some more while doing so. 2927 startMonitoringMotionLocked(); 2928 long delay = mConstants.IDLE_AFTER_INACTIVE_TIMEOUT; 2929 if (shouldUseIdleTimeoutFactorLocked()) { 2930 delay = (long) (mPreIdleFactor * delay); 2931 } 2932 scheduleAlarmLocked(delay, false); 2933 moveToStateLocked(STATE_IDLE_PENDING, reason); 2934 break; 2935 case STATE_IDLE_PENDING: 2936 moveToStateLocked(STATE_SENSING, reason); 2937 cancelLocatingLocked(); 2938 mLocated = false; 2939 mLastGenericLocation = null; 2940 mLastGpsLocation = null; 2941 updateActiveConstraintsLocked(); 2942 2943 // Wait for open constraints and an accelerometer reading before moving on. 2944 if (mUseMotionSensor && mAnyMotionDetector.hasSensor()) { 2945 scheduleSensingTimeoutAlarmLocked(mConstants.SENSING_TIMEOUT); 2946 mNotMoving = false; 2947 mAnyMotionDetector.checkForAnyMotion(); 2948 break; 2949 } else if (mNumBlockingConstraints != 0) { 2950 cancelAlarmLocked(); 2951 break; 2952 } 2953 2954 mNotMoving = true; 2955 // Otherwise, fall through and check this off the list of requirements. 2956 case STATE_SENSING: 2957 cancelSensingTimeoutAlarmLocked(); 2958 moveToStateLocked(STATE_LOCATING, reason); 2959 scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT, false); 2960 LocationManager locationManager = mInjector.getLocationManager(); 2961 if (locationManager != null 2962 && locationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) { 2963 locationManager.requestLocationUpdates(mLocationRequest, 2964 mGenericLocationListener, mHandler.getLooper()); 2965 mLocating = true; 2966 } else { 2967 mHasNetworkLocation = false; 2968 } 2969 if (locationManager != null 2970 && locationManager.getProvider(LocationManager.GPS_PROVIDER) != null) { 2971 mHasGps = true; 2972 locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5, 2973 mGpsLocationListener, mHandler.getLooper()); 2974 mLocating = true; 2975 } else { 2976 mHasGps = false; 2977 } 2978 // If we have a location provider, we're all set, the listeners will move state 2979 // forward. 2980 if (mLocating) { 2981 break; 2982 } 2983 2984 // Otherwise, we have to move from locating into idle maintenance. 2985 case STATE_LOCATING: 2986 cancelAlarmLocked(); 2987 cancelLocatingLocked(); 2988 mAnyMotionDetector.stop(); 2989 2990 // Intentional fallthrough -- time to go into IDLE state. 2991 case STATE_QUICK_DOZE_DELAY: 2992 // Reset the upcoming idle delays. 2993 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT; 2994 mNextIdleDelay = mConstants.IDLE_TIMEOUT; 2995 2996 // Everything is in place to go into IDLE state. 2997 case STATE_IDLE_MAINTENANCE: 2998 scheduleAlarmLocked(mNextIdleDelay, true); 2999 if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay + 3000 " ms."); 3001 mNextIdleDelay = (long)(mNextIdleDelay * mConstants.IDLE_FACTOR); 3002 if (DEBUG) Slog.d(TAG, "Setting mNextIdleDelay = " + mNextIdleDelay); 3003 mIdleStartTime = SystemClock.elapsedRealtime(); 3004 mNextIdleDelay = Math.min(mNextIdleDelay, mConstants.MAX_IDLE_TIMEOUT); 3005 if (mNextIdleDelay < mConstants.IDLE_TIMEOUT) { 3006 mNextIdleDelay = mConstants.IDLE_TIMEOUT; 3007 } 3008 moveToStateLocked(STATE_IDLE, reason); 3009 if (mLightState != LIGHT_STATE_OVERRIDE) { 3010 mLightState = LIGHT_STATE_OVERRIDE; 3011 cancelLightAlarmLocked(); 3012 } 3013 addEvent(EVENT_DEEP_IDLE, null); 3014 mGoingIdleWakeLock.acquire(); 3015 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON); 3016 break; 3017 case STATE_IDLE: 3018 // We have been idling long enough, now it is time to do some work. 3019 mActiveIdleOpCount = 1; 3020 mActiveIdleWakeLock.acquire(); 3021 scheduleAlarmLocked(mNextIdlePendingDelay, false); 3022 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE to STATE_IDLE_MAINTENANCE. " + 3023 "Next alarm in " + mNextIdlePendingDelay + " ms."); 3024 mMaintenanceStartTime = SystemClock.elapsedRealtime(); 3025 mNextIdlePendingDelay = Math.min(mConstants.MAX_IDLE_PENDING_TIMEOUT, 3026 (long)(mNextIdlePendingDelay * mConstants.IDLE_PENDING_FACTOR)); 3027 if (mNextIdlePendingDelay < mConstants.IDLE_PENDING_TIMEOUT) { 3028 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT; 3029 } 3030 moveToStateLocked(STATE_IDLE_MAINTENANCE, reason); 3031 addEvent(EVENT_DEEP_MAINTENANCE, null); 3032 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF); 3033 break; 3034 } 3035 } 3036 moveToStateLocked(int state, String reason)3037 private void moveToStateLocked(int state, String reason) { 3038 final int oldState = mState; 3039 mState = state; 3040 if (DEBUG) { 3041 Slog.d(TAG, String.format("Moved from STATE_%s to STATE_%s.", 3042 stateToString(oldState), stateToString(mState))); 3043 } 3044 EventLogTags.writeDeviceIdle(mState, reason); 3045 updateActiveConstraintsLocked(); 3046 } 3047 incActiveIdleOps()3048 void incActiveIdleOps() { 3049 synchronized (this) { 3050 mActiveIdleOpCount++; 3051 } 3052 } 3053 decActiveIdleOps()3054 void decActiveIdleOps() { 3055 synchronized (this) { 3056 mActiveIdleOpCount--; 3057 if (mActiveIdleOpCount <= 0) { 3058 exitMaintenanceEarlyIfNeededLocked(); 3059 mActiveIdleWakeLock.release(); 3060 } 3061 } 3062 } 3063 3064 /** Must only be used in tests. */ 3065 @VisibleForTesting setActiveIdleOpsForTest(int count)3066 void setActiveIdleOpsForTest(int count) { 3067 synchronized (this) { 3068 mActiveIdleOpCount = count; 3069 } 3070 } 3071 setJobsActive(boolean active)3072 void setJobsActive(boolean active) { 3073 synchronized (this) { 3074 mJobsActive = active; 3075 reportMaintenanceActivityIfNeededLocked(); 3076 if (!active) { 3077 exitMaintenanceEarlyIfNeededLocked(); 3078 } 3079 } 3080 } 3081 setAlarmsActive(boolean active)3082 void setAlarmsActive(boolean active) { 3083 synchronized (this) { 3084 mAlarmsActive = active; 3085 if (!active) { 3086 exitMaintenanceEarlyIfNeededLocked(); 3087 } 3088 } 3089 } 3090 registerMaintenanceActivityListener(IMaintenanceActivityListener listener)3091 boolean registerMaintenanceActivityListener(IMaintenanceActivityListener listener) { 3092 synchronized (this) { 3093 mMaintenanceActivityListeners.register(listener); 3094 return mReportedMaintenanceActivity; 3095 } 3096 } 3097 unregisterMaintenanceActivityListener(IMaintenanceActivityListener listener)3098 void unregisterMaintenanceActivityListener(IMaintenanceActivityListener listener) { 3099 synchronized (this) { 3100 mMaintenanceActivityListeners.unregister(listener); 3101 } 3102 } 3103 3104 @VisibleForTesting setPreIdleTimeoutMode(int mode)3105 int setPreIdleTimeoutMode(int mode) { 3106 return setPreIdleTimeoutFactor(getPreIdleTimeoutByMode(mode)); 3107 } 3108 3109 @VisibleForTesting getPreIdleTimeoutByMode(int mode)3110 float getPreIdleTimeoutByMode(int mode) { 3111 switch (mode) { 3112 case PowerManager.PRE_IDLE_TIMEOUT_MODE_LONG: { 3113 return mConstants.PRE_IDLE_FACTOR_LONG; 3114 } 3115 case PowerManager.PRE_IDLE_TIMEOUT_MODE_SHORT: { 3116 return mConstants.PRE_IDLE_FACTOR_SHORT; 3117 } 3118 case PowerManager.PRE_IDLE_TIMEOUT_MODE_NORMAL: { 3119 return 1.0f; 3120 } 3121 default: { 3122 Slog.w(TAG, "Invalid time out factor mode: " + mode); 3123 return 1.0f; 3124 } 3125 } 3126 } 3127 3128 @VisibleForTesting getPreIdleTimeoutFactor()3129 float getPreIdleTimeoutFactor() { 3130 return mPreIdleFactor; 3131 } 3132 3133 @VisibleForTesting setPreIdleTimeoutFactor(float ratio)3134 int setPreIdleTimeoutFactor(float ratio) { 3135 if (!mDeepEnabled) { 3136 if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: Deep Idle disable"); 3137 return SET_IDLE_FACTOR_RESULT_NOT_SUPPORT; 3138 } else if (ratio <= MIN_PRE_IDLE_FACTOR_CHANGE) { 3139 if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: Invalid input"); 3140 return SET_IDLE_FACTOR_RESULT_INVALID; 3141 } else if (Math.abs(ratio - mPreIdleFactor) < MIN_PRE_IDLE_FACTOR_CHANGE) { 3142 if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: New factor same as previous factor"); 3143 return SET_IDLE_FACTOR_RESULT_IGNORED; 3144 } 3145 synchronized (this) { 3146 mLastPreIdleFactor = mPreIdleFactor; 3147 mPreIdleFactor = ratio; 3148 } 3149 if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: " + ratio); 3150 postUpdatePreIdleFactor(); 3151 return SET_IDLE_FACTOR_RESULT_OK; 3152 } 3153 3154 @VisibleForTesting resetPreIdleTimeoutMode()3155 void resetPreIdleTimeoutMode() { 3156 synchronized (this) { 3157 mLastPreIdleFactor = mPreIdleFactor; 3158 mPreIdleFactor = 1.0f; 3159 } 3160 if (DEBUG) Slog.d(TAG, "resetPreIdleTimeoutMode to 1.0"); 3161 postResetPreIdleTimeoutFactor(); 3162 } 3163 postUpdatePreIdleFactor()3164 private void postUpdatePreIdleFactor() { 3165 mHandler.sendEmptyMessage(MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR); 3166 } 3167 postResetPreIdleTimeoutFactor()3168 private void postResetPreIdleTimeoutFactor() { 3169 mHandler.sendEmptyMessage(MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR); 3170 } 3171 3172 @VisibleForTesting updatePreIdleFactor()3173 void updatePreIdleFactor() { 3174 synchronized (this) { 3175 if (!shouldUseIdleTimeoutFactorLocked()) { 3176 return; 3177 } 3178 if (mState == STATE_INACTIVE || mState == STATE_IDLE_PENDING) { 3179 if (mNextAlarmTime == 0) { 3180 return; 3181 } 3182 long delay = mNextAlarmTime - SystemClock.elapsedRealtime(); 3183 if (delay < MIN_STATE_STEP_ALARM_CHANGE) { 3184 return; 3185 } 3186 long newDelay = (long) (delay / mLastPreIdleFactor * mPreIdleFactor); 3187 if (Math.abs(delay - newDelay) < MIN_STATE_STEP_ALARM_CHANGE) { 3188 return; 3189 } 3190 scheduleAlarmLocked(newDelay, false); 3191 } 3192 } 3193 } 3194 3195 @VisibleForTesting maybeDoImmediateMaintenance()3196 void maybeDoImmediateMaintenance() { 3197 synchronized (this) { 3198 if (mState == STATE_IDLE) { 3199 long duration = SystemClock.elapsedRealtime() - mIdleStartTime; 3200 /* Let's trgger a immediate maintenance, 3201 * if it has been idle for a long time */ 3202 if (duration > mConstants.IDLE_TIMEOUT) { 3203 scheduleAlarmLocked(0, false); 3204 } 3205 } 3206 } 3207 } 3208 shouldUseIdleTimeoutFactorLocked()3209 private boolean shouldUseIdleTimeoutFactorLocked() { 3210 // exclude ACTIVE_REASON_MOTION, for exclude device in pocket case 3211 if (mActiveReason == ACTIVE_REASON_MOTION) { 3212 return false; 3213 } 3214 return true; 3215 } 3216 3217 /** Must only be used in tests. */ 3218 @VisibleForTesting setIdleStartTimeForTest(long idleStartTime)3219 void setIdleStartTimeForTest(long idleStartTime) { 3220 synchronized (this) { 3221 mIdleStartTime = idleStartTime; 3222 } 3223 } 3224 reportMaintenanceActivityIfNeededLocked()3225 void reportMaintenanceActivityIfNeededLocked() { 3226 boolean active = mJobsActive; 3227 if (active == mReportedMaintenanceActivity) { 3228 return; 3229 } 3230 mReportedMaintenanceActivity = active; 3231 Message msg = mHandler.obtainMessage(MSG_REPORT_MAINTENANCE_ACTIVITY, 3232 mReportedMaintenanceActivity ? 1 : 0, 0); 3233 mHandler.sendMessage(msg); 3234 } 3235 3236 @VisibleForTesting getNextAlarmTime()3237 long getNextAlarmTime() { 3238 return mNextAlarmTime; 3239 } 3240 isOpsInactiveLocked()3241 boolean isOpsInactiveLocked() { 3242 return mActiveIdleOpCount <= 0 && !mJobsActive && !mAlarmsActive; 3243 } 3244 exitMaintenanceEarlyIfNeededLocked()3245 void exitMaintenanceEarlyIfNeededLocked() { 3246 if (mState == STATE_IDLE_MAINTENANCE || mLightState == LIGHT_STATE_IDLE_MAINTENANCE 3247 || mLightState == LIGHT_STATE_PRE_IDLE) { 3248 if (isOpsInactiveLocked()) { 3249 final long now = SystemClock.elapsedRealtime(); 3250 if (DEBUG) { 3251 StringBuilder sb = new StringBuilder(); 3252 sb.append("Exit: start="); 3253 TimeUtils.formatDuration(mMaintenanceStartTime, sb); 3254 sb.append(" now="); 3255 TimeUtils.formatDuration(now, sb); 3256 Slog.d(TAG, sb.toString()); 3257 } 3258 if (mState == STATE_IDLE_MAINTENANCE) { 3259 stepIdleStateLocked("s:early"); 3260 } else if (mLightState == LIGHT_STATE_PRE_IDLE) { 3261 stepLightIdleStateLocked("s:predone"); 3262 } else { 3263 stepLightIdleStateLocked("s:early"); 3264 } 3265 } 3266 } 3267 } 3268 motionLocked()3269 void motionLocked() { 3270 if (DEBUG) Slog.d(TAG, "motionLocked()"); 3271 // The motion sensor will have been disabled at this point 3272 handleMotionDetectedLocked(mConstants.MOTION_INACTIVE_TIMEOUT, "motion"); 3273 } 3274 handleMotionDetectedLocked(long timeout, String type)3275 void handleMotionDetectedLocked(long timeout, String type) { 3276 // The device is not yet active, so we want to go back to the pending idle 3277 // state to wait again for no motion. Note that we only monitor for motion 3278 // after moving out of the inactive state, so no need to worry about that. 3279 final boolean becomeInactive = mState != STATE_ACTIVE 3280 || mLightState == LIGHT_STATE_OVERRIDE; 3281 // We only want to change the IDLE state if it's OVERRIDE. 3282 becomeActiveLocked(type, Process.myUid(), timeout, mLightState == LIGHT_STATE_OVERRIDE); 3283 if (becomeInactive) { 3284 becomeInactiveIfAppropriateLocked(); 3285 } 3286 } 3287 receivedGenericLocationLocked(Location location)3288 void receivedGenericLocationLocked(Location location) { 3289 if (mState != STATE_LOCATING) { 3290 cancelLocatingLocked(); 3291 return; 3292 } 3293 if (DEBUG) Slog.d(TAG, "Generic location: " + location); 3294 mLastGenericLocation = new Location(location); 3295 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHasGps) { 3296 return; 3297 } 3298 mLocated = true; 3299 if (mNotMoving) { 3300 stepIdleStateLocked("s:location"); 3301 } 3302 } 3303 receivedGpsLocationLocked(Location location)3304 void receivedGpsLocationLocked(Location location) { 3305 if (mState != STATE_LOCATING) { 3306 cancelLocatingLocked(); 3307 return; 3308 } 3309 if (DEBUG) Slog.d(TAG, "GPS location: " + location); 3310 mLastGpsLocation = new Location(location); 3311 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY) { 3312 return; 3313 } 3314 mLocated = true; 3315 if (mNotMoving) { 3316 stepIdleStateLocked("s:gps"); 3317 } 3318 } 3319 startMonitoringMotionLocked()3320 void startMonitoringMotionLocked() { 3321 if (DEBUG) Slog.d(TAG, "startMonitoringMotionLocked()"); 3322 if (mMotionSensor != null && !mMotionListener.active) { 3323 mMotionListener.registerLocked(); 3324 } 3325 } 3326 stopMonitoringMotionLocked()3327 void stopMonitoringMotionLocked() { 3328 if (DEBUG) Slog.d(TAG, "stopMonitoringMotionLocked()"); 3329 if (mMotionSensor != null && mMotionListener.active) { 3330 mMotionListener.unregisterLocked(); 3331 } 3332 } 3333 cancelAlarmLocked()3334 void cancelAlarmLocked() { 3335 if (mNextAlarmTime != 0) { 3336 mNextAlarmTime = 0; 3337 mAlarmManager.cancel(mDeepAlarmListener); 3338 } 3339 } 3340 cancelLightAlarmLocked()3341 void cancelLightAlarmLocked() { 3342 if (mNextLightAlarmTime != 0) { 3343 mNextLightAlarmTime = 0; 3344 mAlarmManager.cancel(mLightAlarmListener); 3345 } 3346 } 3347 cancelLocatingLocked()3348 void cancelLocatingLocked() { 3349 if (mLocating) { 3350 LocationManager locationManager = mInjector.getLocationManager(); 3351 locationManager.removeUpdates(mGenericLocationListener); 3352 locationManager.removeUpdates(mGpsLocationListener); 3353 mLocating = false; 3354 } 3355 } 3356 cancelSensingTimeoutAlarmLocked()3357 void cancelSensingTimeoutAlarmLocked() { 3358 if (mNextSensingTimeoutAlarmTime != 0) { 3359 mNextSensingTimeoutAlarmTime = 0; 3360 mAlarmManager.cancel(mSensingTimeoutAlarmListener); 3361 } 3362 } 3363 scheduleAlarmLocked(long delay, boolean idleUntil)3364 void scheduleAlarmLocked(long delay, boolean idleUntil) { 3365 if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")"); 3366 3367 if (mUseMotionSensor && mMotionSensor == null 3368 && mState != STATE_QUICK_DOZE_DELAY 3369 && mState != STATE_IDLE 3370 && mState != STATE_IDLE_MAINTENANCE) { 3371 // If there is no motion sensor on this device, but we need one, then we won't schedule 3372 // alarms, because we can't determine if the device is not moving. This effectively 3373 // turns off normal execution of device idling, although it is still possible to 3374 // manually poke it by pretending like the alarm is going off. 3375 // STATE_QUICK_DOZE_DELAY skips the motion sensing so if the state is past the motion 3376 // sensing stage (ie, is QUICK_DOZE_DELAY, IDLE, or IDLE_MAINTENANCE), then idling 3377 // can continue until the user interacts with the device. 3378 return; 3379 } 3380 mNextAlarmTime = SystemClock.elapsedRealtime() + delay; 3381 if (idleUntil) { 3382 mAlarmManager.setIdleUntil(AlarmManager.ELAPSED_REALTIME_WAKEUP, 3383 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler); 3384 } else { 3385 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 3386 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler); 3387 } 3388 } 3389 scheduleLightAlarmLocked(long delay)3390 void scheduleLightAlarmLocked(long delay) { 3391 if (DEBUG) Slog.d(TAG, "scheduleLightAlarmLocked(" + delay + ")"); 3392 mNextLightAlarmTime = SystemClock.elapsedRealtime() + delay; 3393 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 3394 mNextLightAlarmTime, "DeviceIdleController.light", mLightAlarmListener, mHandler); 3395 } 3396 scheduleSensingTimeoutAlarmLocked(long delay)3397 void scheduleSensingTimeoutAlarmLocked(long delay) { 3398 if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")"); 3399 mNextSensingTimeoutAlarmTime = SystemClock.elapsedRealtime() + delay; 3400 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextSensingTimeoutAlarmTime, 3401 "DeviceIdleController.sensing", mSensingTimeoutAlarmListener, mHandler); 3402 } 3403 buildAppIdArray(ArrayMap<String, Integer> systemApps, ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds)3404 private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps, 3405 ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds) { 3406 outAppIds.clear(); 3407 if (systemApps != null) { 3408 for (int i = 0; i < systemApps.size(); i++) { 3409 outAppIds.put(systemApps.valueAt(i), true); 3410 } 3411 } 3412 if (userApps != null) { 3413 for (int i = 0; i < userApps.size(); i++) { 3414 outAppIds.put(userApps.valueAt(i), true); 3415 } 3416 } 3417 int size = outAppIds.size(); 3418 int[] appids = new int[size]; 3419 for (int i = 0; i < size; i++) { 3420 appids[i] = outAppIds.keyAt(i); 3421 } 3422 return appids; 3423 } 3424 updateWhitelistAppIdsLocked()3425 private void updateWhitelistAppIdsLocked() { 3426 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(mPowerSaveWhitelistAppsExceptIdle, 3427 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistExceptIdleAppIds); 3428 mPowerSaveWhitelistAllAppIdArray = buildAppIdArray(mPowerSaveWhitelistApps, 3429 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistAllAppIds); 3430 mPowerSaveWhitelistUserAppIdArray = buildAppIdArray(null, 3431 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistUserAppIds); 3432 if (mLocalActivityManager != null) { 3433 mLocalActivityManager.setDeviceIdleWhitelist( 3434 mPowerSaveWhitelistAllAppIdArray, mPowerSaveWhitelistExceptIdleAppIdArray); 3435 } 3436 if (mLocalPowerManager != null) { 3437 if (DEBUG) { 3438 Slog.d(TAG, "Setting wakelock whitelist to " 3439 + Arrays.toString(mPowerSaveWhitelistAllAppIdArray)); 3440 } 3441 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); 3442 } 3443 passWhiteListsToForceAppStandbyTrackerLocked(); 3444 } 3445 updateTempWhitelistAppIdsLocked(int appId, boolean adding)3446 private void updateTempWhitelistAppIdsLocked(int appId, boolean adding) { 3447 final int size = mTempWhitelistAppIdEndTimes.size(); 3448 if (mTempWhitelistAppIdArray.length != size) { 3449 mTempWhitelistAppIdArray = new int[size]; 3450 } 3451 for (int i = 0; i < size; i++) { 3452 mTempWhitelistAppIdArray[i] = mTempWhitelistAppIdEndTimes.keyAt(i); 3453 } 3454 if (mLocalActivityManager != null) { 3455 if (DEBUG) { 3456 Slog.d(TAG, "Setting activity manager temp whitelist to " 3457 + Arrays.toString(mTempWhitelistAppIdArray)); 3458 } 3459 mLocalActivityManager.updateDeviceIdleTempWhitelist(mTempWhitelistAppIdArray, appId, 3460 adding); 3461 } 3462 if (mLocalPowerManager != null) { 3463 if (DEBUG) { 3464 Slog.d(TAG, "Setting wakelock temp whitelist to " 3465 + Arrays.toString(mTempWhitelistAppIdArray)); 3466 } 3467 mLocalPowerManager.setDeviceIdleTempWhitelist(mTempWhitelistAppIdArray); 3468 } 3469 passWhiteListsToForceAppStandbyTrackerLocked(); 3470 } 3471 reportPowerSaveWhitelistChangedLocked()3472 private void reportPowerSaveWhitelistChangedLocked() { 3473 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED); 3474 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3475 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM); 3476 } 3477 reportTempWhitelistChangedLocked()3478 private void reportTempWhitelistChangedLocked() { 3479 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED); 3480 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3481 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM); 3482 } 3483 passWhiteListsToForceAppStandbyTrackerLocked()3484 private void passWhiteListsToForceAppStandbyTrackerLocked() { 3485 mAppStateTracker.setPowerSaveWhitelistAppIds( 3486 mPowerSaveWhitelistExceptIdleAppIdArray, 3487 mPowerSaveWhitelistUserAppIdArray, 3488 mTempWhitelistAppIdArray); 3489 } 3490 readConfigFileLocked()3491 void readConfigFileLocked() { 3492 if (DEBUG) Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile()); 3493 mPowerSaveWhitelistUserApps.clear(); 3494 FileInputStream stream; 3495 try { 3496 stream = mConfigFile.openRead(); 3497 } catch (FileNotFoundException e) { 3498 return; 3499 } 3500 try { 3501 XmlPullParser parser = Xml.newPullParser(); 3502 parser.setInput(stream, StandardCharsets.UTF_8.name()); 3503 readConfigFileLocked(parser); 3504 } catch (XmlPullParserException e) { 3505 } finally { 3506 try { 3507 stream.close(); 3508 } catch (IOException e) { 3509 } 3510 } 3511 } 3512 readConfigFileLocked(XmlPullParser parser)3513 private void readConfigFileLocked(XmlPullParser parser) { 3514 final PackageManager pm = getContext().getPackageManager(); 3515 3516 try { 3517 int type; 3518 while ((type = parser.next()) != XmlPullParser.START_TAG 3519 && type != XmlPullParser.END_DOCUMENT) { 3520 ; 3521 } 3522 3523 if (type != XmlPullParser.START_TAG) { 3524 throw new IllegalStateException("no start tag found"); 3525 } 3526 3527 int outerDepth = parser.getDepth(); 3528 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 3529 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 3530 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 3531 continue; 3532 } 3533 3534 String tagName = parser.getName(); 3535 switch (tagName) { 3536 case "wl": 3537 String name = parser.getAttributeValue(null, "n"); 3538 if (name != null) { 3539 try { 3540 ApplicationInfo ai = pm.getApplicationInfo(name, 3541 PackageManager.MATCH_ANY_USER); 3542 mPowerSaveWhitelistUserApps.put(ai.packageName, 3543 UserHandle.getAppId(ai.uid)); 3544 } catch (PackageManager.NameNotFoundException e) { 3545 } 3546 } 3547 break; 3548 case "un-wl": 3549 final String packageName = parser.getAttributeValue(null, "n"); 3550 if (mPowerSaveWhitelistApps.containsKey(packageName)) { 3551 mRemovedFromSystemWhitelistApps.put(packageName, 3552 mPowerSaveWhitelistApps.remove(packageName)); 3553 } 3554 break; 3555 default: 3556 Slog.w(TAG, "Unknown element under <config>: " 3557 + parser.getName()); 3558 XmlUtils.skipCurrentTag(parser); 3559 break; 3560 } 3561 } 3562 3563 } catch (IllegalStateException e) { 3564 Slog.w(TAG, "Failed parsing config " + e); 3565 } catch (NullPointerException e) { 3566 Slog.w(TAG, "Failed parsing config " + e); 3567 } catch (NumberFormatException e) { 3568 Slog.w(TAG, "Failed parsing config " + e); 3569 } catch (XmlPullParserException e) { 3570 Slog.w(TAG, "Failed parsing config " + e); 3571 } catch (IOException e) { 3572 Slog.w(TAG, "Failed parsing config " + e); 3573 } catch (IndexOutOfBoundsException e) { 3574 Slog.w(TAG, "Failed parsing config " + e); 3575 } 3576 } 3577 writeConfigFileLocked()3578 void writeConfigFileLocked() { 3579 mHandler.removeMessages(MSG_WRITE_CONFIG); 3580 mHandler.sendEmptyMessageDelayed(MSG_WRITE_CONFIG, 5000); 3581 } 3582 handleWriteConfigFile()3583 void handleWriteConfigFile() { 3584 final ByteArrayOutputStream memStream = new ByteArrayOutputStream(); 3585 3586 try { 3587 synchronized (this) { 3588 XmlSerializer out = new FastXmlSerializer(); 3589 out.setOutput(memStream, StandardCharsets.UTF_8.name()); 3590 writeConfigFileLocked(out); 3591 } 3592 } catch (IOException e) { 3593 } 3594 3595 synchronized (mConfigFile) { 3596 FileOutputStream stream = null; 3597 try { 3598 stream = mConfigFile.startWrite(); 3599 memStream.writeTo(stream); 3600 stream.flush(); 3601 FileUtils.sync(stream); 3602 stream.close(); 3603 mConfigFile.finishWrite(stream); 3604 } catch (IOException e) { 3605 Slog.w(TAG, "Error writing config file", e); 3606 mConfigFile.failWrite(stream); 3607 } 3608 } 3609 } 3610 writeConfigFileLocked(XmlSerializer out)3611 void writeConfigFileLocked(XmlSerializer out) throws IOException { 3612 out.startDocument(null, true); 3613 out.startTag(null, "config"); 3614 for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) { 3615 String name = mPowerSaveWhitelistUserApps.keyAt(i); 3616 out.startTag(null, "wl"); 3617 out.attribute(null, "n", name); 3618 out.endTag(null, "wl"); 3619 } 3620 for (int i = 0; i < mRemovedFromSystemWhitelistApps.size(); i++) { 3621 out.startTag(null, "un-wl"); 3622 out.attribute(null, "n", mRemovedFromSystemWhitelistApps.keyAt(i)); 3623 out.endTag(null, "un-wl"); 3624 } 3625 out.endTag(null, "config"); 3626 out.endDocument(); 3627 } 3628 dumpHelp(PrintWriter pw)3629 static void dumpHelp(PrintWriter pw) { 3630 pw.println("Device idle controller (deviceidle) commands:"); 3631 pw.println(" help"); 3632 pw.println(" Print this help text."); 3633 pw.println(" step [light|deep]"); 3634 pw.println(" Immediately step to next state, without waiting for alarm."); 3635 pw.println(" force-idle [light|deep]"); 3636 pw.println(" Force directly into idle mode, regardless of other device state."); 3637 pw.println(" force-inactive"); 3638 pw.println(" Force to be inactive, ready to freely step idle states."); 3639 pw.println(" unforce"); 3640 pw.println(" Resume normal functioning after force-idle or force-inactive."); 3641 pw.println(" get [light|deep|force|screen|charging|network]"); 3642 pw.println(" Retrieve the current given state."); 3643 pw.println(" disable [light|deep|all]"); 3644 pw.println(" Completely disable device idle mode."); 3645 pw.println(" enable [light|deep|all]"); 3646 pw.println(" Re-enable device idle mode after it had previously been disabled."); 3647 pw.println(" enabled [light|deep|all]"); 3648 pw.println(" Print 1 if device idle mode is currently enabled, else 0."); 3649 pw.println(" whitelist"); 3650 pw.println(" Print currently whitelisted apps."); 3651 pw.println(" whitelist [package ...]"); 3652 pw.println(" Add (prefix with +) or remove (prefix with -) packages."); 3653 pw.println(" sys-whitelist [package ...|reset]"); 3654 pw.println(" Prefix the package with '-' to remove it from the system whitelist or '+'" 3655 + " to put it back in the system whitelist."); 3656 pw.println(" Note that only packages that were" 3657 + " earlier removed from the system whitelist can be added back."); 3658 pw.println(" reset will reset the whitelist to the original state"); 3659 pw.println(" Prints the system whitelist if no arguments are specified"); 3660 pw.println(" except-idle-whitelist [package ...|reset]"); 3661 pw.println(" Prefix the package with '+' to add it to whitelist or " 3662 + "'=' to check if it is already whitelisted"); 3663 pw.println(" [reset] will reset the whitelist to it's original state"); 3664 pw.println(" Note that unlike <whitelist> cmd, " 3665 + "changes made using this won't be persisted across boots"); 3666 pw.println(" tempwhitelist"); 3667 pw.println(" Print packages that are temporarily whitelisted."); 3668 pw.println(" tempwhitelist [-u USER] [-d DURATION] [-r] [package]"); 3669 pw.println(" Temporarily place package in whitelist for DURATION milliseconds."); 3670 pw.println(" If no DURATION is specified, 10 seconds is used"); 3671 pw.println(" If [-r] option is used, then the package is removed from temp whitelist " 3672 + "and any [-d] is ignored"); 3673 pw.println(" motion"); 3674 pw.println(" Simulate a motion event to bring the device out of deep doze"); 3675 pw.println(" pre-idle-factor [0|1|2]"); 3676 pw.println(" Set a new factor to idle time before step to idle" 3677 + "(inactive_to and idle_after_inactive_to)"); 3678 pw.println(" reset-pre-idle-factor"); 3679 pw.println(" Reset factor to idle time to default"); 3680 } 3681 3682 class Shell extends ShellCommand { 3683 int userId = UserHandle.USER_SYSTEM; 3684 3685 @Override onCommand(String cmd)3686 public int onCommand(String cmd) { 3687 return onShellCommand(this, cmd); 3688 } 3689 3690 @Override onHelp()3691 public void onHelp() { 3692 PrintWriter pw = getOutPrintWriter(); 3693 dumpHelp(pw); 3694 } 3695 } 3696 onShellCommand(Shell shell, String cmd)3697 int onShellCommand(Shell shell, String cmd) { 3698 PrintWriter pw = shell.getOutPrintWriter(); 3699 if ("step".equals(cmd)) { 3700 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 3701 null); 3702 synchronized (this) { 3703 long token = Binder.clearCallingIdentity(); 3704 String arg = shell.getNextArg(); 3705 try { 3706 if (arg == null || "deep".equals(arg)) { 3707 stepIdleStateLocked("s:shell"); 3708 pw.print("Stepped to deep: "); 3709 pw.println(stateToString(mState)); 3710 } else if ("light".equals(arg)) { 3711 stepLightIdleStateLocked("s:shell"); 3712 pw.print("Stepped to light: "); pw.println(lightStateToString(mLightState)); 3713 } else { 3714 pw.println("Unknown idle mode: " + arg); 3715 } 3716 } finally { 3717 Binder.restoreCallingIdentity(token); 3718 } 3719 } 3720 } else if ("force-idle".equals(cmd)) { 3721 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 3722 null); 3723 synchronized (this) { 3724 long token = Binder.clearCallingIdentity(); 3725 String arg = shell.getNextArg(); 3726 try { 3727 if (arg == null || "deep".equals(arg)) { 3728 if (!mDeepEnabled) { 3729 pw.println("Unable to go deep idle; not enabled"); 3730 return -1; 3731 } 3732 mForceIdle = true; 3733 becomeInactiveIfAppropriateLocked(); 3734 int curState = mState; 3735 while (curState != STATE_IDLE) { 3736 stepIdleStateLocked("s:shell"); 3737 if (curState == mState) { 3738 pw.print("Unable to go deep idle; stopped at "); 3739 pw.println(stateToString(mState)); 3740 exitForceIdleLocked(); 3741 return -1; 3742 } 3743 curState = mState; 3744 } 3745 pw.println("Now forced in to deep idle mode"); 3746 } else if ("light".equals(arg)) { 3747 mForceIdle = true; 3748 becomeInactiveIfAppropriateLocked(); 3749 int curLightState = mLightState; 3750 while (curLightState != LIGHT_STATE_IDLE) { 3751 stepLightIdleStateLocked("s:shell"); 3752 if (curLightState == mLightState) { 3753 pw.print("Unable to go light idle; stopped at "); 3754 pw.println(lightStateToString(mLightState)); 3755 exitForceIdleLocked(); 3756 return -1; 3757 } 3758 curLightState = mLightState; 3759 } 3760 pw.println("Now forced in to light idle mode"); 3761 } else { 3762 pw.println("Unknown idle mode: " + arg); 3763 } 3764 } finally { 3765 Binder.restoreCallingIdentity(token); 3766 } 3767 } 3768 } else if ("force-inactive".equals(cmd)) { 3769 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 3770 null); 3771 synchronized (this) { 3772 long token = Binder.clearCallingIdentity(); 3773 try { 3774 mForceIdle = true; 3775 becomeInactiveIfAppropriateLocked(); 3776 pw.print("Light state: "); 3777 pw.print(lightStateToString(mLightState)); 3778 pw.print(", deep state: "); 3779 pw.println(stateToString(mState)); 3780 } finally { 3781 Binder.restoreCallingIdentity(token); 3782 } 3783 } 3784 } else if ("unforce".equals(cmd)) { 3785 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 3786 null); 3787 synchronized (this) { 3788 long token = Binder.clearCallingIdentity(); 3789 try { 3790 exitForceIdleLocked(); 3791 pw.print("Light state: "); 3792 pw.print(lightStateToString(mLightState)); 3793 pw.print(", deep state: "); 3794 pw.println(stateToString(mState)); 3795 } finally { 3796 Binder.restoreCallingIdentity(token); 3797 } 3798 } 3799 } else if ("get".equals(cmd)) { 3800 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 3801 null); 3802 synchronized (this) { 3803 String arg = shell.getNextArg(); 3804 if (arg != null) { 3805 long token = Binder.clearCallingIdentity(); 3806 try { 3807 switch (arg) { 3808 case "light": pw.println(lightStateToString(mLightState)); break; 3809 case "deep": pw.println(stateToString(mState)); break; 3810 case "force": pw.println(mForceIdle); break; 3811 case "quick": pw.println(mQuickDozeActivated); break; 3812 case "screen": pw.println(mScreenOn); break; 3813 case "charging": pw.println(mCharging); break; 3814 case "network": pw.println(mNetworkConnected); break; 3815 default: pw.println("Unknown get option: " + arg); break; 3816 } 3817 } finally { 3818 Binder.restoreCallingIdentity(token); 3819 } 3820 } else { 3821 pw.println("Argument required"); 3822 } 3823 } 3824 } else if ("disable".equals(cmd)) { 3825 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 3826 null); 3827 synchronized (this) { 3828 long token = Binder.clearCallingIdentity(); 3829 String arg = shell.getNextArg(); 3830 try { 3831 boolean becomeActive = false; 3832 boolean valid = false; 3833 if (arg == null || "deep".equals(arg) || "all".equals(arg)) { 3834 valid = true; 3835 if (mDeepEnabled) { 3836 mDeepEnabled = false; 3837 becomeActive = true; 3838 pw.println("Deep idle mode disabled"); 3839 } 3840 } 3841 if (arg == null || "light".equals(arg) || "all".equals(arg)) { 3842 valid = true; 3843 if (mLightEnabled) { 3844 mLightEnabled = false; 3845 becomeActive = true; 3846 pw.println("Light idle mode disabled"); 3847 } 3848 } 3849 if (becomeActive) { 3850 mActiveReason = ACTIVE_REASON_FORCED; 3851 becomeActiveLocked((arg == null ? "all" : arg) + "-disabled", 3852 Process.myUid()); 3853 } 3854 if (!valid) { 3855 pw.println("Unknown idle mode: " + arg); 3856 } 3857 } finally { 3858 Binder.restoreCallingIdentity(token); 3859 } 3860 } 3861 } else if ("enable".equals(cmd)) { 3862 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 3863 null); 3864 synchronized (this) { 3865 long token = Binder.clearCallingIdentity(); 3866 String arg = shell.getNextArg(); 3867 try { 3868 boolean becomeInactive = false; 3869 boolean valid = false; 3870 if (arg == null || "deep".equals(arg) || "all".equals(arg)) { 3871 valid = true; 3872 if (!mDeepEnabled) { 3873 mDeepEnabled = true; 3874 becomeInactive = true; 3875 pw.println("Deep idle mode enabled"); 3876 } 3877 } 3878 if (arg == null || "light".equals(arg) || "all".equals(arg)) { 3879 valid = true; 3880 if (!mLightEnabled) { 3881 mLightEnabled = true; 3882 becomeInactive = true; 3883 pw.println("Light idle mode enable"); 3884 } 3885 } 3886 if (becomeInactive) { 3887 becomeInactiveIfAppropriateLocked(); 3888 } 3889 if (!valid) { 3890 pw.println("Unknown idle mode: " + arg); 3891 } 3892 } finally { 3893 Binder.restoreCallingIdentity(token); 3894 } 3895 } 3896 } else if ("enabled".equals(cmd)) { 3897 synchronized (this) { 3898 String arg = shell.getNextArg(); 3899 if (arg == null || "all".equals(arg)) { 3900 pw.println(mDeepEnabled && mLightEnabled ? "1" : 0); 3901 } else if ("deep".equals(arg)) { 3902 pw.println(mDeepEnabled ? "1" : 0); 3903 } else if ("light".equals(arg)) { 3904 pw.println(mLightEnabled ? "1" : 0); 3905 } else { 3906 pw.println("Unknown idle mode: " + arg); 3907 } 3908 } 3909 } else if ("whitelist".equals(cmd)) { 3910 String arg = shell.getNextArg(); 3911 if (arg != null) { 3912 getContext().enforceCallingOrSelfPermission( 3913 android.Manifest.permission.DEVICE_POWER, null); 3914 long token = Binder.clearCallingIdentity(); 3915 try { 3916 do { 3917 if (arg.length() < 1 || (arg.charAt(0) != '-' 3918 && arg.charAt(0) != '+' && arg.charAt(0) != '=')) { 3919 pw.println("Package must be prefixed with +, -, or =: " + arg); 3920 return -1; 3921 } 3922 char op = arg.charAt(0); 3923 String pkg = arg.substring(1); 3924 if (op == '+') { 3925 if (addPowerSaveWhitelistAppInternal(pkg)) { 3926 pw.println("Added: " + pkg); 3927 } else { 3928 pw.println("Unknown package: " + pkg); 3929 } 3930 } else if (op == '-') { 3931 if (removePowerSaveWhitelistAppInternal(pkg)) { 3932 pw.println("Removed: " + pkg); 3933 } 3934 } else { 3935 pw.println(getPowerSaveWhitelistAppInternal(pkg)); 3936 } 3937 } while ((arg=shell.getNextArg()) != null); 3938 } finally { 3939 Binder.restoreCallingIdentity(token); 3940 } 3941 } else { 3942 synchronized (this) { 3943 for (int j=0; j<mPowerSaveWhitelistAppsExceptIdle.size(); j++) { 3944 pw.print("system-excidle,"); 3945 pw.print(mPowerSaveWhitelistAppsExceptIdle.keyAt(j)); 3946 pw.print(","); 3947 pw.println(mPowerSaveWhitelistAppsExceptIdle.valueAt(j)); 3948 } 3949 for (int j=0; j<mPowerSaveWhitelistApps.size(); j++) { 3950 pw.print("system,"); 3951 pw.print(mPowerSaveWhitelistApps.keyAt(j)); 3952 pw.print(","); 3953 pw.println(mPowerSaveWhitelistApps.valueAt(j)); 3954 } 3955 for (int j=0; j<mPowerSaveWhitelistUserApps.size(); j++) { 3956 pw.print("user,"); 3957 pw.print(mPowerSaveWhitelistUserApps.keyAt(j)); 3958 pw.print(","); 3959 pw.println(mPowerSaveWhitelistUserApps.valueAt(j)); 3960 } 3961 } 3962 } 3963 } else if ("tempwhitelist".equals(cmd)) { 3964 long duration = 10000; 3965 boolean removePkg = false; 3966 String opt; 3967 while ((opt=shell.getNextOption()) != null) { 3968 if ("-u".equals(opt)) { 3969 opt = shell.getNextArg(); 3970 if (opt == null) { 3971 pw.println("-u requires a user number"); 3972 return -1; 3973 } 3974 shell.userId = Integer.parseInt(opt); 3975 } else if ("-d".equals(opt)) { 3976 opt = shell.getNextArg(); 3977 if (opt == null) { 3978 pw.println("-d requires a duration"); 3979 return -1; 3980 } 3981 duration = Long.parseLong(opt); 3982 } else if ("-r".equals(opt)) { 3983 removePkg = true; 3984 } 3985 } 3986 String arg = shell.getNextArg(); 3987 if (arg != null) { 3988 try { 3989 if (removePkg) { 3990 removePowerSaveTempWhitelistAppChecked(arg, shell.userId); 3991 } else { 3992 addPowerSaveTempWhitelistAppChecked(arg, duration, shell.userId, "shell"); 3993 } 3994 } catch (Exception e) { 3995 pw.println("Failed: " + e); 3996 return -1; 3997 } 3998 } else if (removePkg) { 3999 pw.println("[-r] requires a package name"); 4000 return -1; 4001 } else { 4002 dumpTempWhitelistSchedule(pw, false); 4003 } 4004 } else if ("except-idle-whitelist".equals(cmd)) { 4005 getContext().enforceCallingOrSelfPermission( 4006 android.Manifest.permission.DEVICE_POWER, null); 4007 final long token = Binder.clearCallingIdentity(); 4008 try { 4009 String arg = shell.getNextArg(); 4010 if (arg == null) { 4011 pw.println("No arguments given"); 4012 return -1; 4013 } else if ("reset".equals(arg)) { 4014 resetPowerSaveWhitelistExceptIdleInternal(); 4015 } else { 4016 do { 4017 if (arg.length() < 1 || (arg.charAt(0) != '-' 4018 && arg.charAt(0) != '+' && arg.charAt(0) != '=')) { 4019 pw.println("Package must be prefixed with +, -, or =: " + arg); 4020 return -1; 4021 } 4022 char op = arg.charAt(0); 4023 String pkg = arg.substring(1); 4024 if (op == '+') { 4025 if (addPowerSaveWhitelistExceptIdleInternal(pkg)) { 4026 pw.println("Added: " + pkg); 4027 } else { 4028 pw.println("Unknown package: " + pkg); 4029 } 4030 } else if (op == '=') { 4031 pw.println(getPowerSaveWhitelistExceptIdleInternal(pkg)); 4032 } else { 4033 pw.println("Unknown argument: " + arg); 4034 return -1; 4035 } 4036 } while ((arg = shell.getNextArg()) != null); 4037 } 4038 } finally { 4039 Binder.restoreCallingIdentity(token); 4040 } 4041 } else if ("sys-whitelist".equals(cmd)) { 4042 String arg = shell.getNextArg(); 4043 if (arg != null) { 4044 getContext().enforceCallingOrSelfPermission( 4045 android.Manifest.permission.DEVICE_POWER, null); 4046 final long token = Binder.clearCallingIdentity(); 4047 try { 4048 if ("reset".equals(arg)) { 4049 resetSystemPowerWhitelistInternal(); 4050 } else { 4051 do { 4052 if (arg.length() < 1 4053 || (arg.charAt(0) != '-' && arg.charAt(0) != '+')) { 4054 pw.println("Package must be prefixed with + or - " + arg); 4055 return -1; 4056 } 4057 final char op = arg.charAt(0); 4058 final String pkg = arg.substring(1); 4059 switch (op) { 4060 case '+': 4061 if (restoreSystemPowerWhitelistAppInternal(pkg)) { 4062 pw.println("Restored " + pkg); 4063 } 4064 break; 4065 case '-': 4066 if (removeSystemPowerWhitelistAppInternal(pkg)) { 4067 pw.println("Removed " + pkg); 4068 } 4069 break; 4070 } 4071 } while ((arg = shell.getNextArg()) != null); 4072 } 4073 } finally { 4074 Binder.restoreCallingIdentity(token); 4075 } 4076 } else { 4077 synchronized (this) { 4078 for (int j = 0; j < mPowerSaveWhitelistApps.size(); j++) { 4079 pw.print(mPowerSaveWhitelistApps.keyAt(j)); 4080 pw.print(","); 4081 pw.println(mPowerSaveWhitelistApps.valueAt(j)); 4082 } 4083 } 4084 } 4085 } else if ("motion".equals(cmd)) { 4086 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 4087 null); 4088 synchronized (this) { 4089 long token = Binder.clearCallingIdentity(); 4090 try { 4091 motionLocked(); 4092 pw.print("Light state: "); 4093 pw.print(lightStateToString(mLightState)); 4094 pw.print(", deep state: "); 4095 pw.println(stateToString(mState)); 4096 } finally { 4097 Binder.restoreCallingIdentity(token); 4098 } 4099 } 4100 } else if ("pre-idle-factor".equals(cmd)) { 4101 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 4102 null); 4103 synchronized (this) { 4104 long token = Binder.clearCallingIdentity(); 4105 int ret = SET_IDLE_FACTOR_RESULT_UNINIT; 4106 try { 4107 String arg = shell.getNextArg(); 4108 boolean valid = false; 4109 int mode = 0; 4110 if (arg != null) { 4111 mode = Integer.parseInt(arg); 4112 ret = setPreIdleTimeoutMode(mode); 4113 if (ret == SET_IDLE_FACTOR_RESULT_OK) { 4114 pw.println("pre-idle-factor: " + mode); 4115 valid = true; 4116 } else if (ret == SET_IDLE_FACTOR_RESULT_NOT_SUPPORT) { 4117 valid = true; 4118 pw.println("Deep idle not supported"); 4119 } else if (ret == SET_IDLE_FACTOR_RESULT_IGNORED) { 4120 valid = true; 4121 pw.println("Idle timeout factor not changed"); 4122 } 4123 } 4124 if (!valid) { 4125 pw.println("Unknown idle timeout factor: " + arg 4126 + ",(error code: " + ret + ")"); 4127 } 4128 } catch (NumberFormatException e) { 4129 pw.println("Unknown idle timeout factor" 4130 + ",(error code: " + ret + ")"); 4131 } finally { 4132 Binder.restoreCallingIdentity(token); 4133 } 4134 } 4135 } else if ("reset-pre-idle-factor".equals(cmd)) { 4136 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 4137 null); 4138 synchronized (this) { 4139 long token = Binder.clearCallingIdentity(); 4140 try { 4141 resetPreIdleTimeoutMode(); 4142 } finally { 4143 Binder.restoreCallingIdentity(token); 4144 } 4145 } 4146 } else { 4147 return shell.handleDefaultCommands(cmd); 4148 } 4149 return 0; 4150 } 4151 dump(FileDescriptor fd, PrintWriter pw, String[] args)4152 void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 4153 if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return; 4154 4155 if (args != null) { 4156 int userId = UserHandle.USER_SYSTEM; 4157 for (int i=0; i<args.length; i++) { 4158 String arg = args[i]; 4159 if ("-h".equals(arg)) { 4160 dumpHelp(pw); 4161 return; 4162 } else if ("-u".equals(arg)) { 4163 i++; 4164 if (i < args.length) { 4165 arg = args[i]; 4166 userId = Integer.parseInt(arg); 4167 } 4168 } else if ("-a".equals(arg)) { 4169 // Ignore, we always dump all. 4170 } else if (arg.length() > 0 && arg.charAt(0) == '-'){ 4171 pw.println("Unknown option: " + arg); 4172 return; 4173 } else { 4174 Shell shell = new Shell(); 4175 shell.userId = userId; 4176 String[] newArgs = new String[args.length-i]; 4177 System.arraycopy(args, i, newArgs, 0, args.length-i); 4178 shell.exec(mBinderService, null, fd, null, newArgs, null, 4179 new ResultReceiver(null)); 4180 return; 4181 } 4182 } 4183 } 4184 4185 synchronized (this) { 4186 mConstants.dump(pw); 4187 4188 if (mEventCmds[0] != EVENT_NULL) { 4189 pw.println(" Idling history:"); 4190 long now = SystemClock.elapsedRealtime(); 4191 for (int i=EVENT_BUFFER_SIZE-1; i>=0; i--) { 4192 int cmd = mEventCmds[i]; 4193 if (cmd == EVENT_NULL) { 4194 continue; 4195 } 4196 String label; 4197 switch (mEventCmds[i]) { 4198 case EVENT_NORMAL: label = " normal"; break; 4199 case EVENT_LIGHT_IDLE: label = " light-idle"; break; 4200 case EVENT_LIGHT_MAINTENANCE: label = "light-maint"; break; 4201 case EVENT_DEEP_IDLE: label = " deep-idle"; break; 4202 case EVENT_DEEP_MAINTENANCE: label = " deep-maint"; break; 4203 default: label = " ??"; break; 4204 } 4205 pw.print(" "); 4206 pw.print(label); 4207 pw.print(": "); 4208 TimeUtils.formatDuration(mEventTimes[i], now, pw); 4209 if (mEventReasons[i] != null) { 4210 pw.print(" ("); 4211 pw.print(mEventReasons[i]); 4212 pw.print(")"); 4213 } 4214 pw.println(); 4215 4216 } 4217 } 4218 4219 int size = mPowerSaveWhitelistAppsExceptIdle.size(); 4220 if (size > 0) { 4221 pw.println(" Whitelist (except idle) system apps:"); 4222 for (int i = 0; i < size; i++) { 4223 pw.print(" "); 4224 pw.println(mPowerSaveWhitelistAppsExceptIdle.keyAt(i)); 4225 } 4226 } 4227 size = mPowerSaveWhitelistApps.size(); 4228 if (size > 0) { 4229 pw.println(" Whitelist system apps:"); 4230 for (int i = 0; i < size; i++) { 4231 pw.print(" "); 4232 pw.println(mPowerSaveWhitelistApps.keyAt(i)); 4233 } 4234 } 4235 size = mRemovedFromSystemWhitelistApps.size(); 4236 if (size > 0) { 4237 pw.println(" Removed from whitelist system apps:"); 4238 for (int i = 0; i < size; i++) { 4239 pw.print(" "); 4240 pw.println(mRemovedFromSystemWhitelistApps.keyAt(i)); 4241 } 4242 } 4243 size = mPowerSaveWhitelistUserApps.size(); 4244 if (size > 0) { 4245 pw.println(" Whitelist user apps:"); 4246 for (int i = 0; i < size; i++) { 4247 pw.print(" "); 4248 pw.println(mPowerSaveWhitelistUserApps.keyAt(i)); 4249 } 4250 } 4251 size = mPowerSaveWhitelistExceptIdleAppIds.size(); 4252 if (size > 0) { 4253 pw.println(" Whitelist (except idle) all app ids:"); 4254 for (int i = 0; i < size; i++) { 4255 pw.print(" "); 4256 pw.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i)); 4257 pw.println(); 4258 } 4259 } 4260 size = mPowerSaveWhitelistUserAppIds.size(); 4261 if (size > 0) { 4262 pw.println(" Whitelist user app ids:"); 4263 for (int i = 0; i < size; i++) { 4264 pw.print(" "); 4265 pw.print(mPowerSaveWhitelistUserAppIds.keyAt(i)); 4266 pw.println(); 4267 } 4268 } 4269 size = mPowerSaveWhitelistAllAppIds.size(); 4270 if (size > 0) { 4271 pw.println(" Whitelist all app ids:"); 4272 for (int i = 0; i < size; i++) { 4273 pw.print(" "); 4274 pw.print(mPowerSaveWhitelistAllAppIds.keyAt(i)); 4275 pw.println(); 4276 } 4277 } 4278 dumpTempWhitelistSchedule(pw, true); 4279 4280 size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0; 4281 if (size > 0) { 4282 pw.println(" Temp whitelist app ids:"); 4283 for (int i = 0; i < size; i++) { 4284 pw.print(" "); 4285 pw.print(mTempWhitelistAppIdArray[i]); 4286 pw.println(); 4287 } 4288 } 4289 4290 pw.print(" mLightEnabled="); pw.print(mLightEnabled); 4291 pw.print(" mDeepEnabled="); pw.println(mDeepEnabled); 4292 pw.print(" mForceIdle="); pw.println(mForceIdle); 4293 pw.print(" mUseMotionSensor="); pw.print(mUseMotionSensor); 4294 if (mUseMotionSensor) { 4295 pw.print(" mMotionSensor="); pw.println(mMotionSensor); 4296 } else { 4297 pw.println(); 4298 } 4299 pw.print(" mScreenOn="); pw.println(mScreenOn); 4300 pw.print(" mScreenLocked="); pw.println(mScreenLocked); 4301 pw.print(" mNetworkConnected="); pw.println(mNetworkConnected); 4302 pw.print(" mCharging="); pw.println(mCharging); 4303 if (mConstraints.size() != 0) { 4304 pw.println(" mConstraints={"); 4305 for (int i = 0; i < mConstraints.size(); i++) { 4306 final DeviceIdleConstraintTracker tracker = mConstraints.valueAt(i); 4307 pw.print(" \""); pw.print(tracker.name); pw.print("\"="); 4308 if (tracker.minState == mState) { 4309 pw.println(tracker.active); 4310 } else { 4311 pw.print("ignored <mMinState="); pw.print(stateToString(tracker.minState)); 4312 pw.println(">"); 4313 } 4314 } 4315 pw.println(" }"); 4316 } 4317 if (mUseMotionSensor) { 4318 pw.print(" mMotionActive="); pw.println(mMotionListener.active); 4319 pw.print(" mNotMoving="); pw.println(mNotMoving); 4320 } 4321 pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHasGps="); 4322 pw.print(mHasGps); pw.print(" mHasNetwork="); 4323 pw.print(mHasNetworkLocation); pw.print(" mLocated="); pw.println(mLocated); 4324 if (mLastGenericLocation != null) { 4325 pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation); 4326 } 4327 if (mLastGpsLocation != null) { 4328 pw.print(" mLastGpsLocation="); pw.println(mLastGpsLocation); 4329 } 4330 pw.print(" mState="); pw.print(stateToString(mState)); 4331 pw.print(" mLightState="); 4332 pw.println(lightStateToString(mLightState)); 4333 pw.print(" mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw); 4334 pw.println(); 4335 if (mActiveIdleOpCount != 0) { 4336 pw.print(" mActiveIdleOpCount="); pw.println(mActiveIdleOpCount); 4337 } 4338 if (mNextAlarmTime != 0) { 4339 pw.print(" mNextAlarmTime="); 4340 TimeUtils.formatDuration(mNextAlarmTime, SystemClock.elapsedRealtime(), pw); 4341 pw.println(); 4342 } 4343 if (mNextIdlePendingDelay != 0) { 4344 pw.print(" mNextIdlePendingDelay="); 4345 TimeUtils.formatDuration(mNextIdlePendingDelay, pw); 4346 pw.println(); 4347 } 4348 if (mNextIdleDelay != 0) { 4349 pw.print(" mNextIdleDelay="); 4350 TimeUtils.formatDuration(mNextIdleDelay, pw); 4351 pw.println(); 4352 } 4353 if (mNextLightIdleDelay != 0) { 4354 pw.print(" mNextIdleDelay="); 4355 TimeUtils.formatDuration(mNextLightIdleDelay, pw); 4356 pw.println(); 4357 } 4358 if (mNextLightAlarmTime != 0) { 4359 pw.print(" mNextLightAlarmTime="); 4360 TimeUtils.formatDuration(mNextLightAlarmTime, SystemClock.elapsedRealtime(), pw); 4361 pw.println(); 4362 } 4363 if (mCurIdleBudget != 0) { 4364 pw.print(" mCurIdleBudget="); 4365 TimeUtils.formatDuration(mCurIdleBudget, pw); 4366 pw.println(); 4367 } 4368 if (mMaintenanceStartTime != 0) { 4369 pw.print(" mMaintenanceStartTime="); 4370 TimeUtils.formatDuration(mMaintenanceStartTime, SystemClock.elapsedRealtime(), pw); 4371 pw.println(); 4372 } 4373 if (mJobsActive) { 4374 pw.print(" mJobsActive="); pw.println(mJobsActive); 4375 } 4376 if (mAlarmsActive) { 4377 pw.print(" mAlarmsActive="); pw.println(mAlarmsActive); 4378 } 4379 if (Math.abs(mPreIdleFactor - 1.0f) > MIN_PRE_IDLE_FACTOR_CHANGE) { 4380 pw.print(" mPreIdleFactor="); pw.println(mPreIdleFactor); 4381 } 4382 } 4383 } 4384 dumpTempWhitelistSchedule(PrintWriter pw, boolean printTitle)4385 void dumpTempWhitelistSchedule(PrintWriter pw, boolean printTitle) { 4386 final int size = mTempWhitelistAppIdEndTimes.size(); 4387 if (size > 0) { 4388 String prefix = ""; 4389 if (printTitle) { 4390 pw.println(" Temp whitelist schedule:"); 4391 prefix = " "; 4392 } 4393 final long timeNow = SystemClock.elapsedRealtime(); 4394 for (int i = 0; i < size; i++) { 4395 pw.print(prefix); 4396 pw.print("UID="); 4397 pw.print(mTempWhitelistAppIdEndTimes.keyAt(i)); 4398 pw.print(": "); 4399 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.valueAt(i); 4400 TimeUtils.formatDuration(entry.first.value, timeNow, pw); 4401 pw.print(" - "); 4402 pw.println(entry.second); 4403 } 4404 } 4405 } 4406 } 4407