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 static android.os.PowerExemptionManager.REASON_SHELL; 20 import static android.os.PowerExemptionManager.REASON_UNKNOWN; 21 import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED; 22 import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_NONE; 23 import static android.os.Process.INVALID_UID; 24 25 import android.Manifest; 26 import android.annotation.NonNull; 27 import android.annotation.Nullable; 28 import android.annotation.SuppressLint; 29 import android.app.ActivityManager; 30 import android.app.ActivityManagerInternal; 31 import android.app.AlarmManager; 32 import android.app.BroadcastOptions; 33 import android.content.BroadcastReceiver; 34 import android.content.Context; 35 import android.content.IIntentReceiver; 36 import android.content.Intent; 37 import android.content.IntentFilter; 38 import android.content.pm.ApplicationInfo; 39 import android.content.pm.PackageManager; 40 import android.content.pm.PackageManager.NameNotFoundException; 41 import android.content.pm.PackageManagerInternal; 42 import android.content.res.Resources; 43 import android.hardware.Sensor; 44 import android.hardware.SensorEvent; 45 import android.hardware.SensorEventListener; 46 import android.hardware.SensorManager; 47 import android.hardware.TriggerEvent; 48 import android.hardware.TriggerEventListener; 49 import android.location.Location; 50 import android.location.LocationListener; 51 import android.location.LocationManager; 52 import android.location.LocationRequest; 53 import android.net.ConnectivityManager; 54 import android.net.INetworkPolicyManager; 55 import android.net.NetworkInfo; 56 import android.net.Uri; 57 import android.os.BatteryManager; 58 import android.os.BatteryStats; 59 import android.os.Binder; 60 import android.os.Bundle; 61 import android.os.Environment; 62 import android.os.Handler; 63 import android.os.IDeviceIdleController; 64 import android.os.Looper; 65 import android.os.Message; 66 import android.os.PowerExemptionManager; 67 import android.os.PowerExemptionManager.ReasonCode; 68 import android.os.PowerExemptionManager.TempAllowListType; 69 import android.os.PowerManager; 70 import android.os.PowerManager.ServiceType; 71 import android.os.PowerManagerInternal; 72 import android.os.Process; 73 import android.os.RemoteException; 74 import android.os.ResultReceiver; 75 import android.os.ServiceManager; 76 import android.os.ShellCallback; 77 import android.os.ShellCommand; 78 import android.os.SystemClock; 79 import android.os.Trace; 80 import android.os.UserHandle; 81 import android.provider.DeviceConfig; 82 import android.telephony.TelephonyCallback; 83 import android.telephony.TelephonyManager; 84 import android.telephony.emergency.EmergencyNumber; 85 import android.util.ArrayMap; 86 import android.util.ArraySet; 87 import android.util.AtomicFile; 88 import android.util.MutableLong; 89 import android.util.Pair; 90 import android.util.Slog; 91 import android.util.SparseArray; 92 import android.util.SparseBooleanArray; 93 import android.util.TimeUtils; 94 import android.util.Xml; 95 96 import com.android.internal.annotations.GuardedBy; 97 import com.android.internal.annotations.VisibleForTesting; 98 import com.android.internal.app.IBatteryStats; 99 import com.android.internal.util.ArrayUtils; 100 import com.android.internal.util.DumpUtils; 101 import com.android.internal.util.FastXmlSerializer; 102 import com.android.internal.util.XmlUtils; 103 import com.android.modules.expresslog.Counter; 104 import com.android.server.am.BatteryStatsService; 105 import com.android.server.deviceidle.ConstraintController; 106 import com.android.server.deviceidle.DeviceIdleConstraintTracker; 107 import com.android.server.deviceidle.IDeviceIdleConstraint; 108 import com.android.server.deviceidle.TvConstraintController; 109 import com.android.server.net.NetworkPolicyManagerInternal; 110 import com.android.server.wm.ActivityTaskManagerInternal; 111 112 import org.xmlpull.v1.XmlPullParser; 113 import org.xmlpull.v1.XmlPullParserException; 114 import org.xmlpull.v1.XmlSerializer; 115 116 import java.io.ByteArrayOutputStream; 117 import java.io.File; 118 import java.io.FileDescriptor; 119 import java.io.FileInputStream; 120 import java.io.FileNotFoundException; 121 import java.io.FileOutputStream; 122 import java.io.IOException; 123 import java.io.PrintWriter; 124 import java.nio.charset.StandardCharsets; 125 import java.util.Arrays; 126 import java.util.Collections; 127 import java.util.List; 128 import java.util.stream.Collectors; 129 130 /** 131 * Keeps track of device idleness and drives low power mode based on that. 132 * 133 * Test: atest com.android.server.DeviceIdleControllerTest 134 * 135 * Current idling state machine (as of Android Q). This can be visualized using Graphviz: 136 <pre> 137 138 digraph { 139 subgraph cluster_legend { 140 label="Legend" 141 142 wakeup_alarm [label="Entering this state requires a wakeup alarm",color=red,shape=box] 143 nonwakeup_alarm [ 144 label="This state can be entered from a non-wakeup alarm",color=blue,shape=oval 145 ] 146 no_alarm [label="This state doesn't require an alarm",color=black,shape=diamond] 147 } 148 149 subgraph deep { 150 label="deep"; 151 152 STATE_ACTIVE [ 153 label="STATE_ACTIVE\nScreen on OR charging OR alarm going off soon\n" 154 + "OR active emergency call", 155 color=black,shape=diamond 156 ] 157 STATE_INACTIVE [ 158 label="STATE_INACTIVE\nScreen off AND not charging AND no active emergency call", 159 color=black,shape=diamond 160 ] 161 STATE_QUICK_DOZE_DELAY [ 162 label="STATE_QUICK_DOZE_DELAY\n" 163 + "Screen off AND not charging AND no active emergency call\n" 164 + "Location, motion detection, and significant motion monitoring turned off", 165 color=black,shape=diamond 166 ] 167 STATE_IDLE_PENDING [ 168 label="STATE_IDLE_PENDING\nSignificant motion monitoring turned on", 169 color=red,shape=box 170 ] 171 STATE_SENSING [label="STATE_SENSING\nMonitoring for ANY motion",color=red,shape=box] 172 STATE_LOCATING [ 173 label="STATE_LOCATING\nRequesting location, motion monitoring still on", 174 color=red,shape=box 175 ] 176 STATE_IDLE [ 177 label="STATE_IDLE\nLocation and motion detection turned off\n" 178 + "Significant motion monitoring state unchanged", 179 color=red,shape=box 180 ] 181 STATE_IDLE_MAINTENANCE [label="STATE_IDLE_MAINTENANCE\n",color=red,shape=box] 182 183 STATE_ACTIVE -> STATE_INACTIVE [ 184 label="becomeInactiveIfAppropriateLocked() AND Quick Doze not enabled" 185 ] 186 STATE_ACTIVE -> STATE_QUICK_DOZE_DELAY [ 187 label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled" 188 ] 189 190 STATE_INACTIVE -> STATE_ACTIVE [ 191 label="handleMotionDetectedLocked(), becomeActiveLocked()" 192 ] 193 STATE_INACTIVE -> STATE_IDLE_PENDING [label="stepIdleStateLocked()"] 194 STATE_INACTIVE -> STATE_QUICK_DOZE_DELAY [ 195 label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled" 196 ] 197 198 STATE_IDLE_PENDING -> STATE_ACTIVE [ 199 label="handleMotionDetectedLocked(), becomeActiveLocked()" 200 ] 201 STATE_IDLE_PENDING -> STATE_SENSING [label="stepIdleStateLocked()"] 202 STATE_IDLE_PENDING -> STATE_QUICK_DOZE_DELAY [ 203 label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled" 204 ] 205 206 STATE_SENSING -> STATE_ACTIVE [ 207 label="handleMotionDetectedLocked(), becomeActiveLocked()" 208 ] 209 STATE_SENSING -> STATE_LOCATING [label="stepIdleStateLocked()"] 210 STATE_SENSING -> STATE_QUICK_DOZE_DELAY [ 211 label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled" 212 ] 213 STATE_SENSING -> STATE_IDLE [ 214 label="stepIdleStateLocked()\n" 215 + "No Location Manager OR (no Network provider AND no GPS provider)" 216 ] 217 218 STATE_LOCATING -> STATE_ACTIVE [ 219 label="handleMotionDetectedLocked(), becomeActiveLocked()" 220 ] 221 STATE_LOCATING -> STATE_QUICK_DOZE_DELAY [ 222 label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled" 223 ] 224 STATE_LOCATING -> STATE_IDLE [label="stepIdleStateLocked()"] 225 226 STATE_QUICK_DOZE_DELAY -> STATE_ACTIVE [ 227 label="handleMotionDetectedLocked(), becomeActiveLocked()" 228 ] 229 STATE_QUICK_DOZE_DELAY -> STATE_IDLE [label="stepIdleStateLocked()"] 230 231 STATE_IDLE -> STATE_ACTIVE [label="handleMotionDetectedLocked(), becomeActiveLocked()"] 232 STATE_IDLE -> STATE_IDLE_MAINTENANCE [label="stepIdleStateLocked()"] 233 234 STATE_IDLE_MAINTENANCE -> STATE_ACTIVE [ 235 label="handleMotionDetectedLocked(), becomeActiveLocked()" 236 ] 237 STATE_IDLE_MAINTENANCE -> STATE_IDLE [ 238 label="stepIdleStateLocked(), exitMaintenanceEarlyIfNeededLocked()" 239 ] 240 } 241 242 subgraph light { 243 label="light" 244 245 LIGHT_STATE_ACTIVE [ 246 label="LIGHT_STATE_ACTIVE\n" 247 + "Screen on OR charging OR alarm going off soon OR active emergency call", 248 color=black,shape=diamond 249 ] 250 LIGHT_STATE_INACTIVE [ 251 label="LIGHT_STATE_INACTIVE\nScreen off AND not charging AND no active emergency call", 252 color=black,shape=diamond 253 ] 254 LIGHT_STATE_IDLE [label="LIGHT_STATE_IDLE\n",color=red,shape=box] 255 LIGHT_STATE_WAITING_FOR_NETWORK [ 256 label="LIGHT_STATE_WAITING_FOR_NETWORK\n" 257 + "Coming out of LIGHT_STATE_IDLE, waiting for network", 258 color=black,shape=diamond 259 ] 260 LIGHT_STATE_IDLE_MAINTENANCE [ 261 label="LIGHT_STATE_IDLE_MAINTENANCE\n",color=red,shape=box 262 ] 263 LIGHT_STATE_OVERRIDE [ 264 label="LIGHT_STATE_OVERRIDE\nDevice in deep doze, light no longer changing states" 265 ] 266 267 LIGHT_STATE_ACTIVE -> LIGHT_STATE_INACTIVE [ 268 label="becomeInactiveIfAppropriateLocked()" 269 ] 270 LIGHT_STATE_ACTIVE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"] 271 272 LIGHT_STATE_INACTIVE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"] 273 LIGHT_STATE_INACTIVE -> LIGHT_STATE_IDLE [label="some time transpires"] 274 LIGHT_STATE_INACTIVE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"] 275 276 LIGHT_STATE_IDLE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"] 277 LIGHT_STATE_IDLE -> LIGHT_STATE_WAITING_FOR_NETWORK [label="no network"] 278 LIGHT_STATE_IDLE -> LIGHT_STATE_IDLE_MAINTENANCE 279 LIGHT_STATE_IDLE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"] 280 281 LIGHT_STATE_WAITING_FOR_NETWORK -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"] 282 LIGHT_STATE_WAITING_FOR_NETWORK -> LIGHT_STATE_IDLE_MAINTENANCE 283 LIGHT_STATE_WAITING_FOR_NETWORK -> LIGHT_STATE_OVERRIDE [ 284 label="deep goes to STATE_IDLE" 285 ] 286 287 LIGHT_STATE_IDLE_MAINTENANCE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"] 288 LIGHT_STATE_IDLE_MAINTENANCE -> LIGHT_STATE_IDLE [ 289 label="stepLightIdleStateLocked(), exitMaintenanceEarlyIfNeededLocked()" 290 ] 291 LIGHT_STATE_IDLE_MAINTENANCE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"] 292 293 LIGHT_STATE_OVERRIDE -> LIGHT_STATE_ACTIVE [ 294 label="handleMotionDetectedLocked(), becomeActiveLocked()" 295 ] 296 } 297 } 298 </pre> 299 */ 300 public class DeviceIdleController extends SystemService 301 implements AnyMotionDetector.DeviceIdleCallback { 302 private static final String TAG = "DeviceIdleController"; 303 304 private static final String USER_ALLOWLIST_ADDITION_METRIC_ID = 305 "battery.value_app_added_to_power_allowlist"; 306 307 private static final String USER_ALLOWLIST_REMOVAL_METRIC_ID = 308 "battery.value_app_removed_from_power_allowlist"; 309 310 private static final boolean DEBUG = false; 311 312 private static final boolean COMPRESS_TIME = false; 313 314 private static final int EVENT_BUFFER_SIZE = 100; 315 316 private AlarmManager mAlarmManager; 317 private AlarmManagerInternal mLocalAlarmManager; 318 private IBatteryStats mBatteryStats; 319 private ActivityManagerInternal mLocalActivityManager; 320 private ActivityTaskManagerInternal mLocalActivityTaskManager; 321 private DeviceIdleInternal mLocalService; 322 private PackageManagerInternal mPackageManagerInternal; 323 private PowerManagerInternal mLocalPowerManager; 324 private PowerManager mPowerManager; 325 private INetworkPolicyManager mNetworkPolicyManager; 326 private SensorManager mSensorManager; 327 private final boolean mUseMotionSensor; 328 private Sensor mMotionSensor; 329 private final boolean mIsLocationPrefetchEnabled; 330 @Nullable 331 private LocationRequest mLocationRequest; 332 private Intent mIdleIntent; 333 private Bundle mIdleIntentOptions; 334 private Intent mLightIdleIntent; 335 private Bundle mLightIdleIntentOptions; 336 private Intent mPowerSaveWhitelistChangedIntent; 337 private Bundle mPowerSaveWhitelistChangedOptions; 338 private Intent mPowerSaveTempWhitelistChangedIntent; 339 private Bundle mPowerSaveTempWhilelistChangedOptions; 340 private AnyMotionDetector mAnyMotionDetector; 341 private final AppStateTrackerImpl mAppStateTracker; 342 @GuardedBy("this") 343 private boolean mLightEnabled; 344 @GuardedBy("this") 345 private boolean mDeepEnabled; 346 @GuardedBy("this") 347 private boolean mQuickDozeActivated; 348 @GuardedBy("this") 349 private boolean mQuickDozeActivatedWhileIdling; 350 @GuardedBy("this") 351 private boolean mForceIdle; 352 @GuardedBy("this") 353 private boolean mNetworkConnected; 354 @GuardedBy("this") 355 private boolean mScreenOn; 356 @GuardedBy("this") 357 private boolean mCharging; 358 @GuardedBy("this") 359 private boolean mNotMoving; 360 @GuardedBy("this") 361 private boolean mLocating; 362 @GuardedBy("this") 363 private boolean mLocated; 364 @GuardedBy("this") 365 private boolean mHasGps; 366 @GuardedBy("this") 367 private boolean mHasFusedLocation; 368 @GuardedBy("this") 369 private Location mLastGenericLocation; 370 @GuardedBy("this") 371 private Location mLastGpsLocation; 372 373 /** Time in the elapsed realtime timebase when this listener last received a motion event. */ 374 @GuardedBy("this") 375 private long mLastMotionEventElapsed; 376 377 // Current locked state of the screen 378 @GuardedBy("this") 379 private boolean mScreenLocked; 380 @GuardedBy("this") 381 private int mNumBlockingConstraints = 0; 382 383 /** 384 * Constraints are the "handbrakes" that stop the device from moving into a lower state until 385 * every one is released at the same time. 386 * 387 * @see #registerDeviceIdleConstraintInternal(IDeviceIdleConstraint, String, int) 388 */ 389 private final ArrayMap<IDeviceIdleConstraint, DeviceIdleConstraintTracker> 390 mConstraints = new ArrayMap<>(); 391 private ConstraintController mConstraintController; 392 393 /** Device is currently active. */ 394 @VisibleForTesting 395 static final int STATE_ACTIVE = 0; 396 /** Device is inactive (screen off, no motion) and we are waiting to for idle. */ 397 @VisibleForTesting 398 static final int STATE_INACTIVE = 1; 399 /** Device is past the initial inactive period, and waiting for the next idle period. */ 400 @VisibleForTesting 401 static final int STATE_IDLE_PENDING = 2; 402 /** Device is currently sensing motion. */ 403 @VisibleForTesting 404 static final int STATE_SENSING = 3; 405 /** Device is currently finding location (and may still be sensing). */ 406 @VisibleForTesting 407 static final int STATE_LOCATING = 4; 408 /** Device is in the idle state, trying to stay asleep as much as possible. */ 409 @VisibleForTesting 410 static final int STATE_IDLE = 5; 411 /** Device is in the idle state, but temporarily out of idle to do regular maintenance. */ 412 @VisibleForTesting 413 static final int STATE_IDLE_MAINTENANCE = 6; 414 /** 415 * Device is inactive and should go straight into idle (foregoing motion and location 416 * monitoring), but allow some time for current work to complete first. 417 */ 418 @VisibleForTesting 419 static final int STATE_QUICK_DOZE_DELAY = 7; 420 421 private static final int ACTIVE_REASON_UNKNOWN = 0; 422 private static final int ACTIVE_REASON_MOTION = 1; 423 private static final int ACTIVE_REASON_SCREEN = 2; 424 private static final int ACTIVE_REASON_CHARGING = 3; 425 private static final int ACTIVE_REASON_UNLOCKED = 4; 426 private static final int ACTIVE_REASON_FROM_BINDER_CALL = 5; 427 private static final int ACTIVE_REASON_FORCED = 6; 428 private static final int ACTIVE_REASON_ALARM = 7; 429 private static final int ACTIVE_REASON_EMERGENCY_CALL = 8; 430 @VisibleForTesting 431 static final int SET_IDLE_FACTOR_RESULT_UNINIT = -1; 432 @VisibleForTesting 433 static final int SET_IDLE_FACTOR_RESULT_IGNORED = 0; 434 @VisibleForTesting 435 static final int SET_IDLE_FACTOR_RESULT_OK = 1; 436 @VisibleForTesting 437 static final int SET_IDLE_FACTOR_RESULT_NOT_SUPPORT = 2; 438 @VisibleForTesting 439 static final int SET_IDLE_FACTOR_RESULT_INVALID = 3; 440 @VisibleForTesting 441 static final long MIN_STATE_STEP_ALARM_CHANGE = 60 * 1000; 442 @VisibleForTesting 443 static final float MIN_PRE_IDLE_FACTOR_CHANGE = 0.05f; 444 445 @VisibleForTesting stateToString(int state)446 static String stateToString(int state) { 447 switch (state) { 448 case STATE_ACTIVE: return "ACTIVE"; 449 case STATE_INACTIVE: return "INACTIVE"; 450 case STATE_IDLE_PENDING: return "IDLE_PENDING"; 451 case STATE_SENSING: return "SENSING"; 452 case STATE_LOCATING: return "LOCATING"; 453 case STATE_IDLE: return "IDLE"; 454 case STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE"; 455 case STATE_QUICK_DOZE_DELAY: return "QUICK_DOZE_DELAY"; 456 default: return Integer.toString(state); 457 } 458 } 459 460 /** Device is currently active. */ 461 @VisibleForTesting 462 static final int LIGHT_STATE_ACTIVE = 0; 463 /** Device is inactive (screen off) and we are waiting to for the first light idle. */ 464 @VisibleForTesting 465 static final int LIGHT_STATE_INACTIVE = 1; 466 /** Device is in the light idle state, trying to stay asleep as much as possible. */ 467 @VisibleForTesting 468 static final int LIGHT_STATE_IDLE = 4; 469 /** Device is in the light idle state, we want to go in to idle maintenance but are 470 * waiting for network connectivity before doing so. */ 471 @VisibleForTesting 472 static final int LIGHT_STATE_WAITING_FOR_NETWORK = 5; 473 /** Device is in the light idle state, but temporarily out of idle to do regular maintenance. */ 474 @VisibleForTesting 475 static final int LIGHT_STATE_IDLE_MAINTENANCE = 6; 476 /** Device light idle state is overridden, now applying deep doze state. */ 477 @VisibleForTesting 478 static final int LIGHT_STATE_OVERRIDE = 7; 479 480 @VisibleForTesting lightStateToString(int state)481 static String lightStateToString(int state) { 482 switch (state) { 483 case LIGHT_STATE_ACTIVE: return "ACTIVE"; 484 case LIGHT_STATE_INACTIVE: return "INACTIVE"; 485 case LIGHT_STATE_IDLE: return "IDLE"; 486 case LIGHT_STATE_WAITING_FOR_NETWORK: return "WAITING_FOR_NETWORK"; 487 case LIGHT_STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE"; 488 case LIGHT_STATE_OVERRIDE: return "OVERRIDE"; 489 default: return Integer.toString(state); 490 } 491 } 492 493 @GuardedBy("this") 494 private int mState; 495 @GuardedBy("this") 496 private int mLightState; 497 498 @GuardedBy("this") 499 private long mInactiveTimeout; 500 @GuardedBy("this") 501 private long mNextAlarmTime; 502 @GuardedBy("this") 503 private long mNextIdlePendingDelay; 504 @GuardedBy("this") 505 private long mNextIdleDelay; 506 @GuardedBy("this") 507 private long mNextLightIdleDelay; 508 @GuardedBy("this") 509 private long mNextLightIdleDelayFlex; 510 @GuardedBy("this") 511 private long mNextLightAlarmTime; 512 @GuardedBy("this") 513 private long mNextSensingTimeoutAlarmTime; 514 515 /** How long a light idle maintenance window should last. */ 516 @GuardedBy("this") 517 private long mCurLightIdleBudget; 518 519 /** 520 * Start time of the current (light or full) maintenance window, in the elapsed timebase. Valid 521 * only if {@link #mState} == {@link #STATE_IDLE_MAINTENANCE} or 522 * {@link #mLightState} == {@link #LIGHT_STATE_IDLE_MAINTENANCE}. 523 */ 524 @GuardedBy("this") 525 private long mMaintenanceStartTime; 526 @GuardedBy("this") 527 private long mIdleStartTime; 528 529 @GuardedBy("this") 530 private int mActiveIdleOpCount; 531 private PowerManager.WakeLock mActiveIdleWakeLock; // held when there are operations in progress 532 private PowerManager.WakeLock mGoingIdleWakeLock; // held when we are going idle so hardware 533 // (especially NetworkPolicyManager) can shut 534 // down. 535 @GuardedBy("this") 536 private boolean mJobsActive; 537 @GuardedBy("this") 538 private boolean mAlarmsActive; 539 540 /* Factor to apply to INACTIVE_TIMEOUT and IDLE_AFTER_INACTIVE_TIMEOUT in order to enter 541 * STATE_IDLE faster or slower. Don't apply this to SENSING_TIMEOUT or LOCATING_TIMEOUT because: 542 * - Both of them are shorter 543 * - Device sensor might take time be to become be stabilized 544 * Also don't apply the factor if the device is in motion because device motion provides a 545 * stronger signal than a prediction algorithm. 546 */ 547 @GuardedBy("this") 548 private float mPreIdleFactor; 549 @GuardedBy("this") 550 private float mLastPreIdleFactor; 551 @GuardedBy("this") 552 private int mActiveReason; 553 554 public final AtomicFile mConfigFile; 555 556 /** 557 * Package names the system has white-listed to opt out of power save restrictions, 558 * except for device idle mode. 559 */ 560 private final ArrayMap<String, Integer> mPowerSaveWhitelistAppsExceptIdle = new ArrayMap<>(); 561 562 /** 563 * Package names the user has white-listed using commandline option to opt out of 564 * power save restrictions, except for device idle mode. 565 */ 566 private final ArraySet<String> mPowerSaveWhitelistUserAppsExceptIdle = new ArraySet<>(); 567 568 /** 569 * Package names the system has white-listed to opt out of power save restrictions for 570 * all modes. 571 */ 572 private final ArrayMap<String, Integer> mPowerSaveWhitelistApps = new ArrayMap<>(); 573 574 /** 575 * Package names the user has white-listed to opt out of power save restrictions. 576 */ 577 private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>(); 578 579 /** 580 * App IDs of built-in system apps that have been white-listed except for idle modes. 581 */ 582 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIdsExceptIdle 583 = new SparseBooleanArray(); 584 585 /** 586 * App IDs of built-in system apps that have been white-listed. 587 */ 588 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray(); 589 590 /** 591 * App IDs that have been white-listed to opt out of power save restrictions, except 592 * for device idle modes. 593 */ 594 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray(); 595 596 /** 597 * Current app IDs that are in the complete power save white list, but shouldn't be 598 * excluded from idle modes. This array can be shared with others because it will not be 599 * modified once set. 600 */ 601 private int[] mPowerSaveWhitelistExceptIdleAppIdArray = new int[0]; 602 603 /** 604 * App IDs that have been white-listed to opt out of power save restrictions. 605 */ 606 private final SparseBooleanArray mPowerSaveWhitelistAllAppIds = new SparseBooleanArray(); 607 608 /** 609 * Current app IDs that are in the complete power save white list. This array can 610 * be shared with others because it will not be modified once set. 611 */ 612 private int[] mPowerSaveWhitelistAllAppIdArray = new int[0]; 613 614 /** 615 * App IDs that have been white-listed by the user to opt out of power save restrictions. 616 */ 617 private final SparseBooleanArray mPowerSaveWhitelistUserAppIds = new SparseBooleanArray(); 618 619 /** 620 * Current app IDs that are in the user power save white list. This array can 621 * be shared with others because it will not be modified once set. 622 */ 623 private int[] mPowerSaveWhitelistUserAppIdArray = new int[0]; 624 625 /** 626 * List of end times for app-IDs that are temporarily marked as being allowed to access 627 * the network and acquire wakelocks. Times are in milliseconds. 628 */ 629 private final SparseArray<Pair<MutableLong, String>> mTempWhitelistAppIdEndTimes 630 = new SparseArray<>(); 631 632 private NetworkPolicyManagerInternal mNetworkPolicyManagerInternal; 633 634 /** 635 * Current app IDs of temporarily whitelist apps for high-priority messages. 636 */ 637 private int[] mTempWhitelistAppIdArray = new int[0]; 638 639 /** 640 * Apps in the system whitelist that have been taken out (probably because the user wanted to). 641 * They can be restored back by calling restoreAppToSystemWhitelist(String). 642 */ 643 private ArrayMap<String, Integer> mRemovedFromSystemWhitelistApps = new ArrayMap<>(); 644 645 private final ArraySet<DeviceIdleInternal.StationaryListener> mStationaryListeners = 646 new ArraySet<>(); 647 648 private final ArraySet<PowerAllowlistInternal.TempAllowlistChangeListener> 649 mTempAllowlistChangeListeners = new ArraySet<>(); 650 651 private static final int EVENT_NULL = 0; 652 private static final int EVENT_NORMAL = 1; 653 private static final int EVENT_LIGHT_IDLE = 2; 654 private static final int EVENT_LIGHT_MAINTENANCE = 3; 655 private static final int EVENT_DEEP_IDLE = 4; 656 private static final int EVENT_DEEP_MAINTENANCE = 5; 657 658 private final int[] mEventCmds = new int[EVENT_BUFFER_SIZE]; 659 private final long[] mEventTimes = new long[EVENT_BUFFER_SIZE]; 660 private final String[] mEventReasons = new String[EVENT_BUFFER_SIZE]; 661 addEvent(int cmd, String reason)662 private void addEvent(int cmd, String reason) { 663 if (mEventCmds[0] != cmd) { 664 System.arraycopy(mEventCmds, 0, mEventCmds, 1, EVENT_BUFFER_SIZE - 1); 665 System.arraycopy(mEventTimes, 0, mEventTimes, 1, EVENT_BUFFER_SIZE - 1); 666 System.arraycopy(mEventReasons, 0, mEventReasons, 1, EVENT_BUFFER_SIZE - 1); 667 mEventCmds[0] = cmd; 668 mEventTimes[0] = SystemClock.elapsedRealtime(); 669 mEventReasons[0] = reason; 670 } 671 } 672 673 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 674 @Override public void onReceive(Context context, Intent intent) { 675 switch (intent.getAction()) { 676 case ConnectivityManager.CONNECTIVITY_ACTION: { 677 updateConnectivityState(intent); 678 } break; 679 case Intent.ACTION_BATTERY_CHANGED: { 680 boolean present = intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, true); 681 boolean plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0; 682 synchronized (DeviceIdleController.this) { 683 updateChargingLocked(present && plugged); 684 } 685 } break; 686 case Intent.ACTION_PACKAGE_REMOVED: { 687 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 688 Uri data = intent.getData(); 689 String ssp; 690 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 691 removePowerSaveWhitelistAppInternal(ssp); 692 } 693 } 694 } break; 695 } 696 } 697 }; 698 699 private final AlarmManager.OnAlarmListener mLightAlarmListener = () -> { 700 if (DEBUG) { 701 Slog.d(TAG, "Light progression alarm fired"); 702 } 703 synchronized (DeviceIdleController.this) { 704 stepLightIdleStateLocked("s:alarm"); 705 } 706 }; 707 708 /** AlarmListener to start monitoring motion if there are registered stationary listeners. */ 709 private final AlarmManager.OnAlarmListener mMotionRegistrationAlarmListener = () -> { 710 synchronized (DeviceIdleController.this) { 711 if (mStationaryListeners.size() > 0) { 712 startMonitoringMotionLocked(); 713 scheduleMotionTimeoutAlarmLocked(); 714 } 715 } 716 }; 717 718 private final AlarmManager.OnAlarmListener mMotionTimeoutAlarmListener = () -> { 719 synchronized (DeviceIdleController.this) { 720 if (!isStationaryLocked()) { 721 // If the device keeps registering motion, then the alarm should be 722 // rescheduled, so this shouldn't go off until the device is stationary. 723 // This case may happen in a race condition (alarm goes off right before 724 // motion is detected, but handleMotionDetectedLocked is called before 725 // we enter this block). 726 Slog.w(TAG, "motion timeout went off and device isn't stationary"); 727 return; 728 } 729 } 730 postStationaryStatusUpdated(); 731 }; 732 733 private final AlarmManager.OnAlarmListener mSensingTimeoutAlarmListener 734 = new AlarmManager.OnAlarmListener() { 735 @Override 736 public void onAlarm() { 737 synchronized (DeviceIdleController.this) { 738 if (mState == STATE_SENSING) { 739 // Restart the device idle progression in case the device moved but the screen 740 // didn't turn on. 741 becomeInactiveIfAppropriateLocked(); 742 } 743 } 744 } 745 }; 746 747 @VisibleForTesting 748 final AlarmManager.OnAlarmListener mDeepAlarmListener 749 = new AlarmManager.OnAlarmListener() { 750 @Override 751 public void onAlarm() { 752 synchronized (DeviceIdleController.this) { 753 stepIdleStateLocked("s:alarm"); 754 } 755 } 756 }; 757 758 private final IIntentReceiver mIdleStartedDoneReceiver = new IIntentReceiver.Stub() { 759 @Override 760 public void performReceive(Intent intent, int resultCode, String data, Bundle extras, 761 boolean ordered, boolean sticky, int sendingUser) { 762 // When coming out of a deep idle, we will add in some delay before we allow 763 // the system to settle down and finish the maintenance window. This is 764 // to give a chance for any pending work to be scheduled. 765 if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(intent.getAction())) { 766 mHandler.sendEmptyMessageDelayed(MSG_FINISH_IDLE_OP, 767 mConstants.MIN_DEEP_MAINTENANCE_TIME); 768 } else { 769 mHandler.sendEmptyMessageDelayed(MSG_FINISH_IDLE_OP, 770 mConstants.MIN_LIGHT_MAINTENANCE_TIME); 771 } 772 } 773 }; 774 775 private final BroadcastReceiver mInteractivityReceiver = new BroadcastReceiver() { 776 @Override 777 public void onReceive(Context context, Intent intent) { 778 synchronized (DeviceIdleController.this) { 779 updateInteractivityLocked(); 780 } 781 } 782 }; 783 784 private final EmergencyCallListener mEmergencyCallListener = new EmergencyCallListener(); 785 786 /** Post stationary status only to this listener. */ postStationaryStatus(DeviceIdleInternal.StationaryListener listener)787 private void postStationaryStatus(DeviceIdleInternal.StationaryListener listener) { 788 mHandler.obtainMessage(MSG_REPORT_STATIONARY_STATUS, listener).sendToTarget(); 789 } 790 791 /** Post stationary status to all registered listeners. */ postStationaryStatusUpdated()792 private void postStationaryStatusUpdated() { 793 mHandler.sendEmptyMessage(MSG_REPORT_STATIONARY_STATUS); 794 } 795 796 @GuardedBy("this") isStationaryLocked()797 private boolean isStationaryLocked() { 798 final long now = mInjector.getElapsedRealtime(); 799 return mMotionListener.active 800 // Listening for motion for long enough and last motion was long enough ago. 801 && now - Math.max(mMotionListener.activatedTimeElapsed, mLastMotionEventElapsed) 802 >= mConstants.MOTION_INACTIVE_TIMEOUT; 803 } 804 805 @VisibleForTesting registerStationaryListener(DeviceIdleInternal.StationaryListener listener)806 void registerStationaryListener(DeviceIdleInternal.StationaryListener listener) { 807 synchronized (this) { 808 if (!mStationaryListeners.add(listener)) { 809 // Listener already registered. 810 return; 811 } 812 postStationaryStatus(listener); 813 if (mMotionListener.active) { 814 if (!isStationaryLocked() && mStationaryListeners.size() == 1) { 815 // First listener to be registered and the device isn't stationary, so we 816 // need to register the alarm to report the device is stationary. 817 scheduleMotionTimeoutAlarmLocked(); 818 } 819 } else { 820 startMonitoringMotionLocked(); 821 scheduleMotionTimeoutAlarmLocked(); 822 } 823 } 824 } 825 unregisterStationaryListener(DeviceIdleInternal.StationaryListener listener)826 private void unregisterStationaryListener(DeviceIdleInternal.StationaryListener listener) { 827 synchronized (this) { 828 if (mStationaryListeners.remove(listener) && mStationaryListeners.size() == 0 829 // Motion detection is started when transitioning from INACTIVE to IDLE_PENDING 830 // and so doesn't need to be on for ACTIVE or INACTIVE states. 831 // Motion detection isn't needed when idling due to Quick Doze. 832 && (mState == STATE_ACTIVE || mState == STATE_INACTIVE 833 || mQuickDozeActivated)) { 834 maybeStopMonitoringMotionLocked(); 835 } 836 } 837 } 838 registerTempAllowlistChangeListener( @onNull PowerAllowlistInternal.TempAllowlistChangeListener listener)839 private void registerTempAllowlistChangeListener( 840 @NonNull PowerAllowlistInternal.TempAllowlistChangeListener listener) { 841 synchronized (this) { 842 mTempAllowlistChangeListeners.add(listener); 843 } 844 } 845 unregisterTempAllowlistChangeListener( @onNull PowerAllowlistInternal.TempAllowlistChangeListener listener)846 private void unregisterTempAllowlistChangeListener( 847 @NonNull PowerAllowlistInternal.TempAllowlistChangeListener listener) { 848 synchronized (this) { 849 mTempAllowlistChangeListeners.remove(listener); 850 } 851 } 852 853 @VisibleForTesting 854 final class MotionListener extends TriggerEventListener 855 implements SensorEventListener { 856 857 boolean active = false; 858 859 /** 860 * Time in the elapsed realtime timebase when this listener was activated. Only valid if 861 * {@link #active} is true. 862 */ 863 long activatedTimeElapsed; 864 isActive()865 public boolean isActive() { 866 return active; 867 } 868 869 @Override onTrigger(TriggerEvent event)870 public void onTrigger(TriggerEvent event) { 871 synchronized (DeviceIdleController.this) { 872 // One_shot sensors (which call onTrigger) are unregistered when onTrigger is called 873 active = false; 874 motionLocked(); 875 } 876 } 877 878 @Override onSensorChanged(SensorEvent event)879 public void onSensorChanged(SensorEvent event) { 880 synchronized (DeviceIdleController.this) { 881 // Since one_shot sensors are unregistered when onTrigger is called, unregister 882 // listeners here so that the MotionListener is in a consistent state when it calls 883 // out to motionLocked. 884 mSensorManager.unregisterListener(this, mMotionSensor); 885 active = false; 886 motionLocked(); 887 } 888 } 889 890 @Override onAccuracyChanged(Sensor sensor, int accuracy)891 public void onAccuracyChanged(Sensor sensor, int accuracy) {} 892 registerLocked()893 public boolean registerLocked() { 894 boolean success; 895 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) { 896 success = mSensorManager.requestTriggerSensor(mMotionListener, mMotionSensor); 897 } else { 898 success = mSensorManager.registerListener( 899 mMotionListener, mMotionSensor, SensorManager.SENSOR_DELAY_NORMAL); 900 } 901 if (success) { 902 active = true; 903 activatedTimeElapsed = mInjector.getElapsedRealtime(); 904 } else { 905 Slog.e(TAG, "Unable to register for " + mMotionSensor); 906 } 907 return success; 908 } 909 unregisterLocked()910 public void unregisterLocked() { 911 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) { 912 mSensorManager.cancelTriggerSensor(mMotionListener, mMotionSensor); 913 } else { 914 mSensorManager.unregisterListener(mMotionListener); 915 } 916 active = false; 917 } 918 } 919 @VisibleForTesting final MotionListener mMotionListener = new MotionListener(); 920 921 private final LocationListener mGenericLocationListener = new LocationListener() { 922 @Override 923 public void onLocationChanged(Location location) { 924 synchronized (DeviceIdleController.this) { 925 receivedGenericLocationLocked(location); 926 } 927 } 928 929 @Override 930 public void onStatusChanged(String provider, int status, Bundle extras) { 931 } 932 933 @Override 934 public void onProviderEnabled(String provider) { 935 } 936 937 @Override 938 public void onProviderDisabled(String provider) { 939 } 940 }; 941 942 private final LocationListener mGpsLocationListener = new LocationListener() { 943 @Override 944 public void onLocationChanged(Location location) { 945 synchronized (DeviceIdleController.this) { 946 receivedGpsLocationLocked(location); 947 } 948 } 949 950 @Override 951 public void onStatusChanged(String provider, int status, Bundle extras) { 952 } 953 954 @Override 955 public void onProviderEnabled(String provider) { 956 } 957 958 @Override 959 public void onProviderDisabled(String provider) { 960 } 961 }; 962 963 /** 964 * All times are in milliseconds. These constants are kept synchronized with the system 965 * global Settings. Any access to this class or its fields should be done while 966 * holding the DeviceIdleController lock. 967 */ 968 public final class Constants implements DeviceConfig.OnPropertiesChangedListener { 969 // Key names stored in the settings value. 970 private static final String KEY_FLEX_TIME_SHORT = "flex_time_short"; 971 private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = 972 "light_after_inactive_to"; 973 private static final String KEY_LIGHT_IDLE_TIMEOUT = "light_idle_to"; 974 private static final String KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX = 975 "light_idle_to_initial_flex"; 976 private static final String KEY_LIGHT_IDLE_TIMEOUT_MAX_FLEX = "light_max_idle_to_flex"; 977 private static final String KEY_LIGHT_IDLE_FACTOR = "light_idle_factor"; 978 private static final String KEY_LIGHT_MAX_IDLE_TIMEOUT = "light_max_idle_to"; 979 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = 980 "light_idle_maintenance_min_budget"; 981 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = 982 "light_idle_maintenance_max_budget"; 983 private static final String KEY_MIN_LIGHT_MAINTENANCE_TIME = "min_light_maintenance_time"; 984 private static final String KEY_MIN_DEEP_MAINTENANCE_TIME = "min_deep_maintenance_time"; 985 private static final String KEY_INACTIVE_TIMEOUT = "inactive_to"; 986 private static final String KEY_SENSING_TIMEOUT = "sensing_to"; 987 private static final String KEY_LOCATING_TIMEOUT = "locating_to"; 988 private static final String KEY_LOCATION_ACCURACY = "location_accuracy"; 989 private static final String KEY_MOTION_INACTIVE_TIMEOUT = "motion_inactive_to"; 990 private static final String KEY_MOTION_INACTIVE_TIMEOUT_FLEX = "motion_inactive_to_flex"; 991 private static final String KEY_IDLE_AFTER_INACTIVE_TIMEOUT = "idle_after_inactive_to"; 992 private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to"; 993 private static final String KEY_MAX_IDLE_PENDING_TIMEOUT = "max_idle_pending_to"; 994 private static final String KEY_IDLE_PENDING_FACTOR = "idle_pending_factor"; 995 private static final String KEY_QUICK_DOZE_DELAY_TIMEOUT = "quick_doze_delay_to"; 996 private static final String KEY_IDLE_TIMEOUT = "idle_to"; 997 private static final String KEY_MAX_IDLE_TIMEOUT = "max_idle_to"; 998 private static final String KEY_IDLE_FACTOR = "idle_factor"; 999 private static final String KEY_MIN_TIME_TO_ALARM = "min_time_to_alarm"; 1000 private static final String KEY_MAX_TEMP_APP_ALLOWLIST_DURATION_MS = 1001 "max_temp_app_allowlist_duration_ms"; 1002 private static final String KEY_MMS_TEMP_APP_ALLOWLIST_DURATION_MS = 1003 "mms_temp_app_allowlist_duration_ms"; 1004 private static final String KEY_SMS_TEMP_APP_ALLOWLIST_DURATION_MS = 1005 "sms_temp_app_allowlist_duration_ms"; 1006 private static final String KEY_NOTIFICATION_ALLOWLIST_DURATION_MS = 1007 "notification_allowlist_duration_ms"; 1008 /** 1009 * Whether to wait for the user to unlock the device before causing screen-on to 1010 * exit doze. Default = true 1011 */ 1012 private static final String KEY_WAIT_FOR_UNLOCK = "wait_for_unlock"; 1013 private static final String KEY_PRE_IDLE_FACTOR_LONG = 1014 "pre_idle_factor_long"; 1015 private static final String KEY_PRE_IDLE_FACTOR_SHORT = 1016 "pre_idle_factor_short"; 1017 private static final String KEY_USE_WINDOW_ALARMS = "use_window_alarms"; 1018 1019 private long mDefaultFlexTimeShort = 1020 !COMPRESS_TIME ? 60 * 1000L : 5 * 1000L; 1021 private long mDefaultLightIdleAfterInactiveTimeout = 1022 !COMPRESS_TIME ? 4 * 60 * 1000L : 30 * 1000L; 1023 private long mDefaultLightIdleTimeout = 1024 !COMPRESS_TIME ? 5 * 60 * 1000L : 15 * 1000L; 1025 private long mDefaultLightIdleTimeoutInitialFlex = 1026 !COMPRESS_TIME ? 60 * 1000L : 5 * 1000L; 1027 private long mDefaultLightIdleTimeoutMaxFlex = 1028 !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L; 1029 private float mDefaultLightIdleFactor = 2f; 1030 private long mDefaultLightMaxIdleTimeout = 1031 !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L; 1032 private long mDefaultLightIdleMaintenanceMinBudget = 1033 !COMPRESS_TIME ? 1 * 60 * 1000L : 15 * 1000L; 1034 private long mDefaultLightIdleMaintenanceMaxBudget = 1035 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L; 1036 private long mDefaultMinLightMaintenanceTime = 1037 !COMPRESS_TIME ? 5 * 1000L : 1 * 1000L; 1038 private long mDefaultMinDeepMaintenanceTime = 1039 !COMPRESS_TIME ? 30 * 1000L : 5 * 1000L; 1040 private long mDefaultInactiveTimeout = 1041 (30 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10); 1042 private static final long DEFAULT_INACTIVE_TIMEOUT_SMALL_BATTERY = 1043 (15 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10); 1044 private long mDefaultSensingTimeout = 1045 !COMPRESS_TIME ? 4 * 60 * 1000L : 60 * 1000L; 1046 private long mDefaultLocatingTimeout = 1047 !COMPRESS_TIME ? 30 * 1000L : 15 * 1000L; 1048 private float mDefaultLocationAccuracy = 20f; 1049 private long mDefaultMotionInactiveTimeout = 1050 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L; 1051 private long mDefaultMotionInactiveTimeoutFlex = 1052 !COMPRESS_TIME ? 60 * 1000L : 5 * 1000L; 1053 private long mDefaultIdleAfterInactiveTimeout = 1054 (30 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10); 1055 private static final long DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT_SMALL_BATTERY = 1056 (15 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10); 1057 private long mDefaultIdlePendingTimeout = 1058 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L; 1059 private long mDefaultMaxIdlePendingTimeout = 1060 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L; 1061 private float mDefaultIdlePendingFactor = 2f; 1062 private long mDefaultQuickDozeDelayTimeout = 1063 !COMPRESS_TIME ? 60 * 1000L : 15 * 1000L; 1064 private long mDefaultIdleTimeout = 1065 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L; 1066 private long mDefaultMaxIdleTimeout = 1067 !COMPRESS_TIME ? 6 * 60 * 60 * 1000L : 30 * 60 * 1000L; 1068 private float mDefaultIdleFactor = 2f; 1069 private long mDefaultMinTimeToAlarm = 1070 !COMPRESS_TIME ? 30 * 60 * 1000L : 6 * 60 * 1000L; 1071 private long mDefaultMaxTempAppAllowlistDurationMs = 5 * 60 * 1000L; 1072 private long mDefaultMmsTempAppAllowlistDurationMs = 60 * 1000L; 1073 private long mDefaultSmsTempAppAllowlistDurationMs = 20 * 1000L; 1074 private long mDefaultNotificationAllowlistDurationMs = 30 * 1000L; 1075 private boolean mDefaultWaitForUnlock = true; 1076 private float mDefaultPreIdleFactorLong = 1.67f; 1077 private float mDefaultPreIdleFactorShort = .33f; 1078 private boolean mDefaultUseWindowAlarms = true; 1079 1080 /** 1081 * A somewhat short alarm window size that we will tolerate for various alarm timings. 1082 * 1083 * @see #KEY_FLEX_TIME_SHORT 1084 */ 1085 public long FLEX_TIME_SHORT = mDefaultFlexTimeShort; 1086 1087 /** 1088 * This is the time, after becoming inactive, that we go in to the first 1089 * light-weight idle mode. 1090 * 1091 * @see #KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT 1092 */ 1093 public long LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = mDefaultLightIdleAfterInactiveTimeout; 1094 1095 /** 1096 * This is the initial time that we will run in light idle maintenance mode. 1097 * 1098 * @see #KEY_LIGHT_IDLE_TIMEOUT 1099 */ 1100 public long LIGHT_IDLE_TIMEOUT = mDefaultLightIdleTimeout; 1101 1102 /** 1103 * This is the initial alarm window size that we will tolerate for light idle maintenance 1104 * timing. 1105 * 1106 * @see #KEY_LIGHT_IDLE_TIMEOUT_MAX_FLEX 1107 * @see #mNextLightIdleDelayFlex 1108 */ 1109 public long LIGHT_IDLE_TIMEOUT_INITIAL_FLEX = mDefaultLightIdleTimeoutInitialFlex; 1110 1111 /** 1112 * This is the maximum value that {@link #mNextLightIdleDelayFlex} should take. 1113 * 1114 * @see #KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX 1115 */ 1116 public long LIGHT_IDLE_TIMEOUT_MAX_FLEX = mDefaultLightIdleTimeoutMaxFlex; 1117 1118 /** 1119 * Scaling factor to apply to the light idle mode time each time we complete a cycle. 1120 * 1121 * @see #KEY_LIGHT_IDLE_FACTOR 1122 */ 1123 public float LIGHT_IDLE_FACTOR = mDefaultLightIdleFactor; 1124 1125 /** 1126 * This is the maximum time we will stay in light idle mode. 1127 * 1128 * @see #KEY_LIGHT_MAX_IDLE_TIMEOUT 1129 */ 1130 public long LIGHT_MAX_IDLE_TIMEOUT = mDefaultLightMaxIdleTimeout; 1131 1132 /** 1133 * This is the minimum amount of time we want to make available for maintenance mode 1134 * when lightly idling. That is, we will always have at least this amount of time 1135 * available maintenance before timing out and cutting off maintenance mode. 1136 * 1137 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET 1138 */ 1139 public long LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = mDefaultLightIdleMaintenanceMinBudget; 1140 1141 /** 1142 * This is the maximum amount of time we want to make available for maintenance mode 1143 * when lightly idling. That is, if the system isn't using up its minimum maintenance 1144 * budget and this time is being added to the budget reserve, this is the maximum 1145 * reserve size we will allow to grow and thus the maximum amount of time we will 1146 * allow for the maintenance window. 1147 * 1148 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET 1149 */ 1150 public long LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = mDefaultLightIdleMaintenanceMaxBudget; 1151 1152 /** 1153 * This is the minimum amount of time that we will stay in maintenance mode after 1154 * a light doze. We have this minimum to allow various things to respond to switching 1155 * in to maintenance mode and scheduling their work -- otherwise we may 1156 * see there is nothing to do (no jobs pending) and go out of maintenance 1157 * mode immediately. 1158 * 1159 * @see #KEY_MIN_LIGHT_MAINTENANCE_TIME 1160 */ 1161 public long MIN_LIGHT_MAINTENANCE_TIME = mDefaultMinLightMaintenanceTime; 1162 1163 /** 1164 * This is the minimum amount of time that we will stay in maintenance mode after 1165 * a full doze. We have this minimum to allow various things to respond to switching 1166 * in to maintenance mode and scheduling their work -- otherwise we may 1167 * see there is nothing to do (no jobs pending) and go out of maintenance 1168 * mode immediately. 1169 * @see #KEY_MIN_DEEP_MAINTENANCE_TIME 1170 */ 1171 public long MIN_DEEP_MAINTENANCE_TIME = mDefaultMinDeepMaintenanceTime; 1172 1173 /** 1174 * This is the time, after becoming inactive, at which we start looking at the 1175 * motion sensor to determine if the device is being left alone. We don't do this 1176 * immediately after going inactive just because we don't want to be continually running 1177 * the motion sensor whenever the screen is off. 1178 * @see #KEY_INACTIVE_TIMEOUT 1179 */ 1180 public long INACTIVE_TIMEOUT = mDefaultInactiveTimeout; 1181 1182 /** 1183 * If we don't receive a callback from AnyMotion in this amount of time + 1184 * {@link #LOCATING_TIMEOUT}, we will change from 1185 * STATE_SENSING to STATE_INACTIVE, and any AnyMotion callbacks while not in STATE_SENSING 1186 * will be ignored. 1187 * @see #KEY_SENSING_TIMEOUT 1188 */ 1189 public long SENSING_TIMEOUT = mDefaultSensingTimeout; 1190 1191 /** 1192 * This is how long we will wait to try to get a good location fix before going in to 1193 * idle mode. 1194 * @see #KEY_LOCATING_TIMEOUT 1195 */ 1196 public long LOCATING_TIMEOUT = mDefaultLocatingTimeout; 1197 1198 /** 1199 * The desired maximum accuracy (in meters) we consider the location to be good enough to go 1200 * on to idle. We will be trying to get an accuracy fix at least this good or until 1201 * {@link #LOCATING_TIMEOUT} expires. 1202 * @see #KEY_LOCATION_ACCURACY 1203 */ 1204 public float LOCATION_ACCURACY = mDefaultLocationAccuracy; 1205 1206 /** 1207 * This is the time, after seeing motion, that we wait after becoming inactive from 1208 * that until we start looking for motion again. 1209 * 1210 * @see #KEY_MOTION_INACTIVE_TIMEOUT 1211 */ 1212 public long MOTION_INACTIVE_TIMEOUT = mDefaultMotionInactiveTimeout; 1213 1214 /** 1215 * This is the alarm window size we will tolerate for motion detection timings. 1216 * 1217 * @see #KEY_MOTION_INACTIVE_TIMEOUT_FLEX 1218 */ 1219 public long MOTION_INACTIVE_TIMEOUT_FLEX = mDefaultMotionInactiveTimeoutFlex; 1220 1221 /** 1222 * This is the time, after the inactive timeout elapses, that we will wait looking 1223 * for motion until we truly consider the device to be idle. 1224 * 1225 * @see #KEY_IDLE_AFTER_INACTIVE_TIMEOUT 1226 */ 1227 public long IDLE_AFTER_INACTIVE_TIMEOUT = mDefaultIdleAfterInactiveTimeout; 1228 1229 /** 1230 * This is the initial time, after being idle, that we will allow ourself to be back 1231 * in the IDLE_MAINTENANCE state allowing the system to run normally until we return to 1232 * idle. 1233 * @see #KEY_IDLE_PENDING_TIMEOUT 1234 */ 1235 public long IDLE_PENDING_TIMEOUT = mDefaultIdlePendingTimeout; 1236 1237 /** 1238 * Maximum pending idle timeout (time spent running) we will be allowed to use. 1239 * @see #KEY_MAX_IDLE_PENDING_TIMEOUT 1240 */ 1241 public long MAX_IDLE_PENDING_TIMEOUT = mDefaultMaxIdlePendingTimeout; 1242 1243 /** 1244 * Scaling factor to apply to current pending idle timeout each time we cycle through 1245 * that state. 1246 * @see #KEY_IDLE_PENDING_FACTOR 1247 */ 1248 public float IDLE_PENDING_FACTOR = mDefaultIdlePendingFactor; 1249 1250 /** 1251 * This is amount of time we will wait from the point where we go into 1252 * STATE_QUICK_DOZE_DELAY until we actually go into STATE_IDLE, while waiting for jobs 1253 * and other current activity to finish. 1254 * @see #KEY_QUICK_DOZE_DELAY_TIMEOUT 1255 */ 1256 public long QUICK_DOZE_DELAY_TIMEOUT = mDefaultQuickDozeDelayTimeout; 1257 1258 /** 1259 * This is the initial time that we want to sit in the idle state before waking up 1260 * again to return to pending idle and allowing normal work to run. 1261 * @see #KEY_IDLE_TIMEOUT 1262 */ 1263 public long IDLE_TIMEOUT = mDefaultIdleTimeout; 1264 1265 /** 1266 * Maximum idle duration we will be allowed to use. 1267 * @see #KEY_MAX_IDLE_TIMEOUT 1268 */ 1269 public long MAX_IDLE_TIMEOUT = mDefaultMaxIdleTimeout; 1270 1271 /** 1272 * Scaling factor to apply to current idle timeout each time we cycle through that state. 1273 * @see #KEY_IDLE_FACTOR 1274 */ 1275 public float IDLE_FACTOR = mDefaultIdleFactor; 1276 1277 /** 1278 * This is the minimum time we will allow until the next upcoming alarm for us to 1279 * actually go in to idle mode. 1280 * @see #KEY_MIN_TIME_TO_ALARM 1281 */ 1282 public long MIN_TIME_TO_ALARM = mDefaultMinTimeToAlarm; 1283 1284 /** 1285 * Max amount of time to temporarily whitelist an app when it receives a high priority 1286 * tickle. 1287 * 1288 * @see #KEY_MAX_TEMP_APP_ALLOWLIST_DURATION_MS 1289 */ 1290 public long MAX_TEMP_APP_ALLOWLIST_DURATION_MS = mDefaultMaxTempAppAllowlistDurationMs; 1291 1292 /** 1293 * Amount of time we would like to whitelist an app that is receiving an MMS. 1294 * @see #KEY_MMS_TEMP_APP_ALLOWLIST_DURATION_MS 1295 */ 1296 public long MMS_TEMP_APP_ALLOWLIST_DURATION_MS = mDefaultMmsTempAppAllowlistDurationMs; 1297 1298 /** 1299 * Amount of time we would like to whitelist an app that is receiving an SMS. 1300 * @see #KEY_SMS_TEMP_APP_ALLOWLIST_DURATION_MS 1301 */ 1302 public long SMS_TEMP_APP_ALLOWLIST_DURATION_MS = mDefaultSmsTempAppAllowlistDurationMs; 1303 1304 /** 1305 * Amount of time we would like to whitelist an app that is handling a 1306 * {@link android.app.PendingIntent} triggered by a {@link android.app.Notification}. 1307 * @see #KEY_NOTIFICATION_ALLOWLIST_DURATION_MS 1308 */ 1309 public long NOTIFICATION_ALLOWLIST_DURATION_MS = mDefaultNotificationAllowlistDurationMs; 1310 1311 /** 1312 * Pre idle time factor use to make idle delay longer 1313 */ 1314 public float PRE_IDLE_FACTOR_LONG = mDefaultPreIdleFactorLong; 1315 1316 /** 1317 * Pre idle time factor use to make idle delay shorter 1318 */ 1319 public float PRE_IDLE_FACTOR_SHORT = mDefaultPreIdleFactorShort; 1320 1321 public boolean WAIT_FOR_UNLOCK = mDefaultWaitForUnlock; 1322 1323 /** 1324 * Whether to use window alarms. True to use window alarms (call AlarmManager.setWindow()). 1325 * False to use the legacy inexact alarms (call AlarmManager.set()). 1326 */ 1327 public boolean USE_WINDOW_ALARMS = mDefaultUseWindowAlarms; 1328 1329 private final boolean mSmallBatteryDevice; 1330 Constants()1331 public Constants() { 1332 initDefault(); 1333 mSmallBatteryDevice = ActivityManager.isSmallBatteryDevice(); 1334 if (mSmallBatteryDevice) { 1335 INACTIVE_TIMEOUT = DEFAULT_INACTIVE_TIMEOUT_SMALL_BATTERY; 1336 IDLE_AFTER_INACTIVE_TIMEOUT = DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT_SMALL_BATTERY; 1337 } 1338 DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_DEVICE_IDLE, 1339 AppSchedulingModuleThread.getExecutor(), this); 1340 // Load all the constants. 1341 onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_DEVICE_IDLE)); 1342 } 1343 initDefault()1344 private void initDefault() { 1345 final Resources res = getContext().getResources(); 1346 1347 mDefaultFlexTimeShort = getTimeout( 1348 res.getInteger(com.android.internal.R.integer.device_idle_flex_time_short_ms), 1349 mDefaultFlexTimeShort); 1350 mDefaultLightIdleAfterInactiveTimeout = getTimeout(res.getInteger( 1351 com.android.internal.R.integer.device_idle_light_after_inactive_to_ms), 1352 mDefaultLightIdleAfterInactiveTimeout); 1353 mDefaultLightIdleTimeout = getTimeout( 1354 res.getInteger(com.android.internal.R.integer.device_idle_light_idle_to_ms), 1355 mDefaultLightIdleTimeout); 1356 mDefaultLightIdleTimeoutInitialFlex = getTimeout( 1357 res.getInteger( 1358 com.android.internal.R.integer.device_idle_light_idle_to_init_flex_ms), 1359 mDefaultLightIdleTimeoutInitialFlex); 1360 mDefaultLightIdleTimeoutMaxFlex = getTimeout( 1361 res.getInteger( 1362 com.android.internal.R.integer.device_idle_light_idle_to_max_flex_ms), 1363 mDefaultLightIdleTimeoutMaxFlex); 1364 mDefaultLightIdleFactor = res.getFloat( 1365 com.android.internal.R.integer.device_idle_light_idle_factor); 1366 mDefaultLightMaxIdleTimeout = getTimeout( 1367 res.getInteger(com.android.internal.R.integer.device_idle_light_max_idle_to_ms), 1368 mDefaultLightMaxIdleTimeout); 1369 mDefaultLightIdleMaintenanceMinBudget = getTimeout(res.getInteger( 1370 com.android.internal.R.integer.device_idle_light_idle_maintenance_min_budget_ms 1371 ), mDefaultLightIdleMaintenanceMinBudget); 1372 mDefaultLightIdleMaintenanceMaxBudget = getTimeout(res.getInteger( 1373 com.android.internal.R.integer.device_idle_light_idle_maintenance_max_budget_ms 1374 ), mDefaultLightIdleMaintenanceMaxBudget); 1375 mDefaultMinLightMaintenanceTime = getTimeout(res.getInteger( 1376 com.android.internal.R.integer.device_idle_min_light_maintenance_time_ms), 1377 mDefaultMinLightMaintenanceTime); 1378 mDefaultMinDeepMaintenanceTime = getTimeout(res.getInteger( 1379 com.android.internal.R.integer.device_idle_min_deep_maintenance_time_ms), 1380 mDefaultMinDeepMaintenanceTime); 1381 mDefaultInactiveTimeout = getTimeout( 1382 res.getInteger(com.android.internal.R.integer.device_idle_inactive_to_ms), 1383 mDefaultInactiveTimeout); 1384 mDefaultSensingTimeout = getTimeout( 1385 res.getInteger(com.android.internal.R.integer.device_idle_sensing_to_ms), 1386 mDefaultSensingTimeout); 1387 mDefaultLocatingTimeout = getTimeout( 1388 res.getInteger(com.android.internal.R.integer.device_idle_locating_to_ms), 1389 mDefaultLocatingTimeout); 1390 mDefaultLocationAccuracy = res.getFloat( 1391 com.android.internal.R.integer.device_idle_location_accuracy); 1392 mDefaultMotionInactiveTimeout = getTimeout(res.getInteger( 1393 com.android.internal.R.integer.device_idle_motion_inactive_to_ms), 1394 mDefaultMotionInactiveTimeout); 1395 mDefaultMotionInactiveTimeoutFlex = getTimeout(res.getInteger( 1396 com.android.internal.R.integer.device_idle_motion_inactive_to_flex_ms), 1397 mDefaultMotionInactiveTimeoutFlex); 1398 mDefaultIdleAfterInactiveTimeout = getTimeout(res.getInteger( 1399 com.android.internal.R.integer.device_idle_idle_after_inactive_to_ms), 1400 mDefaultIdleAfterInactiveTimeout); 1401 mDefaultIdlePendingTimeout = getTimeout( 1402 res.getInteger(com.android.internal.R.integer.device_idle_idle_pending_to_ms), 1403 mDefaultIdlePendingTimeout); 1404 mDefaultMaxIdlePendingTimeout = getTimeout(res.getInteger( 1405 com.android.internal.R.integer.device_idle_max_idle_pending_to_ms), 1406 mDefaultMaxIdlePendingTimeout); 1407 mDefaultIdlePendingFactor = res.getFloat( 1408 com.android.internal.R.integer.device_idle_idle_pending_factor); 1409 mDefaultQuickDozeDelayTimeout = getTimeout(res.getInteger( 1410 com.android.internal.R.integer.device_idle_quick_doze_delay_to_ms), 1411 mDefaultQuickDozeDelayTimeout); 1412 mDefaultIdleTimeout = getTimeout( 1413 res.getInteger(com.android.internal.R.integer.device_idle_idle_to_ms), 1414 mDefaultIdleTimeout); 1415 mDefaultMaxIdleTimeout = getTimeout( 1416 res.getInteger(com.android.internal.R.integer.device_idle_max_idle_to_ms), 1417 mDefaultMaxIdleTimeout); 1418 mDefaultIdleFactor = res.getFloat( 1419 com.android.internal.R.integer.device_idle_idle_factor); 1420 mDefaultMinTimeToAlarm = getTimeout(res.getInteger( 1421 com.android.internal.R.integer.device_idle_min_time_to_alarm_ms), 1422 mDefaultMinTimeToAlarm); 1423 mDefaultMaxTempAppAllowlistDurationMs = res.getInteger( 1424 com.android.internal.R.integer.device_idle_max_temp_app_allowlist_duration_ms); 1425 mDefaultMmsTempAppAllowlistDurationMs = res.getInteger( 1426 com.android.internal.R.integer.device_idle_mms_temp_app_allowlist_duration_ms); 1427 mDefaultSmsTempAppAllowlistDurationMs = res.getInteger( 1428 com.android.internal.R.integer.device_idle_sms_temp_app_allowlist_duration_ms); 1429 mDefaultNotificationAllowlistDurationMs = res.getInteger( 1430 com.android.internal.R.integer.device_idle_notification_allowlist_duration_ms); 1431 mDefaultWaitForUnlock = res.getBoolean( 1432 com.android.internal.R.bool.device_idle_wait_for_unlock); 1433 mDefaultPreIdleFactorLong = res.getFloat( 1434 com.android.internal.R.integer.device_idle_pre_idle_factor_long); 1435 mDefaultPreIdleFactorShort = res.getFloat( 1436 com.android.internal.R.integer.device_idle_pre_idle_factor_short); 1437 mDefaultUseWindowAlarms = res.getBoolean( 1438 com.android.internal.R.bool.device_idle_use_window_alarms); 1439 1440 FLEX_TIME_SHORT = mDefaultFlexTimeShort; 1441 LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = mDefaultLightIdleAfterInactiveTimeout; 1442 LIGHT_IDLE_TIMEOUT = mDefaultLightIdleTimeout; 1443 LIGHT_IDLE_TIMEOUT_INITIAL_FLEX = mDefaultLightIdleTimeoutInitialFlex; 1444 LIGHT_IDLE_TIMEOUT_MAX_FLEX = mDefaultLightIdleTimeoutMaxFlex; 1445 LIGHT_IDLE_FACTOR = mDefaultLightIdleFactor; 1446 LIGHT_MAX_IDLE_TIMEOUT = mDefaultLightMaxIdleTimeout; 1447 LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = mDefaultLightIdleMaintenanceMinBudget; 1448 LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = mDefaultLightIdleMaintenanceMaxBudget; 1449 MIN_LIGHT_MAINTENANCE_TIME = mDefaultMinLightMaintenanceTime; 1450 MIN_DEEP_MAINTENANCE_TIME = mDefaultMinDeepMaintenanceTime; 1451 INACTIVE_TIMEOUT = mDefaultInactiveTimeout; 1452 SENSING_TIMEOUT = mDefaultSensingTimeout; 1453 LOCATING_TIMEOUT = mDefaultLocatingTimeout; 1454 LOCATION_ACCURACY = mDefaultLocationAccuracy; 1455 MOTION_INACTIVE_TIMEOUT = mDefaultMotionInactiveTimeout; 1456 MOTION_INACTIVE_TIMEOUT_FLEX = mDefaultMotionInactiveTimeoutFlex; 1457 IDLE_AFTER_INACTIVE_TIMEOUT = mDefaultIdleAfterInactiveTimeout; 1458 IDLE_PENDING_TIMEOUT = mDefaultIdlePendingTimeout; 1459 MAX_IDLE_PENDING_TIMEOUT = mDefaultMaxIdlePendingTimeout; 1460 IDLE_PENDING_FACTOR = mDefaultIdlePendingFactor; 1461 QUICK_DOZE_DELAY_TIMEOUT = mDefaultQuickDozeDelayTimeout; 1462 IDLE_TIMEOUT = mDefaultIdleTimeout; 1463 MAX_IDLE_TIMEOUT = mDefaultMaxIdleTimeout; 1464 IDLE_FACTOR = mDefaultIdleFactor; 1465 MIN_TIME_TO_ALARM = mDefaultMinTimeToAlarm; 1466 MAX_TEMP_APP_ALLOWLIST_DURATION_MS = mDefaultMaxTempAppAllowlistDurationMs; 1467 MMS_TEMP_APP_ALLOWLIST_DURATION_MS = mDefaultMmsTempAppAllowlistDurationMs; 1468 SMS_TEMP_APP_ALLOWLIST_DURATION_MS = mDefaultSmsTempAppAllowlistDurationMs; 1469 NOTIFICATION_ALLOWLIST_DURATION_MS = mDefaultNotificationAllowlistDurationMs; 1470 WAIT_FOR_UNLOCK = mDefaultWaitForUnlock; 1471 PRE_IDLE_FACTOR_LONG = mDefaultPreIdleFactorLong; 1472 PRE_IDLE_FACTOR_SHORT = mDefaultPreIdleFactorShort; 1473 USE_WINDOW_ALARMS = mDefaultUseWindowAlarms; 1474 } 1475 getTimeout(long defTimeout, long compTimeout)1476 private long getTimeout(long defTimeout, long compTimeout) { 1477 return (!COMPRESS_TIME || defTimeout < compTimeout) ? defTimeout : compTimeout; 1478 } 1479 1480 1481 @Override onPropertiesChanged(DeviceConfig.Properties properties)1482 public void onPropertiesChanged(DeviceConfig.Properties properties) { 1483 synchronized (DeviceIdleController.this) { 1484 for (String name : properties.getKeyset()) { 1485 if (name == null) { 1486 continue; 1487 } 1488 switch (name) { 1489 case KEY_FLEX_TIME_SHORT: 1490 FLEX_TIME_SHORT = properties.getLong( 1491 KEY_FLEX_TIME_SHORT, mDefaultFlexTimeShort); 1492 break; 1493 case KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT: 1494 LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = properties.getLong( 1495 KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT, 1496 mDefaultLightIdleAfterInactiveTimeout); 1497 break; 1498 case KEY_LIGHT_IDLE_TIMEOUT: 1499 LIGHT_IDLE_TIMEOUT = properties.getLong( 1500 KEY_LIGHT_IDLE_TIMEOUT, mDefaultLightIdleTimeout); 1501 break; 1502 case KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX: 1503 LIGHT_IDLE_TIMEOUT_INITIAL_FLEX = properties.getLong( 1504 KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX, 1505 mDefaultLightIdleTimeoutInitialFlex); 1506 break; 1507 case KEY_LIGHT_IDLE_TIMEOUT_MAX_FLEX: 1508 LIGHT_IDLE_TIMEOUT_MAX_FLEX = properties.getLong( 1509 KEY_LIGHT_IDLE_TIMEOUT_MAX_FLEX, 1510 mDefaultLightIdleTimeoutMaxFlex); 1511 break; 1512 case KEY_LIGHT_IDLE_FACTOR: 1513 LIGHT_IDLE_FACTOR = Math.max(1, properties.getFloat( 1514 KEY_LIGHT_IDLE_FACTOR, mDefaultLightIdleFactor)); 1515 break; 1516 case KEY_LIGHT_MAX_IDLE_TIMEOUT: 1517 LIGHT_MAX_IDLE_TIMEOUT = properties.getLong( 1518 KEY_LIGHT_MAX_IDLE_TIMEOUT, mDefaultLightMaxIdleTimeout); 1519 break; 1520 case KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET: 1521 LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = properties.getLong( 1522 KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET, 1523 mDefaultLightIdleMaintenanceMinBudget); 1524 break; 1525 case KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET: 1526 LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = properties.getLong( 1527 KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET, 1528 mDefaultLightIdleMaintenanceMaxBudget); 1529 break; 1530 case KEY_MIN_LIGHT_MAINTENANCE_TIME: 1531 MIN_LIGHT_MAINTENANCE_TIME = properties.getLong( 1532 KEY_MIN_LIGHT_MAINTENANCE_TIME, 1533 mDefaultMinLightMaintenanceTime); 1534 break; 1535 case KEY_MIN_DEEP_MAINTENANCE_TIME: 1536 MIN_DEEP_MAINTENANCE_TIME = properties.getLong( 1537 KEY_MIN_DEEP_MAINTENANCE_TIME, 1538 mDefaultMinDeepMaintenanceTime); 1539 break; 1540 case KEY_INACTIVE_TIMEOUT: 1541 final long defaultInactiveTimeout = mSmallBatteryDevice 1542 ? DEFAULT_INACTIVE_TIMEOUT_SMALL_BATTERY 1543 : mDefaultInactiveTimeout; 1544 INACTIVE_TIMEOUT = properties.getLong( 1545 KEY_INACTIVE_TIMEOUT, defaultInactiveTimeout); 1546 break; 1547 case KEY_SENSING_TIMEOUT: 1548 SENSING_TIMEOUT = properties.getLong( 1549 KEY_SENSING_TIMEOUT, mDefaultSensingTimeout); 1550 break; 1551 case KEY_LOCATING_TIMEOUT: 1552 LOCATING_TIMEOUT = properties.getLong( 1553 KEY_LOCATING_TIMEOUT, mDefaultLocatingTimeout); 1554 break; 1555 case KEY_LOCATION_ACCURACY: 1556 LOCATION_ACCURACY = properties.getFloat( 1557 KEY_LOCATION_ACCURACY, mDefaultLocationAccuracy); 1558 break; 1559 case KEY_MOTION_INACTIVE_TIMEOUT: 1560 MOTION_INACTIVE_TIMEOUT = properties.getLong( 1561 KEY_MOTION_INACTIVE_TIMEOUT, mDefaultMotionInactiveTimeout); 1562 break; 1563 case KEY_MOTION_INACTIVE_TIMEOUT_FLEX: 1564 MOTION_INACTIVE_TIMEOUT_FLEX = properties.getLong( 1565 KEY_MOTION_INACTIVE_TIMEOUT_FLEX, 1566 mDefaultMotionInactiveTimeoutFlex); 1567 break; 1568 case KEY_IDLE_AFTER_INACTIVE_TIMEOUT: 1569 final long defaultIdleAfterInactiveTimeout = mSmallBatteryDevice 1570 ? DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT_SMALL_BATTERY 1571 : mDefaultIdleAfterInactiveTimeout; 1572 IDLE_AFTER_INACTIVE_TIMEOUT = properties.getLong( 1573 KEY_IDLE_AFTER_INACTIVE_TIMEOUT, 1574 defaultIdleAfterInactiveTimeout); 1575 break; 1576 case KEY_IDLE_PENDING_TIMEOUT: 1577 IDLE_PENDING_TIMEOUT = properties.getLong( 1578 KEY_IDLE_PENDING_TIMEOUT, mDefaultIdlePendingTimeout); 1579 break; 1580 case KEY_MAX_IDLE_PENDING_TIMEOUT: 1581 MAX_IDLE_PENDING_TIMEOUT = properties.getLong( 1582 KEY_MAX_IDLE_PENDING_TIMEOUT, mDefaultMaxIdlePendingTimeout); 1583 break; 1584 case KEY_IDLE_PENDING_FACTOR: 1585 IDLE_PENDING_FACTOR = properties.getFloat( 1586 KEY_IDLE_PENDING_FACTOR, mDefaultIdlePendingFactor); 1587 break; 1588 case KEY_QUICK_DOZE_DELAY_TIMEOUT: 1589 QUICK_DOZE_DELAY_TIMEOUT = properties.getLong( 1590 KEY_QUICK_DOZE_DELAY_TIMEOUT, mDefaultQuickDozeDelayTimeout); 1591 break; 1592 case KEY_IDLE_TIMEOUT: 1593 IDLE_TIMEOUT = properties.getLong( 1594 KEY_IDLE_TIMEOUT, mDefaultIdleTimeout); 1595 break; 1596 case KEY_MAX_IDLE_TIMEOUT: 1597 MAX_IDLE_TIMEOUT = properties.getLong( 1598 KEY_MAX_IDLE_TIMEOUT, mDefaultMaxIdleTimeout); 1599 break; 1600 case KEY_IDLE_FACTOR: 1601 IDLE_FACTOR = properties.getFloat(KEY_IDLE_FACTOR, mDefaultIdleFactor); 1602 break; 1603 case KEY_MIN_TIME_TO_ALARM: 1604 MIN_TIME_TO_ALARM = properties.getLong( 1605 KEY_MIN_TIME_TO_ALARM, mDefaultMinTimeToAlarm); 1606 break; 1607 case KEY_MAX_TEMP_APP_ALLOWLIST_DURATION_MS: 1608 MAX_TEMP_APP_ALLOWLIST_DURATION_MS = properties.getLong( 1609 KEY_MAX_TEMP_APP_ALLOWLIST_DURATION_MS, 1610 mDefaultMaxTempAppAllowlistDurationMs); 1611 break; 1612 case KEY_MMS_TEMP_APP_ALLOWLIST_DURATION_MS: 1613 MMS_TEMP_APP_ALLOWLIST_DURATION_MS = properties.getLong( 1614 KEY_MMS_TEMP_APP_ALLOWLIST_DURATION_MS, 1615 mDefaultMmsTempAppAllowlistDurationMs); 1616 break; 1617 case KEY_SMS_TEMP_APP_ALLOWLIST_DURATION_MS: 1618 SMS_TEMP_APP_ALLOWLIST_DURATION_MS = properties.getLong( 1619 KEY_SMS_TEMP_APP_ALLOWLIST_DURATION_MS, 1620 mDefaultSmsTempAppAllowlistDurationMs); 1621 break; 1622 case KEY_NOTIFICATION_ALLOWLIST_DURATION_MS: 1623 NOTIFICATION_ALLOWLIST_DURATION_MS = properties.getLong( 1624 KEY_NOTIFICATION_ALLOWLIST_DURATION_MS, 1625 mDefaultNotificationAllowlistDurationMs); 1626 break; 1627 case KEY_WAIT_FOR_UNLOCK: 1628 WAIT_FOR_UNLOCK = properties.getBoolean( 1629 KEY_WAIT_FOR_UNLOCK, mDefaultWaitForUnlock); 1630 break; 1631 case KEY_PRE_IDLE_FACTOR_LONG: 1632 PRE_IDLE_FACTOR_LONG = properties.getFloat( 1633 KEY_PRE_IDLE_FACTOR_LONG, mDefaultPreIdleFactorLong); 1634 break; 1635 case KEY_PRE_IDLE_FACTOR_SHORT: 1636 PRE_IDLE_FACTOR_SHORT = properties.getFloat( 1637 KEY_PRE_IDLE_FACTOR_SHORT, mDefaultPreIdleFactorShort); 1638 break; 1639 case KEY_USE_WINDOW_ALARMS: 1640 USE_WINDOW_ALARMS = properties.getBoolean( 1641 KEY_USE_WINDOW_ALARMS, mDefaultUseWindowAlarms); 1642 break; 1643 default: 1644 Slog.e(TAG, "Unknown configuration key: " + name); 1645 break; 1646 } 1647 } 1648 } 1649 } 1650 dump(PrintWriter pw)1651 void dump(PrintWriter pw) { 1652 pw.println(" Settings:"); 1653 1654 pw.print(" "); pw.print(KEY_FLEX_TIME_SHORT); pw.print("="); 1655 TimeUtils.formatDuration(FLEX_TIME_SHORT, pw); 1656 pw.println(); 1657 1658 pw.print(" "); 1659 pw.print(KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT); 1660 pw.print("="); 1661 TimeUtils.formatDuration(LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT, pw); 1662 pw.println(); 1663 1664 pw.print(" "); pw.print(KEY_LIGHT_IDLE_TIMEOUT); pw.print("="); 1665 TimeUtils.formatDuration(LIGHT_IDLE_TIMEOUT, pw); 1666 pw.println(); 1667 1668 pw.print(" "); pw.print(KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX); pw.print("="); 1669 TimeUtils.formatDuration(LIGHT_IDLE_TIMEOUT_INITIAL_FLEX, pw); 1670 pw.println(); 1671 1672 pw.print(" "); pw.print(KEY_LIGHT_IDLE_TIMEOUT_MAX_FLEX); pw.print("="); 1673 TimeUtils.formatDuration(LIGHT_IDLE_TIMEOUT_MAX_FLEX, pw); 1674 pw.println(); 1675 1676 pw.print(" "); pw.print(KEY_LIGHT_IDLE_FACTOR); pw.print("="); 1677 pw.print(LIGHT_IDLE_FACTOR); 1678 pw.println(); 1679 1680 pw.print(" "); pw.print(KEY_LIGHT_MAX_IDLE_TIMEOUT); pw.print("="); 1681 TimeUtils.formatDuration(LIGHT_MAX_IDLE_TIMEOUT, pw); 1682 pw.println(); 1683 1684 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET); pw.print("="); 1685 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MIN_BUDGET, pw); 1686 pw.println(); 1687 1688 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET); pw.print("="); 1689 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MAX_BUDGET, pw); 1690 pw.println(); 1691 1692 pw.print(" "); pw.print(KEY_MIN_LIGHT_MAINTENANCE_TIME); pw.print("="); 1693 TimeUtils.formatDuration(MIN_LIGHT_MAINTENANCE_TIME, pw); 1694 pw.println(); 1695 1696 pw.print(" "); pw.print(KEY_MIN_DEEP_MAINTENANCE_TIME); pw.print("="); 1697 TimeUtils.formatDuration(MIN_DEEP_MAINTENANCE_TIME, pw); 1698 pw.println(); 1699 1700 pw.print(" "); pw.print(KEY_INACTIVE_TIMEOUT); pw.print("="); 1701 TimeUtils.formatDuration(INACTIVE_TIMEOUT, pw); 1702 pw.println(); 1703 1704 pw.print(" "); pw.print(KEY_SENSING_TIMEOUT); pw.print("="); 1705 TimeUtils.formatDuration(SENSING_TIMEOUT, pw); 1706 pw.println(); 1707 1708 pw.print(" "); pw.print(KEY_LOCATING_TIMEOUT); pw.print("="); 1709 TimeUtils.formatDuration(LOCATING_TIMEOUT, pw); 1710 pw.println(); 1711 1712 pw.print(" "); pw.print(KEY_LOCATION_ACCURACY); pw.print("="); 1713 pw.print(LOCATION_ACCURACY); pw.print("m"); 1714 pw.println(); 1715 1716 pw.print(" "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT); pw.print("="); 1717 TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT, pw); 1718 pw.println(); 1719 1720 pw.print(" "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT_FLEX); pw.print("="); 1721 TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT_FLEX, pw); 1722 pw.println(); 1723 1724 pw.print(" "); pw.print(KEY_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("="); 1725 TimeUtils.formatDuration(IDLE_AFTER_INACTIVE_TIMEOUT, pw); 1726 pw.println(); 1727 1728 pw.print(" "); pw.print(KEY_IDLE_PENDING_TIMEOUT); pw.print("="); 1729 TimeUtils.formatDuration(IDLE_PENDING_TIMEOUT, pw); 1730 pw.println(); 1731 1732 pw.print(" "); pw.print(KEY_MAX_IDLE_PENDING_TIMEOUT); pw.print("="); 1733 TimeUtils.formatDuration(MAX_IDLE_PENDING_TIMEOUT, pw); 1734 pw.println(); 1735 1736 pw.print(" "); pw.print(KEY_IDLE_PENDING_FACTOR); pw.print("="); 1737 pw.println(IDLE_PENDING_FACTOR); 1738 1739 pw.print(" "); pw.print(KEY_QUICK_DOZE_DELAY_TIMEOUT); pw.print("="); 1740 TimeUtils.formatDuration(QUICK_DOZE_DELAY_TIMEOUT, pw); 1741 pw.println(); 1742 1743 pw.print(" "); pw.print(KEY_IDLE_TIMEOUT); pw.print("="); 1744 TimeUtils.formatDuration(IDLE_TIMEOUT, pw); 1745 pw.println(); 1746 1747 pw.print(" "); pw.print(KEY_MAX_IDLE_TIMEOUT); pw.print("="); 1748 TimeUtils.formatDuration(MAX_IDLE_TIMEOUT, pw); 1749 pw.println(); 1750 1751 pw.print(" "); pw.print(KEY_IDLE_FACTOR); pw.print("="); 1752 pw.println(IDLE_FACTOR); 1753 1754 pw.print(" "); pw.print(KEY_MIN_TIME_TO_ALARM); pw.print("="); 1755 TimeUtils.formatDuration(MIN_TIME_TO_ALARM, pw); 1756 pw.println(); 1757 1758 pw.print(" "); pw.print(KEY_MAX_TEMP_APP_ALLOWLIST_DURATION_MS); pw.print("="); 1759 TimeUtils.formatDuration(MAX_TEMP_APP_ALLOWLIST_DURATION_MS, pw); 1760 pw.println(); 1761 1762 pw.print(" "); pw.print(KEY_MMS_TEMP_APP_ALLOWLIST_DURATION_MS); pw.print("="); 1763 TimeUtils.formatDuration(MMS_TEMP_APP_ALLOWLIST_DURATION_MS, pw); 1764 pw.println(); 1765 1766 pw.print(" "); pw.print(KEY_SMS_TEMP_APP_ALLOWLIST_DURATION_MS); pw.print("="); 1767 TimeUtils.formatDuration(SMS_TEMP_APP_ALLOWLIST_DURATION_MS, pw); 1768 pw.println(); 1769 1770 pw.print(" "); pw.print(KEY_NOTIFICATION_ALLOWLIST_DURATION_MS); pw.print("="); 1771 TimeUtils.formatDuration(NOTIFICATION_ALLOWLIST_DURATION_MS, pw); 1772 pw.println(); 1773 1774 pw.print(" "); pw.print(KEY_WAIT_FOR_UNLOCK); pw.print("="); 1775 pw.println(WAIT_FOR_UNLOCK); 1776 1777 pw.print(" "); pw.print(KEY_PRE_IDLE_FACTOR_LONG); pw.print("="); 1778 pw.println(PRE_IDLE_FACTOR_LONG); 1779 1780 pw.print(" "); pw.print(KEY_PRE_IDLE_FACTOR_SHORT); pw.print("="); 1781 pw.println(PRE_IDLE_FACTOR_SHORT); 1782 1783 pw.print(" "); pw.print(KEY_USE_WINDOW_ALARMS); pw.print("="); 1784 pw.println(USE_WINDOW_ALARMS); 1785 } 1786 } 1787 1788 private Constants mConstants; 1789 1790 @Override onAnyMotionResult(int result)1791 public void onAnyMotionResult(int result) { 1792 if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")"); 1793 synchronized (this) { 1794 if (result != AnyMotionDetector.RESULT_UNKNOWN) { 1795 cancelSensingTimeoutAlarmLocked(); 1796 } 1797 if ((result == AnyMotionDetector.RESULT_MOVED) 1798 || (result == AnyMotionDetector.RESULT_UNKNOWN)) { 1799 handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "non_stationary"); 1800 } else if (result == AnyMotionDetector.RESULT_STATIONARY) { 1801 if (mState == STATE_SENSING) { 1802 // If we are currently sensing, it is time to move to locating. 1803 mNotMoving = true; 1804 stepIdleStateLocked("s:stationary"); 1805 } else if (mState == STATE_LOCATING) { 1806 // If we are currently locating, note that we are not moving and step 1807 // if we have located the position. 1808 mNotMoving = true; 1809 if (mLocated) { 1810 stepIdleStateLocked("s:stationary"); 1811 } 1812 } 1813 } 1814 } 1815 } 1816 1817 private static final int MSG_WRITE_CONFIG = 1; 1818 private static final int MSG_REPORT_IDLE_ON = 2; 1819 private static final int MSG_REPORT_IDLE_ON_LIGHT = 3; 1820 private static final int MSG_REPORT_IDLE_OFF = 4; 1821 private static final int MSG_REPORT_ACTIVE = 5; 1822 private static final int MSG_TEMP_APP_WHITELIST_TIMEOUT = 6; 1823 @VisibleForTesting 1824 static final int MSG_REPORT_STATIONARY_STATUS = 7; 1825 private static final int MSG_FINISH_IDLE_OP = 8; 1826 private static final int MSG_SEND_CONSTRAINT_MONITORING = 10; 1827 @VisibleForTesting 1828 static final int MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR = 11; 1829 @VisibleForTesting 1830 static final int MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR = 12; 1831 private static final int MSG_REPORT_TEMP_APP_WHITELIST_CHANGED = 13; 1832 private static final int MSG_REPORT_TEMP_APP_WHITELIST_ADDED_TO_NPMS = 14; 1833 private static final int MSG_REPORT_TEMP_APP_WHITELIST_REMOVED_TO_NPMS = 15; 1834 1835 final class MyHandler extends Handler { MyHandler(Looper looper)1836 MyHandler(Looper looper) { 1837 super(looper); 1838 } 1839 handleMessage(Message msg)1840 @Override public void handleMessage(Message msg) { 1841 if (DEBUG) Slog.d(TAG, "handleMessage(" + msg.what + ")"); 1842 switch (msg.what) { 1843 case MSG_WRITE_CONFIG: { 1844 // Does not hold a wakelock. Just let this happen whenever. 1845 handleWriteConfigFile(); 1846 } break; 1847 case MSG_REPORT_IDLE_ON: 1848 case MSG_REPORT_IDLE_ON_LIGHT: { 1849 // mGoingIdleWakeLock is held at this point 1850 EventLogTags.writeDeviceIdleOnStart(); 1851 final boolean deepChanged; 1852 final boolean lightChanged; 1853 if (msg.what == MSG_REPORT_IDLE_ON) { 1854 deepChanged = mLocalPowerManager.setDeviceIdleMode(true); 1855 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false); 1856 } else { 1857 deepChanged = mLocalPowerManager.setDeviceIdleMode(false); 1858 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(true); 1859 } 1860 try { 1861 mNetworkPolicyManager.setDeviceIdleMode(true); 1862 mBatteryStats.noteDeviceIdleMode(msg.what == MSG_REPORT_IDLE_ON 1863 ? BatteryStats.DEVICE_IDLE_MODE_DEEP 1864 : BatteryStats.DEVICE_IDLE_MODE_LIGHT, null, Process.myUid()); 1865 } catch (RemoteException e) { 1866 } 1867 if (deepChanged) { 1868 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL, 1869 null /* receiverPermission */, mIdleIntentOptions); 1870 } 1871 if (lightChanged) { 1872 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL, 1873 null /* receiverPermission */, mLightIdleIntentOptions); 1874 } 1875 EventLogTags.writeDeviceIdleOnComplete(); 1876 mGoingIdleWakeLock.release(); 1877 } break; 1878 case MSG_REPORT_IDLE_OFF: { 1879 // mActiveIdleWakeLock is held at this point 1880 EventLogTags.writeDeviceIdleOffStart("unknown"); 1881 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false); 1882 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false); 1883 try { 1884 mNetworkPolicyManager.setDeviceIdleMode(false); 1885 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF, 1886 null, Process.myUid()); 1887 } catch (RemoteException e) { 1888 } 1889 if (deepChanged) { 1890 incActiveIdleOps(); 1891 mLocalActivityManager.broadcastIntentWithCallback(mIdleIntent, 1892 mIdleStartedDoneReceiver, null, UserHandle.USER_ALL, 1893 null, null, mIdleIntentOptions); 1894 } 1895 if (lightChanged) { 1896 incActiveIdleOps(); 1897 mLocalActivityManager.broadcastIntentWithCallback(mLightIdleIntent, 1898 mIdleStartedDoneReceiver, null, UserHandle.USER_ALL, 1899 null, null, mLightIdleIntentOptions); 1900 } 1901 // Always start with one active op for the message being sent here. 1902 // Now we are done! 1903 decActiveIdleOps(); 1904 EventLogTags.writeDeviceIdleOffComplete(); 1905 } break; 1906 case MSG_REPORT_ACTIVE: { 1907 // The device is awake at this point, so no wakelock necessary. 1908 String activeReason = (String)msg.obj; 1909 int activeUid = msg.arg1; 1910 EventLogTags.writeDeviceIdleOffStart( 1911 activeReason != null ? activeReason : "unknown"); 1912 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false); 1913 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false); 1914 try { 1915 mNetworkPolicyManager.setDeviceIdleMode(false); 1916 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF, 1917 activeReason, activeUid); 1918 } catch (RemoteException e) { 1919 } 1920 if (deepChanged) { 1921 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL, 1922 null /* receiverPermission */, mIdleIntentOptions); 1923 } 1924 if (lightChanged) { 1925 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL, 1926 null /* receiverPermission */, mLightIdleIntentOptions); 1927 } 1928 EventLogTags.writeDeviceIdleOffComplete(); 1929 } break; 1930 case MSG_TEMP_APP_WHITELIST_TIMEOUT: { 1931 // TODO: What is keeping the device awake at this point? Does it need to be? 1932 int uid = msg.arg1; 1933 checkTempAppWhitelistTimeout(uid); 1934 } break; 1935 case MSG_FINISH_IDLE_OP: { 1936 // mActiveIdleWakeLock is held at this point 1937 decActiveIdleOps(); 1938 } break; 1939 case MSG_REPORT_TEMP_APP_WHITELIST_CHANGED: { 1940 final int uid = msg.arg1; 1941 final boolean added = (msg.arg2 == 1); 1942 PowerAllowlistInternal.TempAllowlistChangeListener[] listeners; 1943 synchronized (DeviceIdleController.this) { 1944 listeners = mTempAllowlistChangeListeners.toArray( 1945 new PowerAllowlistInternal.TempAllowlistChangeListener[ 1946 mTempAllowlistChangeListeners.size()]); 1947 } 1948 for (PowerAllowlistInternal.TempAllowlistChangeListener listener : listeners) { 1949 if (added) { 1950 listener.onAppAdded(uid); 1951 } else { 1952 listener.onAppRemoved(uid); 1953 } 1954 } 1955 } break; 1956 case MSG_REPORT_TEMP_APP_WHITELIST_ADDED_TO_NPMS: { 1957 final int appId = msg.arg1; 1958 final int reasonCode = msg.arg2; 1959 final String reason = (String) msg.obj; 1960 mNetworkPolicyManagerInternal.onTempPowerSaveWhitelistChange(appId, true, 1961 reasonCode, reason); 1962 } break; 1963 case MSG_REPORT_TEMP_APP_WHITELIST_REMOVED_TO_NPMS: { 1964 final int appId = msg.arg1; 1965 mNetworkPolicyManagerInternal.onTempPowerSaveWhitelistChange(appId, false, 1966 REASON_UNKNOWN, /* reason= */ null); 1967 } break; 1968 case MSG_SEND_CONSTRAINT_MONITORING: { 1969 final IDeviceIdleConstraint constraint = (IDeviceIdleConstraint) msg.obj; 1970 final boolean monitoring = (msg.arg1 == 1); 1971 if (monitoring) { 1972 constraint.startMonitoring(); 1973 } else { 1974 constraint.stopMonitoring(); 1975 } 1976 } break; 1977 case MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR: { 1978 updatePreIdleFactor(); 1979 } break; 1980 case MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR: { 1981 updatePreIdleFactor(); 1982 maybeDoImmediateMaintenance("idle factor"); 1983 } break; 1984 case MSG_REPORT_STATIONARY_STATUS: { 1985 final DeviceIdleInternal.StationaryListener newListener = 1986 (DeviceIdleInternal.StationaryListener) msg.obj; 1987 final DeviceIdleInternal.StationaryListener[] listeners; 1988 final boolean isStationary; 1989 synchronized (DeviceIdleController.this) { 1990 isStationary = isStationaryLocked(); 1991 if (newListener == null) { 1992 // Only notify all listeners if we aren't directing to one listener. 1993 listeners = mStationaryListeners.toArray( 1994 new DeviceIdleInternal.StationaryListener[ 1995 mStationaryListeners.size()]); 1996 } else { 1997 listeners = null; 1998 } 1999 } 2000 if (listeners != null) { 2001 for (DeviceIdleInternal.StationaryListener listener : listeners) { 2002 listener.onDeviceStationaryChanged(isStationary); 2003 } 2004 } 2005 if (newListener != null) { 2006 newListener.onDeviceStationaryChanged(isStationary); 2007 } 2008 } 2009 break; 2010 } 2011 } 2012 } 2013 2014 final MyHandler mHandler; 2015 2016 BinderService mBinderService; 2017 2018 private final class BinderService extends IDeviceIdleController.Stub { addPowerSaveWhitelistApp(String name)2019 @Override public void addPowerSaveWhitelistApp(String name) { 2020 if (DEBUG) { 2021 Slog.i(TAG, "addPowerSaveWhitelistApp(name = " + name + ")"); 2022 } 2023 addPowerSaveWhitelistApps(Collections.singletonList(name)); 2024 } 2025 2026 @Override addPowerSaveWhitelistApps(List<String> packageNames)2027 public int addPowerSaveWhitelistApps(List<String> packageNames) { 2028 if (DEBUG) { 2029 Slog.i(TAG, 2030 "addPowerSaveWhitelistApps(name = " + packageNames + ")"); 2031 } 2032 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 2033 null); 2034 final long ident = Binder.clearCallingIdentity(); 2035 try { 2036 return addPowerSaveWhitelistAppsInternal(packageNames); 2037 } finally { 2038 Binder.restoreCallingIdentity(ident); 2039 } 2040 } 2041 removePowerSaveWhitelistApp(String name)2042 @Override public void removePowerSaveWhitelistApp(String name) { 2043 if (DEBUG) { 2044 Slog.i(TAG, "removePowerSaveWhitelistApp(name = " + name + ")"); 2045 } 2046 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 2047 null); 2048 final long ident = Binder.clearCallingIdentity(); 2049 try { 2050 if (!removePowerSaveWhitelistAppInternal(name) 2051 && mPowerSaveWhitelistAppsExceptIdle.containsKey(name)) { 2052 throw new UnsupportedOperationException("Cannot remove system whitelisted app"); 2053 } 2054 } finally { 2055 Binder.restoreCallingIdentity(ident); 2056 } 2057 } 2058 removeSystemPowerWhitelistApp(String name)2059 @Override public void removeSystemPowerWhitelistApp(String name) { 2060 if (DEBUG) { 2061 Slog.d(TAG, "removeAppFromSystemWhitelist(name = " + name + ")"); 2062 } 2063 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 2064 null); 2065 final long ident = Binder.clearCallingIdentity(); 2066 try { 2067 removeSystemPowerWhitelistAppInternal(name); 2068 } finally { 2069 Binder.restoreCallingIdentity(ident); 2070 } 2071 } 2072 restoreSystemPowerWhitelistApp(String name)2073 @Override public void restoreSystemPowerWhitelistApp(String name) { 2074 if (DEBUG) { 2075 Slog.d(TAG, "restoreAppToSystemWhitelist(name = " + name + ")"); 2076 } 2077 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 2078 null); 2079 final long ident = Binder.clearCallingIdentity(); 2080 try { 2081 restoreSystemPowerWhitelistAppInternal(name); 2082 } finally { 2083 Binder.restoreCallingIdentity(ident); 2084 } 2085 } 2086 getRemovedSystemPowerWhitelistApps()2087 public String[] getRemovedSystemPowerWhitelistApps() { 2088 return getRemovedSystemPowerWhitelistAppsInternal( 2089 Binder.getCallingUid(), UserHandle.getCallingUserId()); 2090 } 2091 getSystemPowerWhitelistExceptIdle()2092 @Override public String[] getSystemPowerWhitelistExceptIdle() { 2093 return getSystemPowerWhitelistExceptIdleInternal( 2094 Binder.getCallingUid(), UserHandle.getCallingUserId()); 2095 } 2096 getSystemPowerWhitelist()2097 @Override public String[] getSystemPowerWhitelist() { 2098 return getSystemPowerWhitelistInternal( 2099 Binder.getCallingUid(), UserHandle.getCallingUserId()); 2100 } 2101 getUserPowerWhitelist()2102 @Override public String[] getUserPowerWhitelist() { 2103 return getUserPowerWhitelistInternal( 2104 Binder.getCallingUid(), UserHandle.getCallingUserId()); 2105 } 2106 getFullPowerWhitelistExceptIdle()2107 @Override public String[] getFullPowerWhitelistExceptIdle() { 2108 return getFullPowerWhitelistExceptIdleInternal( 2109 Binder.getCallingUid(), UserHandle.getCallingUserId()); 2110 } 2111 getFullPowerWhitelist()2112 @Override public String[] getFullPowerWhitelist() { 2113 return getFullPowerWhitelistInternal( 2114 Binder.getCallingUid(), UserHandle.getCallingUserId()); 2115 } 2116 getAppIdWhitelistExceptIdle()2117 @Override public int[] getAppIdWhitelistExceptIdle() { 2118 return getAppIdWhitelistExceptIdleInternal(); 2119 } 2120 getAppIdWhitelist()2121 @Override public int[] getAppIdWhitelist() { 2122 return getAppIdWhitelistInternal(); 2123 } 2124 getAppIdUserWhitelist()2125 @Override public int[] getAppIdUserWhitelist() { 2126 return getAppIdUserWhitelistInternal(); 2127 } 2128 getAppIdTempWhitelist()2129 @Override public int[] getAppIdTempWhitelist() { 2130 return getAppIdTempWhitelistInternal(); 2131 } 2132 isPowerSaveWhitelistExceptIdleApp(String name)2133 @Override public boolean isPowerSaveWhitelistExceptIdleApp(String name) { 2134 if (mPackageManagerInternal 2135 .filterAppAccess(name, Binder.getCallingUid(), UserHandle.getCallingUserId())) { 2136 return false; 2137 } 2138 return isPowerSaveWhitelistExceptIdleAppInternal(name); 2139 } 2140 isPowerSaveWhitelistApp(String name)2141 @Override public boolean isPowerSaveWhitelistApp(String name) { 2142 if (mPackageManagerInternal 2143 .filterAppAccess(name, Binder.getCallingUid(), UserHandle.getCallingUserId())) { 2144 return false; 2145 } 2146 return isPowerSaveWhitelistAppInternal(name); 2147 } 2148 2149 @Override whitelistAppTemporarily(String packageName, int userId, @ReasonCode int reasonCode, @Nullable String reason)2150 public long whitelistAppTemporarily(String packageName, int userId, 2151 @ReasonCode int reasonCode, @Nullable String reason) throws RemoteException { 2152 // At least 10 seconds. 2153 long durationMs = Math.max(10_000L, mConstants.MAX_TEMP_APP_ALLOWLIST_DURATION_MS / 2); 2154 addPowerSaveTempAllowlistAppChecked(packageName, durationMs, userId, reasonCode, 2155 reason); 2156 return durationMs; 2157 } 2158 2159 @Override addPowerSaveTempWhitelistApp(String packageName, long duration, int userId, @ReasonCode int reasonCode, @Nullable String reason)2160 public void addPowerSaveTempWhitelistApp(String packageName, long duration, int userId, 2161 @ReasonCode int reasonCode, @Nullable String reason) throws RemoteException { 2162 addPowerSaveTempAllowlistAppChecked(packageName, duration, userId, reasonCode, reason); 2163 } 2164 addPowerSaveTempWhitelistAppForMms(String packageName, int userId, @ReasonCode int reasonCode, @Nullable String reason)2165 @Override public long addPowerSaveTempWhitelistAppForMms(String packageName, int userId, 2166 @ReasonCode int reasonCode, @Nullable String reason) throws RemoteException { 2167 long durationMs = mConstants.MMS_TEMP_APP_ALLOWLIST_DURATION_MS; 2168 addPowerSaveTempAllowlistAppChecked(packageName, durationMs, userId, reasonCode, 2169 reason); 2170 return durationMs; 2171 } 2172 addPowerSaveTempWhitelistAppForSms(String packageName, int userId, @ReasonCode int reasonCode, @Nullable String reason)2173 @Override public long addPowerSaveTempWhitelistAppForSms(String packageName, int userId, 2174 @ReasonCode int reasonCode, @Nullable String reason) throws RemoteException { 2175 long durationMs = mConstants.SMS_TEMP_APP_ALLOWLIST_DURATION_MS; 2176 addPowerSaveTempAllowlistAppChecked(packageName, durationMs, userId, reasonCode, 2177 reason); 2178 return durationMs; 2179 } 2180 exitIdle(String reason)2181 @Override public void exitIdle(String reason) { 2182 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER, 2183 null); 2184 final long ident = Binder.clearCallingIdentity(); 2185 try { 2186 exitIdleInternal(reason); 2187 } finally { 2188 Binder.restoreCallingIdentity(ident); 2189 } 2190 } 2191 setPreIdleTimeoutMode(int mode)2192 @Override public int setPreIdleTimeoutMode(int mode) { 2193 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER, 2194 null); 2195 final long ident = Binder.clearCallingIdentity(); 2196 try { 2197 return DeviceIdleController.this.setPreIdleTimeoutMode(mode); 2198 } finally { 2199 Binder.restoreCallingIdentity(ident); 2200 } 2201 } 2202 resetPreIdleTimeoutMode()2203 @Override public void resetPreIdleTimeoutMode() { 2204 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER, 2205 null); 2206 final long ident = Binder.clearCallingIdentity(); 2207 try { 2208 DeviceIdleController.this.resetPreIdleTimeoutMode(); 2209 } finally { 2210 Binder.restoreCallingIdentity(ident); 2211 } 2212 } 2213 dump(FileDescriptor fd, PrintWriter pw, String[] args)2214 @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2215 DeviceIdleController.this.dump(fd, pw, args); 2216 } 2217 onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)2218 @Override public void onShellCommand(FileDescriptor in, FileDescriptor out, 2219 FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) { 2220 (new Shell()).exec(this, in, out, err, args, callback, resultReceiver); 2221 } 2222 } 2223 2224 private class LocalService implements DeviceIdleInternal { 2225 @Override onConstraintStateChanged(IDeviceIdleConstraint constraint, boolean active)2226 public void onConstraintStateChanged(IDeviceIdleConstraint constraint, boolean active) { 2227 synchronized (DeviceIdleController.this) { 2228 onConstraintStateChangedLocked(constraint, active); 2229 } 2230 } 2231 2232 @Override registerDeviceIdleConstraint(IDeviceIdleConstraint constraint, String name, @IDeviceIdleConstraint.MinimumState int minState)2233 public void registerDeviceIdleConstraint(IDeviceIdleConstraint constraint, String name, 2234 @IDeviceIdleConstraint.MinimumState int minState) { 2235 registerDeviceIdleConstraintInternal(constraint, name, minState); 2236 } 2237 2238 @Override unregisterDeviceIdleConstraint(IDeviceIdleConstraint constraint)2239 public void unregisterDeviceIdleConstraint(IDeviceIdleConstraint constraint) { 2240 unregisterDeviceIdleConstraintInternal(constraint); 2241 } 2242 2243 @Override exitIdle(String reason)2244 public void exitIdle(String reason) { 2245 exitIdleInternal(reason); 2246 } 2247 2248 @Override addPowerSaveTempWhitelistApp(int callingUid, String packageName, long durationMs, int userId, boolean sync, @ReasonCode int reasonCode, @Nullable String reason)2249 public void addPowerSaveTempWhitelistApp(int callingUid, String packageName, 2250 long durationMs, int userId, boolean sync, @ReasonCode int reasonCode, 2251 @Nullable String reason) { 2252 addPowerSaveTempAllowlistAppInternal(callingUid, packageName, durationMs, 2253 TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, 2254 userId, sync, reasonCode, reason); 2255 } 2256 2257 @Override addPowerSaveTempWhitelistApp(int callingUid, String packageName, long durationMs, @TempAllowListType int tempAllowListType, int userId, boolean sync, @ReasonCode int reasonCode, @Nullable String reason)2258 public void addPowerSaveTempWhitelistApp(int callingUid, String packageName, 2259 long durationMs, @TempAllowListType int tempAllowListType, int userId, boolean sync, 2260 @ReasonCode int reasonCode, @Nullable String reason) { 2261 addPowerSaveTempAllowlistAppInternal(callingUid, packageName, durationMs, 2262 tempAllowListType, userId, sync, reasonCode, reason); 2263 } 2264 2265 @Override addPowerSaveTempWhitelistAppDirect(int uid, long durationMs, @TempAllowListType int tempAllowListType, boolean sync, @ReasonCode int reasonCode, @Nullable String reason, int callingUid)2266 public void addPowerSaveTempWhitelistAppDirect(int uid, long durationMs, 2267 @TempAllowListType int tempAllowListType, boolean sync, @ReasonCode int reasonCode, 2268 @Nullable String reason, int callingUid) { 2269 addPowerSaveTempWhitelistAppDirectInternal(callingUid, uid, durationMs, 2270 tempAllowListType, sync, reasonCode, reason); 2271 } 2272 2273 // duration in milliseconds 2274 @Override getNotificationAllowlistDuration()2275 public long getNotificationAllowlistDuration() { 2276 return mConstants.NOTIFICATION_ALLOWLIST_DURATION_MS; 2277 } 2278 2279 @Override setJobsActive(boolean active)2280 public void setJobsActive(boolean active) { 2281 DeviceIdleController.this.setJobsActive(active); 2282 } 2283 2284 // Up-call from alarm manager. 2285 @Override setAlarmsActive(boolean active)2286 public void setAlarmsActive(boolean active) { 2287 DeviceIdleController.this.setAlarmsActive(active); 2288 } 2289 2290 /** Is the app on any of the power save whitelists, whether system or user? */ 2291 @Override isAppOnWhitelist(int appid)2292 public boolean isAppOnWhitelist(int appid) { 2293 return DeviceIdleController.this.isAppOnWhitelistInternal(appid); 2294 } 2295 2296 /** 2297 * Returns the array of app ids whitelisted by user. Take care not to 2298 * modify this, as it is a reference to the original copy. But the reference 2299 * can change when the list changes, so it needs to be re-acquired when 2300 * {@link PowerManager#ACTION_POWER_SAVE_WHITELIST_CHANGED} is sent. 2301 */ 2302 @Override getPowerSaveWhitelistUserAppIds()2303 public int[] getPowerSaveWhitelistUserAppIds() { 2304 return DeviceIdleController.this.getPowerSaveWhitelistUserAppIds(); 2305 } 2306 2307 @Override getPowerSaveTempWhitelistAppIds()2308 public int[] getPowerSaveTempWhitelistAppIds() { 2309 return DeviceIdleController.this.getAppIdTempWhitelistInternal(); 2310 } 2311 2312 @Override registerStationaryListener(StationaryListener listener)2313 public void registerStationaryListener(StationaryListener listener) { 2314 DeviceIdleController.this.registerStationaryListener(listener); 2315 } 2316 2317 @Override unregisterStationaryListener(StationaryListener listener)2318 public void unregisterStationaryListener(StationaryListener listener) { 2319 DeviceIdleController.this.unregisterStationaryListener(listener); 2320 } 2321 2322 @Override getTempAllowListType(@easonCode int reasonCode, @TempAllowListType int defaultType)2323 public @TempAllowListType int getTempAllowListType(@ReasonCode int reasonCode, 2324 @TempAllowListType int defaultType) { 2325 return DeviceIdleController.this.getTempAllowListType(reasonCode, defaultType); 2326 } 2327 } 2328 2329 private class LocalPowerAllowlistService implements PowerAllowlistInternal { 2330 2331 @Override registerTempAllowlistChangeListener( @onNull TempAllowlistChangeListener listener)2332 public void registerTempAllowlistChangeListener( 2333 @NonNull TempAllowlistChangeListener listener) { 2334 DeviceIdleController.this.registerTempAllowlistChangeListener(listener); 2335 } 2336 2337 @Override unregisterTempAllowlistChangeListener( @onNull TempAllowlistChangeListener listener)2338 public void unregisterTempAllowlistChangeListener( 2339 @NonNull TempAllowlistChangeListener listener) { 2340 DeviceIdleController.this.unregisterTempAllowlistChangeListener(listener); 2341 } 2342 } 2343 2344 private class EmergencyCallListener extends TelephonyCallback implements 2345 TelephonyCallback.OutgoingEmergencyCallListener, 2346 TelephonyCallback.CallStateListener { 2347 private volatile boolean mIsEmergencyCallActive; 2348 2349 @Override onOutgoingEmergencyCall(EmergencyNumber placedEmergencyNumber, int subscriptionId)2350 public void onOutgoingEmergencyCall(EmergencyNumber placedEmergencyNumber, 2351 int subscriptionId) { 2352 mIsEmergencyCallActive = true; 2353 if (DEBUG) Slog.d(TAG, "onOutgoingEmergencyCall(): subId = " + subscriptionId); 2354 synchronized (DeviceIdleController.this) { 2355 mActiveReason = ACTIVE_REASON_EMERGENCY_CALL; 2356 becomeActiveLocked("emergency call", Process.myUid()); 2357 } 2358 } 2359 2360 @Override onCallStateChanged(int state)2361 public void onCallStateChanged(int state) { 2362 if (DEBUG) Slog.d(TAG, "onCallStateChanged(): state is " + state); 2363 // An emergency call just finished 2364 if (state == TelephonyManager.CALL_STATE_IDLE && mIsEmergencyCallActive) { 2365 mIsEmergencyCallActive = false; 2366 synchronized (DeviceIdleController.this) { 2367 becomeInactiveIfAppropriateLocked(); 2368 } 2369 } 2370 } 2371 isEmergencyCallActive()2372 boolean isEmergencyCallActive() { 2373 return mIsEmergencyCallActive; 2374 } 2375 } 2376 2377 static class Injector { 2378 private final Context mContext; 2379 private ConnectivityManager mConnectivityManager; 2380 private Constants mConstants; 2381 private LocationManager mLocationManager; 2382 Injector(Context ctx)2383 Injector(Context ctx) { 2384 mContext = ctx.createAttributionContext(TAG); 2385 } 2386 getAlarmManager()2387 AlarmManager getAlarmManager() { 2388 return mContext.getSystemService(AlarmManager.class); 2389 } 2390 getAnyMotionDetector(Handler handler, SensorManager sm, AnyMotionDetector.DeviceIdleCallback callback, float angleThreshold)2391 AnyMotionDetector getAnyMotionDetector(Handler handler, SensorManager sm, 2392 AnyMotionDetector.DeviceIdleCallback callback, float angleThreshold) { 2393 return new AnyMotionDetector(getPowerManager(), handler, sm, callback, angleThreshold); 2394 } 2395 getAppStateTracker(Context ctx, Looper looper)2396 AppStateTrackerImpl getAppStateTracker(Context ctx, Looper looper) { 2397 return new AppStateTrackerImpl(ctx, looper); 2398 } 2399 getConnectivityManager()2400 ConnectivityManager getConnectivityManager() { 2401 if (mConnectivityManager == null) { 2402 mConnectivityManager = mContext.getSystemService(ConnectivityManager.class); 2403 } 2404 return mConnectivityManager; 2405 } 2406 getConstants(DeviceIdleController controller)2407 Constants getConstants(DeviceIdleController controller) { 2408 if (mConstants == null) { 2409 mConstants = controller.new Constants(); 2410 } 2411 return mConstants; 2412 } 2413 2414 /** Returns the current elapsed realtime in milliseconds. */ getElapsedRealtime()2415 long getElapsedRealtime() { 2416 return SystemClock.elapsedRealtime(); 2417 } 2418 getLocationManager()2419 LocationManager getLocationManager() { 2420 if (mLocationManager == null) { 2421 mLocationManager = mContext.getSystemService(LocationManager.class); 2422 } 2423 return mLocationManager; 2424 } 2425 getHandler(DeviceIdleController controller)2426 MyHandler getHandler(DeviceIdleController controller) { 2427 return controller.new MyHandler(AppSchedulingModuleThread.getHandler().getLooper()); 2428 } 2429 getMotionSensor()2430 Sensor getMotionSensor() { 2431 final SensorManager sensorManager = getSensorManager(); 2432 Sensor motionSensor = null; 2433 int sigMotionSensorId = mContext.getResources().getInteger( 2434 com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor); 2435 if (sigMotionSensorId > 0) { 2436 motionSensor = sensorManager.getDefaultSensor(sigMotionSensorId, true); 2437 } 2438 if (motionSensor == null && mContext.getResources().getBoolean( 2439 com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) { 2440 motionSensor = sensorManager.getDefaultSensor( 2441 Sensor.TYPE_WRIST_TILT_GESTURE, true); 2442 } 2443 if (motionSensor == null) { 2444 // As a last ditch, fall back to SMD. 2445 motionSensor = sensorManager.getDefaultSensor( 2446 Sensor.TYPE_SIGNIFICANT_MOTION, true); 2447 } 2448 return motionSensor; 2449 } 2450 getPowerManager()2451 PowerManager getPowerManager() { 2452 return mContext.getSystemService(PowerManager.class); 2453 } 2454 getSensorManager()2455 SensorManager getSensorManager() { 2456 return mContext.getSystemService(SensorManager.class); 2457 } 2458 getTelephonyManager()2459 TelephonyManager getTelephonyManager() { 2460 return mContext.getSystemService(TelephonyManager.class); 2461 } 2462 getConstraintController(Handler handler, DeviceIdleInternal localService)2463 ConstraintController getConstraintController(Handler handler, 2464 DeviceIdleInternal localService) { 2465 if (mContext.getPackageManager() 2466 .hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY)) { 2467 return new TvConstraintController(mContext, handler); 2468 } 2469 return null; 2470 } 2471 isLocationPrefetchEnabled()2472 boolean isLocationPrefetchEnabled() { 2473 return mContext.getResources().getBoolean( 2474 com.android.internal.R.bool.config_autoPowerModePrefetchLocation); 2475 } 2476 useMotionSensor()2477 boolean useMotionSensor() { 2478 return mContext.getResources().getBoolean( 2479 com.android.internal.R.bool.config_autoPowerModeUseMotionSensor); 2480 } 2481 } 2482 2483 private final Injector mInjector; 2484 2485 private ActivityTaskManagerInternal.ScreenObserver mScreenObserver = 2486 new ActivityTaskManagerInternal.ScreenObserver() { 2487 @Override 2488 public void onAwakeStateChanged(boolean isAwake) { } 2489 2490 @Override 2491 public void onKeyguardStateChanged(boolean isShowing) { 2492 synchronized (DeviceIdleController.this) { 2493 DeviceIdleController.this.keyguardShowingLocked(isShowing); 2494 } 2495 } 2496 }; 2497 DeviceIdleController(Context context, Injector injector)2498 @VisibleForTesting DeviceIdleController(Context context, Injector injector) { 2499 super(context); 2500 mInjector = injector; 2501 mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml")); 2502 mHandler = mInjector.getHandler(this); 2503 mAppStateTracker = mInjector.getAppStateTracker(context, 2504 AppSchedulingModuleThread.get().getLooper()); 2505 LocalServices.addService(AppStateTracker.class, mAppStateTracker); 2506 mIsLocationPrefetchEnabled = mInjector.isLocationPrefetchEnabled(); 2507 mUseMotionSensor = mInjector.useMotionSensor(); 2508 } 2509 DeviceIdleController(Context context)2510 public DeviceIdleController(Context context) { 2511 this(context, new Injector(context)); 2512 } 2513 isAppOnWhitelistInternal(int appid)2514 boolean isAppOnWhitelistInternal(int appid) { 2515 synchronized (this) { 2516 return Arrays.binarySearch(mPowerSaveWhitelistAllAppIdArray, appid) >= 0; 2517 } 2518 } 2519 getPowerSaveWhitelistUserAppIds()2520 int[] getPowerSaveWhitelistUserAppIds() { 2521 synchronized (this) { 2522 return mPowerSaveWhitelistUserAppIdArray; 2523 } 2524 } 2525 getSystemDir()2526 private static File getSystemDir() { 2527 return new File(Environment.getDataDirectory(), "system"); 2528 } 2529 2530 @Override onStart()2531 public void onStart() { 2532 final PackageManager pm = getContext().getPackageManager(); 2533 2534 synchronized (this) { 2535 mLightEnabled = mDeepEnabled = getContext().getResources().getBoolean( 2536 com.android.internal.R.bool.config_enableAutoPowerModes); 2537 SystemConfig sysConfig = SystemConfig.getInstance(); 2538 ArraySet<String> allowPowerExceptIdle = sysConfig.getAllowInPowerSaveExceptIdle(); 2539 for (int i=0; i<allowPowerExceptIdle.size(); i++) { 2540 String pkg = allowPowerExceptIdle.valueAt(i); 2541 try { 2542 ApplicationInfo ai = pm.getApplicationInfo(pkg, 2543 PackageManager.MATCH_SYSTEM_ONLY); 2544 int appid = UserHandle.getAppId(ai.uid); 2545 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid); 2546 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true); 2547 } catch (PackageManager.NameNotFoundException e) { 2548 } 2549 } 2550 ArraySet<String> allowPower = sysConfig.getAllowInPowerSave(); 2551 for (int i=0; i<allowPower.size(); i++) { 2552 String pkg = allowPower.valueAt(i); 2553 try { 2554 ApplicationInfo ai = pm.getApplicationInfo(pkg, 2555 PackageManager.MATCH_SYSTEM_ONLY); 2556 int appid = UserHandle.getAppId(ai.uid); 2557 // These apps are on both the whitelist-except-idle as well 2558 // as the full whitelist, so they apply in all cases. 2559 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid); 2560 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true); 2561 mPowerSaveWhitelistApps.put(ai.packageName, appid); 2562 mPowerSaveWhitelistSystemAppIds.put(appid, true); 2563 } catch (PackageManager.NameNotFoundException e) { 2564 } 2565 } 2566 2567 mConstants = mInjector.getConstants(this); 2568 2569 readConfigFileLocked(); 2570 updateWhitelistAppIdsLocked(); 2571 2572 mNetworkConnected = true; 2573 mScreenOn = true; 2574 mScreenLocked = false; 2575 // Start out assuming we are charging. If we aren't, we will at least get 2576 // a battery update the next time the level drops. 2577 mCharging = true; 2578 mActiveReason = ACTIVE_REASON_UNKNOWN; 2579 moveToStateLocked(STATE_ACTIVE, "boot"); 2580 moveToLightStateLocked(LIGHT_STATE_ACTIVE, "boot"); 2581 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT; 2582 mPreIdleFactor = 1.0f; 2583 mLastPreIdleFactor = 1.0f; 2584 } 2585 2586 mBinderService = new BinderService(); 2587 publishBinderService(Context.DEVICE_IDLE_CONTROLLER, mBinderService); 2588 mLocalService = new LocalService(); 2589 publishLocalService(DeviceIdleInternal.class, mLocalService); 2590 publishLocalService(PowerAllowlistInternal.class, new LocalPowerAllowlistService()); 2591 } 2592 2593 @Override onBootPhase(int phase)2594 public void onBootPhase(int phase) { 2595 if (phase == PHASE_SYSTEM_SERVICES_READY) { 2596 synchronized (this) { 2597 mAlarmManager = mInjector.getAlarmManager(); 2598 mLocalAlarmManager = getLocalService(AlarmManagerInternal.class); 2599 mBatteryStats = BatteryStatsService.getService(); 2600 mLocalActivityManager = getLocalService(ActivityManagerInternal.class); 2601 mLocalActivityTaskManager = getLocalService(ActivityTaskManagerInternal.class); 2602 mPackageManagerInternal = getLocalService(PackageManagerInternal.class); 2603 mLocalPowerManager = getLocalService(PowerManagerInternal.class); 2604 mPowerManager = mInjector.getPowerManager(); 2605 mActiveIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 2606 "deviceidle_maint"); 2607 mActiveIdleWakeLock.setReferenceCounted(false); 2608 mGoingIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 2609 "deviceidle_going_idle"); 2610 mGoingIdleWakeLock.setReferenceCounted(true); 2611 mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface( 2612 ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)); 2613 mNetworkPolicyManagerInternal = getLocalService(NetworkPolicyManagerInternal.class); 2614 mSensorManager = mInjector.getSensorManager(); 2615 2616 if (mUseMotionSensor) { 2617 mMotionSensor = mInjector.getMotionSensor(); 2618 } 2619 2620 if (mIsLocationPrefetchEnabled) { 2621 mLocationRequest = new LocationRequest.Builder(/*intervalMillis=*/ 0) 2622 .setQuality(LocationRequest.QUALITY_HIGH_ACCURACY) 2623 .setMaxUpdates(1) 2624 .build(); 2625 } 2626 2627 mConstraintController = mInjector.getConstraintController( 2628 mHandler, getLocalService(LocalService.class)); 2629 if (mConstraintController != null) { 2630 mConstraintController.start(); 2631 } 2632 2633 float angleThreshold = getContext().getResources().getInteger( 2634 com.android.internal.R.integer.config_autoPowerModeThresholdAngle) / 100f; 2635 mAnyMotionDetector = mInjector.getAnyMotionDetector(mHandler, mSensorManager, this, 2636 angleThreshold); 2637 2638 mAppStateTracker.onSystemServicesReady(); 2639 2640 final Bundle mostRecentDeliveryOptions = BroadcastOptions.makeBasic() 2641 .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT) 2642 .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE) 2643 .toBundle(); 2644 2645 mIdleIntent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); 2646 mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 2647 | Intent.FLAG_RECEIVER_FOREGROUND); 2648 mLightIdleIntent = new Intent(PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED); 2649 mLightIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 2650 | Intent.FLAG_RECEIVER_FOREGROUND); 2651 mIdleIntentOptions = mLightIdleIntentOptions = mostRecentDeliveryOptions; 2652 2653 mPowerSaveWhitelistChangedIntent = new Intent( 2654 PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED); 2655 mPowerSaveWhitelistChangedIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 2656 mPowerSaveTempWhitelistChangedIntent = new Intent( 2657 PowerManager.ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED); 2658 mPowerSaveTempWhitelistChangedIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 2659 mPowerSaveWhitelistChangedOptions = mostRecentDeliveryOptions; 2660 mPowerSaveTempWhilelistChangedOptions = mostRecentDeliveryOptions; 2661 2662 IntentFilter filter = new IntentFilter(); 2663 filter.addAction(Intent.ACTION_BATTERY_CHANGED); 2664 getContext().registerReceiver(mReceiver, filter); 2665 2666 filter = new IntentFilter(); 2667 filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 2668 filter.addDataScheme("package"); 2669 getContext().registerReceiver(mReceiver, filter); 2670 2671 filter = new IntentFilter(); 2672 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 2673 getContext().registerReceiver(mReceiver, filter); 2674 2675 filter = new IntentFilter(); 2676 filter.addAction(Intent.ACTION_SCREEN_OFF); 2677 filter.addAction(Intent.ACTION_SCREEN_ON); 2678 getContext().registerReceiver(mInteractivityReceiver, filter); 2679 2680 mLocalActivityManager.setDeviceIdleAllowlist( 2681 mPowerSaveWhitelistAllAppIdArray, mPowerSaveWhitelistExceptIdleAppIdArray); 2682 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); 2683 2684 mLocalPowerManager.registerLowPowerModeObserver(ServiceType.QUICK_DOZE, 2685 state -> { 2686 synchronized (DeviceIdleController.this) { 2687 updateQuickDozeFlagLocked(state.batterySaverEnabled); 2688 } 2689 }); 2690 updateQuickDozeFlagLocked( 2691 mLocalPowerManager.getLowPowerState( 2692 ServiceType.QUICK_DOZE).batterySaverEnabled); 2693 2694 mLocalActivityTaskManager.registerScreenObserver(mScreenObserver); 2695 2696 mInjector.getTelephonyManager().registerTelephonyCallback( 2697 AppSchedulingModuleThread.getExecutor(), mEmergencyCallListener); 2698 2699 passWhiteListsToForceAppStandbyTrackerLocked(); 2700 updateInteractivityLocked(); 2701 } 2702 updateConnectivityState(null); 2703 } 2704 } 2705 2706 @VisibleForTesting hasMotionSensor()2707 boolean hasMotionSensor() { 2708 return mUseMotionSensor && mMotionSensor != null; 2709 } 2710 registerDeviceIdleConstraintInternal(IDeviceIdleConstraint constraint, final String name, final int type)2711 private void registerDeviceIdleConstraintInternal(IDeviceIdleConstraint constraint, 2712 final String name, final int type) { 2713 final int minState; 2714 switch (type) { 2715 case IDeviceIdleConstraint.ACTIVE: 2716 minState = STATE_ACTIVE; 2717 break; 2718 case IDeviceIdleConstraint.SENSING_OR_ABOVE: 2719 minState = STATE_SENSING; 2720 break; 2721 default: 2722 Slog.wtf(TAG, "Registering device-idle constraint with invalid type: " + type); 2723 return; 2724 } 2725 synchronized (this) { 2726 if (mConstraints.containsKey(constraint)) { 2727 Slog.e(TAG, "Re-registering device-idle constraint: " + constraint + "."); 2728 return; 2729 } 2730 DeviceIdleConstraintTracker tracker = new DeviceIdleConstraintTracker(name, minState); 2731 mConstraints.put(constraint, tracker); 2732 updateActiveConstraintsLocked(); 2733 } 2734 } 2735 unregisterDeviceIdleConstraintInternal(IDeviceIdleConstraint constraint)2736 private void unregisterDeviceIdleConstraintInternal(IDeviceIdleConstraint constraint) { 2737 synchronized (this) { 2738 // Artificially force the constraint to inactive to unblock anything waiting for it. 2739 onConstraintStateChangedLocked(constraint, /* active= */ false); 2740 2741 // Let the constraint know that we are not listening to it any more. 2742 setConstraintMonitoringLocked(constraint, /* monitoring= */ false); 2743 mConstraints.remove(constraint); 2744 } 2745 } 2746 2747 @GuardedBy("this") onConstraintStateChangedLocked(IDeviceIdleConstraint constraint, boolean active)2748 private void onConstraintStateChangedLocked(IDeviceIdleConstraint constraint, boolean active) { 2749 DeviceIdleConstraintTracker tracker = mConstraints.get(constraint); 2750 if (tracker == null) { 2751 Slog.e(TAG, "device-idle constraint " + constraint + " has not been registered."); 2752 return; 2753 } 2754 if (active != tracker.active && tracker.monitoring) { 2755 tracker.active = active; 2756 mNumBlockingConstraints += (tracker.active ? +1 : -1); 2757 if (mNumBlockingConstraints == 0) { 2758 if (mState == STATE_ACTIVE) { 2759 becomeInactiveIfAppropriateLocked(); 2760 } else if (mNextAlarmTime == 0 || mNextAlarmTime < SystemClock.elapsedRealtime()) { 2761 stepIdleStateLocked("s:" + tracker.name); 2762 } 2763 } 2764 } 2765 } 2766 2767 @GuardedBy("this") setConstraintMonitoringLocked(IDeviceIdleConstraint constraint, boolean monitor)2768 private void setConstraintMonitoringLocked(IDeviceIdleConstraint constraint, boolean monitor) { 2769 DeviceIdleConstraintTracker tracker = mConstraints.get(constraint); 2770 if (tracker.monitoring != monitor) { 2771 tracker.monitoring = monitor; 2772 updateActiveConstraintsLocked(); 2773 // We send the callback on a separate thread instead of just relying on oneway as 2774 // the client could be in the system server with us and cause re-entry problems. 2775 mHandler.obtainMessage(MSG_SEND_CONSTRAINT_MONITORING, 2776 /* monitoring= */ monitor ? 1 : 0, 2777 /* <not used>= */ -1, 2778 /* constraint= */ constraint).sendToTarget(); 2779 } 2780 } 2781 2782 @GuardedBy("this") updateActiveConstraintsLocked()2783 private void updateActiveConstraintsLocked() { 2784 mNumBlockingConstraints = 0; 2785 for (int i = 0; i < mConstraints.size(); i++) { 2786 final IDeviceIdleConstraint constraint = mConstraints.keyAt(i); 2787 final DeviceIdleConstraintTracker tracker = mConstraints.valueAt(i); 2788 final boolean monitoring = (tracker.minState == mState); 2789 if (monitoring != tracker.monitoring) { 2790 setConstraintMonitoringLocked(constraint, monitoring); 2791 tracker.active = monitoring; 2792 } 2793 if (tracker.monitoring && tracker.active) { 2794 mNumBlockingConstraints++; 2795 } 2796 } 2797 } 2798 addPowerSaveWhitelistAppsInternal(List<String> pkgNames)2799 private int addPowerSaveWhitelistAppsInternal(List<String> pkgNames) { 2800 int numAdded = 0; 2801 int numErrors = 0; 2802 synchronized (this) { 2803 for (int i = pkgNames.size() - 1; i >= 0; --i) { 2804 final String name = pkgNames.get(i); 2805 if (name == null) { 2806 numErrors++; 2807 continue; 2808 } 2809 try { 2810 ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name, 2811 PackageManager.MATCH_ANY_USER); 2812 if (mPowerSaveWhitelistUserApps.put(name, UserHandle.getAppId(ai.uid)) 2813 == null) { 2814 numAdded++; 2815 Counter.logIncrement(USER_ALLOWLIST_ADDITION_METRIC_ID); 2816 } 2817 } catch (PackageManager.NameNotFoundException e) { 2818 Slog.e(TAG, "Tried to add unknown package to power save whitelist: " + name); 2819 numErrors++; 2820 } 2821 } 2822 if (numAdded > 0) { 2823 reportPowerSaveWhitelistChangedLocked(); 2824 updateWhitelistAppIdsLocked(); 2825 writeConfigFileLocked(); 2826 } 2827 } 2828 return pkgNames.size() - numErrors; 2829 } 2830 removePowerSaveWhitelistAppInternal(String name)2831 public boolean removePowerSaveWhitelistAppInternal(String name) { 2832 synchronized (this) { 2833 if (mPowerSaveWhitelistUserApps.remove(name) != null) { 2834 reportPowerSaveWhitelistChangedLocked(); 2835 updateWhitelistAppIdsLocked(); 2836 writeConfigFileLocked(); 2837 Counter.logIncrement(USER_ALLOWLIST_REMOVAL_METRIC_ID); 2838 return true; 2839 } 2840 } 2841 return false; 2842 } 2843 getPowerSaveWhitelistAppInternal(String name)2844 public boolean getPowerSaveWhitelistAppInternal(String name) { 2845 synchronized (this) { 2846 return mPowerSaveWhitelistUserApps.containsKey(name); 2847 } 2848 } 2849 resetSystemPowerWhitelistInternal()2850 void resetSystemPowerWhitelistInternal() { 2851 synchronized (this) { 2852 mPowerSaveWhitelistApps.putAll(mRemovedFromSystemWhitelistApps); 2853 mRemovedFromSystemWhitelistApps.clear(); 2854 reportPowerSaveWhitelistChangedLocked(); 2855 updateWhitelistAppIdsLocked(); 2856 writeConfigFileLocked(); 2857 } 2858 } 2859 restoreSystemPowerWhitelistAppInternal(String name)2860 public boolean restoreSystemPowerWhitelistAppInternal(String name) { 2861 synchronized (this) { 2862 if (!mRemovedFromSystemWhitelistApps.containsKey(name)) { 2863 return false; 2864 } 2865 mPowerSaveWhitelistApps.put(name, mRemovedFromSystemWhitelistApps.remove(name)); 2866 reportPowerSaveWhitelistChangedLocked(); 2867 updateWhitelistAppIdsLocked(); 2868 writeConfigFileLocked(); 2869 return true; 2870 } 2871 } 2872 removeSystemPowerWhitelistAppInternal(String name)2873 public boolean removeSystemPowerWhitelistAppInternal(String name) { 2874 synchronized (this) { 2875 if (!mPowerSaveWhitelistApps.containsKey(name)) { 2876 return false; 2877 } 2878 mRemovedFromSystemWhitelistApps.put(name, mPowerSaveWhitelistApps.remove(name)); 2879 reportPowerSaveWhitelistChangedLocked(); 2880 updateWhitelistAppIdsLocked(); 2881 writeConfigFileLocked(); 2882 return true; 2883 } 2884 } 2885 addPowerSaveWhitelistExceptIdleInternal(String name)2886 public boolean addPowerSaveWhitelistExceptIdleInternal(String name) { 2887 synchronized (this) { 2888 try { 2889 final ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name, 2890 PackageManager.MATCH_ANY_USER); 2891 if (mPowerSaveWhitelistAppsExceptIdle.put(name, UserHandle.getAppId(ai.uid)) 2892 == null) { 2893 mPowerSaveWhitelistUserAppsExceptIdle.add(name); 2894 reportPowerSaveWhitelistChangedLocked(); 2895 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray( 2896 mPowerSaveWhitelistAppsExceptIdle, mPowerSaveWhitelistUserApps, 2897 mPowerSaveWhitelistExceptIdleAppIds); 2898 2899 passWhiteListsToForceAppStandbyTrackerLocked(); 2900 } 2901 return true; 2902 } catch (PackageManager.NameNotFoundException e) { 2903 return false; 2904 } 2905 } 2906 } 2907 resetPowerSaveWhitelistExceptIdleInternal()2908 public void resetPowerSaveWhitelistExceptIdleInternal() { 2909 synchronized (this) { 2910 if (mPowerSaveWhitelistAppsExceptIdle.removeAll( 2911 mPowerSaveWhitelistUserAppsExceptIdle)) { 2912 reportPowerSaveWhitelistChangedLocked(); 2913 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray( 2914 mPowerSaveWhitelistAppsExceptIdle, mPowerSaveWhitelistUserApps, 2915 mPowerSaveWhitelistExceptIdleAppIds); 2916 mPowerSaveWhitelistUserAppsExceptIdle.clear(); 2917 2918 passWhiteListsToForceAppStandbyTrackerLocked(); 2919 } 2920 } 2921 } 2922 getPowerSaveWhitelistExceptIdleInternal(String name)2923 public boolean getPowerSaveWhitelistExceptIdleInternal(String name) { 2924 synchronized (this) { 2925 return mPowerSaveWhitelistAppsExceptIdle.containsKey(name); 2926 } 2927 } 2928 getSystemPowerWhitelistExceptIdleInternal(final int callingUid, final int callingUserId)2929 private String[] getSystemPowerWhitelistExceptIdleInternal(final int callingUid, 2930 final int callingUserId) { 2931 final String[] apps; 2932 synchronized (this) { 2933 int size = mPowerSaveWhitelistAppsExceptIdle.size(); 2934 apps = new String[size]; 2935 for (int i = 0; i < size; i++) { 2936 apps[i] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i); 2937 } 2938 } 2939 return ArrayUtils.filter(apps, String[]::new, 2940 (pkg) -> !mPackageManagerInternal.filterAppAccess(pkg, callingUid, callingUserId)); 2941 } 2942 getSystemPowerWhitelistInternal(final int callingUid, final int callingUserId)2943 private String[] getSystemPowerWhitelistInternal(final int callingUid, 2944 final int callingUserId) { 2945 final String[] apps; 2946 synchronized (this) { 2947 int size = mPowerSaveWhitelistApps.size(); 2948 apps = new String[size]; 2949 for (int i = 0; i < size; i++) { 2950 apps[i] = mPowerSaveWhitelistApps.keyAt(i); 2951 } 2952 } 2953 return ArrayUtils.filter(apps, String[]::new, 2954 (pkg) -> !mPackageManagerInternal.filterAppAccess(pkg, callingUid, callingUserId)); 2955 } 2956 getRemovedSystemPowerWhitelistAppsInternal(final int callingUid, final int callingUserId)2957 private String[] getRemovedSystemPowerWhitelistAppsInternal(final int callingUid, 2958 final int callingUserId) { 2959 final String[] apps; 2960 synchronized (this) { 2961 int size = mRemovedFromSystemWhitelistApps.size(); 2962 apps = new String[size]; 2963 for (int i = 0; i < size; i++) { 2964 apps[i] = mRemovedFromSystemWhitelistApps.keyAt(i); 2965 } 2966 } 2967 return ArrayUtils.filter(apps, String[]::new, 2968 (pkg) -> !mPackageManagerInternal.filterAppAccess(pkg, callingUid, callingUserId)); 2969 } 2970 getUserPowerWhitelistInternal(final int callingUid, final int callingUserId)2971 private String[] getUserPowerWhitelistInternal(final int callingUid, final int callingUserId) { 2972 final String[] apps; 2973 synchronized (this) { 2974 int size = mPowerSaveWhitelistUserApps.size(); 2975 apps = new String[size]; 2976 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) { 2977 apps[i] = mPowerSaveWhitelistUserApps.keyAt(i); 2978 } 2979 } 2980 return ArrayUtils.filter(apps, String[]::new, 2981 (pkg) -> !mPackageManagerInternal.filterAppAccess(pkg, callingUid, callingUserId)); 2982 } 2983 getFullPowerWhitelistExceptIdleInternal(final int callingUid, final int callingUserId)2984 private String[] getFullPowerWhitelistExceptIdleInternal(final int callingUid, 2985 final int callingUserId) { 2986 final String[] apps; 2987 synchronized (this) { 2988 int size = 2989 mPowerSaveWhitelistAppsExceptIdle.size() + mPowerSaveWhitelistUserApps.size(); 2990 apps = new String[size]; 2991 int cur = 0; 2992 for (int i = 0; i < mPowerSaveWhitelistAppsExceptIdle.size(); i++) { 2993 apps[cur] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i); 2994 cur++; 2995 } 2996 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) { 2997 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i); 2998 cur++; 2999 } 3000 } 3001 return ArrayUtils.filter(apps, String[]::new, 3002 (pkg) -> !mPackageManagerInternal.filterAppAccess(pkg, callingUid, callingUserId)); 3003 } 3004 getFullPowerWhitelistInternal(final int callingUid, final int callingUserId)3005 private String[] getFullPowerWhitelistInternal(final int callingUid, final int callingUserId) { 3006 final String[] apps; 3007 synchronized (this) { 3008 int size = mPowerSaveWhitelistApps.size() + mPowerSaveWhitelistUserApps.size(); 3009 apps = new String[size]; 3010 int cur = 0; 3011 for (int i = 0; i < mPowerSaveWhitelistApps.size(); i++) { 3012 apps[cur] = mPowerSaveWhitelistApps.keyAt(i); 3013 cur++; 3014 } 3015 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) { 3016 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i); 3017 cur++; 3018 } 3019 } 3020 return ArrayUtils.filter(apps, String[]::new, 3021 (pkg) -> !mPackageManagerInternal.filterAppAccess(pkg, callingUid, callingUserId)); 3022 } 3023 isPowerSaveWhitelistExceptIdleAppInternal(String packageName)3024 public boolean isPowerSaveWhitelistExceptIdleAppInternal(String packageName) { 3025 synchronized (this) { 3026 return mPowerSaveWhitelistAppsExceptIdle.containsKey(packageName) 3027 || mPowerSaveWhitelistUserApps.containsKey(packageName); 3028 } 3029 } 3030 isPowerSaveWhitelistAppInternal(String packageName)3031 public boolean isPowerSaveWhitelistAppInternal(String packageName) { 3032 synchronized (this) { 3033 return mPowerSaveWhitelistApps.containsKey(packageName) 3034 || mPowerSaveWhitelistUserApps.containsKey(packageName); 3035 } 3036 } 3037 getAppIdWhitelistExceptIdleInternal()3038 public int[] getAppIdWhitelistExceptIdleInternal() { 3039 synchronized (this) { 3040 return mPowerSaveWhitelistExceptIdleAppIdArray; 3041 } 3042 } 3043 getAppIdWhitelistInternal()3044 public int[] getAppIdWhitelistInternal() { 3045 synchronized (this) { 3046 return mPowerSaveWhitelistAllAppIdArray; 3047 } 3048 } 3049 getAppIdUserWhitelistInternal()3050 public int[] getAppIdUserWhitelistInternal() { 3051 synchronized (this) { 3052 return mPowerSaveWhitelistUserAppIdArray; 3053 } 3054 } 3055 getAppIdTempWhitelistInternal()3056 public int[] getAppIdTempWhitelistInternal() { 3057 synchronized (this) { 3058 return mTempWhitelistAppIdArray; 3059 } 3060 } 3061 getTempAllowListType(@easonCode int reasonCode, @TempAllowListType int defaultType)3062 private @TempAllowListType int getTempAllowListType(@ReasonCode int reasonCode, 3063 @TempAllowListType int defaultType) { 3064 switch (reasonCode) { 3065 case PowerExemptionManager.REASON_PUSH_MESSAGING_OVER_QUOTA: 3066 return mLocalActivityManager.getPushMessagingOverQuotaBehavior(); 3067 case PowerExemptionManager.REASON_DENIED: 3068 return TEMPORARY_ALLOW_LIST_TYPE_NONE; 3069 default: 3070 return defaultType; 3071 } 3072 } 3073 addPowerSaveTempAllowlistAppChecked(String packageName, long duration, int userId, @ReasonCode int reasonCode, @Nullable String reason)3074 void addPowerSaveTempAllowlistAppChecked(String packageName, long duration, 3075 int userId, @ReasonCode int reasonCode, @Nullable String reason) 3076 throws RemoteException { 3077 getContext().enforceCallingOrSelfPermission( 3078 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, 3079 "No permission to change device idle whitelist"); 3080 final int callingUid = Binder.getCallingUid(); 3081 userId = ActivityManager.getService().handleIncomingUser( 3082 Binder.getCallingPid(), 3083 callingUid, 3084 userId, 3085 /*allowAll=*/ false, 3086 /*requireFull=*/ false, 3087 "addPowerSaveTempWhitelistApp", null); 3088 final long token = Binder.clearCallingIdentity(); 3089 try { 3090 @TempAllowListType int type = getTempAllowListType(reasonCode, 3091 TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED); 3092 if (type != TEMPORARY_ALLOW_LIST_TYPE_NONE) { 3093 addPowerSaveTempAllowlistAppInternal(callingUid, 3094 packageName, duration, type, userId, true, reasonCode, reason); 3095 } 3096 } finally { 3097 Binder.restoreCallingIdentity(token); 3098 } 3099 } 3100 removePowerSaveTempAllowlistAppChecked(String packageName, int userId)3101 void removePowerSaveTempAllowlistAppChecked(String packageName, int userId) 3102 throws RemoteException { 3103 getContext().enforceCallingOrSelfPermission( 3104 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, 3105 "No permission to change device idle whitelist"); 3106 final int callingUid = Binder.getCallingUid(); 3107 userId = ActivityManager.getService().handleIncomingUser( 3108 Binder.getCallingPid(), 3109 callingUid, 3110 userId, 3111 /*allowAll=*/ false, 3112 /*requireFull=*/ false, 3113 "removePowerSaveTempWhitelistApp", null); 3114 final long token = Binder.clearCallingIdentity(); 3115 try { 3116 removePowerSaveTempAllowlistAppInternal(packageName, userId); 3117 } finally { 3118 Binder.restoreCallingIdentity(token); 3119 } 3120 } 3121 3122 /** 3123 * Adds an app to the temporary whitelist and resets the endTime for granting the 3124 * app an exemption to access network and acquire wakelocks. 3125 */ addPowerSaveTempAllowlistAppInternal(int callingUid, String packageName, long durationMs, @TempAllowListType int tempAllowListType, int userId, boolean sync, @ReasonCode int reasonCode, @Nullable String reason)3126 void addPowerSaveTempAllowlistAppInternal(int callingUid, String packageName, 3127 long durationMs, @TempAllowListType int tempAllowListType, int userId, boolean sync, 3128 @ReasonCode int reasonCode, @Nullable String reason) { 3129 try { 3130 int uid = getContext().getPackageManager().getPackageUidAsUser(packageName, userId); 3131 addPowerSaveTempWhitelistAppDirectInternal(callingUid, uid, durationMs, 3132 tempAllowListType, sync, reasonCode, reason); 3133 } catch (NameNotFoundException e) { 3134 } 3135 } 3136 3137 /** 3138 * Adds an app to the temporary whitelist and resets the endTime for granting the 3139 * app an exemption to access network and acquire wakelocks. 3140 */ addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int uid, long duration, @TempAllowListType int tempAllowListType, boolean sync, @ReasonCode int reasonCode, @Nullable String reason)3141 void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int uid, 3142 long duration, @TempAllowListType int tempAllowListType, boolean sync, 3143 @ReasonCode int reasonCode, @Nullable String reason) { 3144 final long timeNow = SystemClock.elapsedRealtime(); 3145 boolean informWhitelistChanged = false; 3146 int appId = UserHandle.getAppId(uid); 3147 synchronized (this) { 3148 duration = Math.min(duration, mConstants.MAX_TEMP_APP_ALLOWLIST_DURATION_MS); 3149 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId); 3150 final boolean newEntry = entry == null; 3151 // Set the new end time 3152 if (newEntry) { 3153 entry = new Pair<>(new MutableLong(0), reason); 3154 mTempWhitelistAppIdEndTimes.put(appId, entry); 3155 } 3156 entry.first.value = timeNow + duration; 3157 if (DEBUG) { 3158 Slog.d(TAG, "Adding AppId " + appId + " to temp whitelist. New entry: " + newEntry); 3159 } 3160 if (newEntry) { 3161 // No pending timeout for the app id, post a delayed message 3162 try { 3163 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_START, 3164 reason, uid); 3165 } catch (RemoteException e) { 3166 } 3167 postTempActiveTimeoutMessage(uid, duration); 3168 updateTempWhitelistAppIdsLocked(uid, true, duration, tempAllowListType, 3169 reasonCode, reason, callingUid); 3170 if (sync) { 3171 informWhitelistChanged = true; 3172 } else { 3173 // NPMS needs to update its state synchronously in certain situations so we 3174 // can't have it use the TempAllowlistChangeListener path right now. 3175 // TODO: see if there's a way to simplify/consolidate 3176 mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_ADDED_TO_NPMS, appId, 3177 reasonCode, reason).sendToTarget(); 3178 } 3179 reportTempWhitelistChangedLocked(uid, true); 3180 } else { 3181 // The uid is already temp allowlisted, only need to update AMS for temp allowlist 3182 // duration. 3183 if (mLocalActivityManager != null) { 3184 mLocalActivityManager.updateDeviceIdleTempAllowlist(null, uid, true, 3185 duration, tempAllowListType, reasonCode, reason, callingUid); 3186 } 3187 } 3188 } 3189 if (informWhitelistChanged) { 3190 mNetworkPolicyManagerInternal.onTempPowerSaveWhitelistChange(appId, true, 3191 reasonCode, reason); 3192 } 3193 } 3194 3195 /** 3196 * Removes an app from the temporary whitelist and notifies the observers. 3197 */ removePowerSaveTempAllowlistAppInternal(String packageName, int userId)3198 private void removePowerSaveTempAllowlistAppInternal(String packageName, int userId) { 3199 try { 3200 final int uid = getContext().getPackageManager().getPackageUidAsUser( 3201 packageName, userId); 3202 removePowerSaveTempWhitelistAppDirectInternal(uid); 3203 } catch (NameNotFoundException e) { 3204 } 3205 } 3206 removePowerSaveTempWhitelistAppDirectInternal(int uid)3207 private void removePowerSaveTempWhitelistAppDirectInternal(int uid) { 3208 final int appId = UserHandle.getAppId(uid); 3209 synchronized (this) { 3210 final int idx = mTempWhitelistAppIdEndTimes.indexOfKey(appId); 3211 if (idx < 0) { 3212 // Nothing else to do 3213 return; 3214 } 3215 final String reason = mTempWhitelistAppIdEndTimes.valueAt(idx).second; 3216 mTempWhitelistAppIdEndTimes.removeAt(idx); 3217 onAppRemovedFromTempWhitelistLocked(uid, reason); 3218 } 3219 } 3220 postTempActiveTimeoutMessage(int uid, long delay)3221 private void postTempActiveTimeoutMessage(int uid, long delay) { 3222 if (DEBUG) { 3223 Slog.d(TAG, "postTempActiveTimeoutMessage: uid=" + uid + ", delay=" + delay); 3224 } 3225 mHandler.sendMessageDelayed( 3226 mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, uid, 0), delay); 3227 } 3228 checkTempAppWhitelistTimeout(int uid)3229 void checkTempAppWhitelistTimeout(int uid) { 3230 final long timeNow = SystemClock.elapsedRealtime(); 3231 final int appId = UserHandle.getAppId(uid); 3232 if (DEBUG) { 3233 Slog.d(TAG, "checkTempAppWhitelistTimeout: uid=" + uid + ", timeNow=" + timeNow); 3234 } 3235 synchronized (this) { 3236 Pair<MutableLong, String> entry = 3237 mTempWhitelistAppIdEndTimes.get(appId); 3238 if (entry == null) { 3239 // Nothing to do 3240 return; 3241 } 3242 if (timeNow >= entry.first.value) { 3243 mTempWhitelistAppIdEndTimes.delete(appId); 3244 onAppRemovedFromTempWhitelistLocked(uid, entry.second); 3245 } else { 3246 // Need more time 3247 if (DEBUG) { 3248 Slog.d(TAG, "Time to remove uid " + uid + ": " + entry.first.value); 3249 } 3250 postTempActiveTimeoutMessage(uid, entry.first.value - timeNow); 3251 } 3252 } 3253 } 3254 3255 @GuardedBy("this") onAppRemovedFromTempWhitelistLocked(int uid, @Nullable String reason)3256 private void onAppRemovedFromTempWhitelistLocked(int uid, @Nullable String reason) { 3257 if (DEBUG) { 3258 Slog.d(TAG, "Removing uid " + uid + " from temp whitelist"); 3259 } 3260 final int appId = UserHandle.getAppId(uid); 3261 updateTempWhitelistAppIdsLocked(uid, false, 0, 0, REASON_UNKNOWN, 3262 reason, INVALID_UID); 3263 mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_REMOVED_TO_NPMS, appId, 3264 /* unused= */ 0).sendToTarget(); 3265 reportTempWhitelistChangedLocked(uid, false); 3266 try { 3267 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH, 3268 reason, appId); 3269 } catch (RemoteException e) { 3270 } 3271 } 3272 exitIdleInternal(String reason)3273 public void exitIdleInternal(String reason) { 3274 synchronized (this) { 3275 mActiveReason = ACTIVE_REASON_FROM_BINDER_CALL; 3276 becomeActiveLocked(reason, Binder.getCallingUid()); 3277 } 3278 } 3279 3280 @VisibleForTesting isNetworkConnected()3281 boolean isNetworkConnected() { 3282 synchronized (this) { 3283 return mNetworkConnected; 3284 } 3285 } 3286 updateConnectivityState(Intent connIntent)3287 void updateConnectivityState(Intent connIntent) { 3288 ConnectivityManager cm; 3289 synchronized (this) { 3290 cm = mInjector.getConnectivityManager(); 3291 } 3292 if (cm == null) { 3293 return; 3294 } 3295 // Note: can't call out to ConnectivityService with our lock held. 3296 NetworkInfo ni = cm.getActiveNetworkInfo(); 3297 synchronized (this) { 3298 boolean conn; 3299 if (ni == null) { 3300 conn = false; 3301 } else { 3302 if (connIntent == null) { 3303 conn = ni.isConnected(); 3304 } else { 3305 final int networkType = 3306 connIntent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 3307 ConnectivityManager.TYPE_NONE); 3308 if (ni.getType() != networkType) { 3309 return; 3310 } 3311 conn = !connIntent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, 3312 false); 3313 } 3314 } 3315 if (conn != mNetworkConnected) { 3316 mNetworkConnected = conn; 3317 if (conn && mLightState == LIGHT_STATE_WAITING_FOR_NETWORK) { 3318 stepLightIdleStateLocked("network"); 3319 } 3320 } 3321 } 3322 } 3323 3324 @VisibleForTesting isScreenOn()3325 boolean isScreenOn() { 3326 synchronized (this) { 3327 return mScreenOn; 3328 } 3329 } 3330 3331 @GuardedBy("this") updateInteractivityLocked()3332 void updateInteractivityLocked() { 3333 // The interactivity state from the power manager tells us whether the display is 3334 // in a state that we need to keep things running so they will update at a normal 3335 // frequency. 3336 boolean screenOn = mPowerManager.isInteractive(); 3337 if (DEBUG) Slog.d(TAG, "updateInteractivityLocked: screenOn=" + screenOn); 3338 if (!screenOn && mScreenOn) { 3339 mScreenOn = false; 3340 if (!mForceIdle) { 3341 becomeInactiveIfAppropriateLocked(); 3342 } 3343 } else if (screenOn) { 3344 mScreenOn = true; 3345 if (!mForceIdle && (!mScreenLocked || !mConstants.WAIT_FOR_UNLOCK)) { 3346 mActiveReason = ACTIVE_REASON_SCREEN; 3347 becomeActiveLocked("screen", Process.myUid()); 3348 } 3349 } 3350 } 3351 3352 @VisibleForTesting isCharging()3353 boolean isCharging() { 3354 synchronized (this) { 3355 return mCharging; 3356 } 3357 } 3358 3359 @GuardedBy("this") updateChargingLocked(boolean charging)3360 void updateChargingLocked(boolean charging) { 3361 if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging); 3362 if (!charging && mCharging) { 3363 mCharging = false; 3364 if (!mForceIdle) { 3365 becomeInactiveIfAppropriateLocked(); 3366 } 3367 } else if (charging) { 3368 mCharging = charging; 3369 if (!mForceIdle) { 3370 mActiveReason = ACTIVE_REASON_CHARGING; 3371 becomeActiveLocked("charging", Process.myUid()); 3372 } 3373 } 3374 } 3375 3376 @VisibleForTesting isQuickDozeEnabled()3377 boolean isQuickDozeEnabled() { 3378 synchronized (this) { 3379 return mQuickDozeActivated; 3380 } 3381 } 3382 3383 /** Updates the quick doze flag and enters deep doze if appropriate. */ 3384 @VisibleForTesting 3385 @GuardedBy("this") updateQuickDozeFlagLocked(boolean enabled)3386 void updateQuickDozeFlagLocked(boolean enabled) { 3387 if (DEBUG) Slog.i(TAG, "updateQuickDozeFlagLocked: enabled=" + enabled); 3388 mQuickDozeActivated = enabled; 3389 mQuickDozeActivatedWhileIdling = 3390 mQuickDozeActivated && (mState == STATE_IDLE || mState == STATE_IDLE_MAINTENANCE); 3391 if (enabled) { 3392 // If Quick Doze is enabled, see if we should go straight into it. 3393 becomeInactiveIfAppropriateLocked(); 3394 } 3395 // Going from Deep Doze to Light Idle (if quick doze becomes disabled) is tricky and 3396 // probably not worth the overhead, so leave in deep doze if that's the case until the 3397 // next natural time to come out of it. 3398 } 3399 3400 3401 /** Returns true if the screen is locked. */ 3402 @VisibleForTesting isKeyguardShowing()3403 boolean isKeyguardShowing() { 3404 synchronized (this) { 3405 return mScreenLocked; 3406 } 3407 } 3408 3409 @VisibleForTesting 3410 @GuardedBy("this") keyguardShowingLocked(boolean showing)3411 void keyguardShowingLocked(boolean showing) { 3412 if (DEBUG) Slog.i(TAG, "keyguardShowing=" + showing); 3413 if (mScreenLocked != showing) { 3414 mScreenLocked = showing; 3415 if (mScreenOn && !mForceIdle && !mScreenLocked) { 3416 mActiveReason = ACTIVE_REASON_UNLOCKED; 3417 becomeActiveLocked("unlocked", Process.myUid()); 3418 } 3419 } 3420 } 3421 3422 @VisibleForTesting 3423 @GuardedBy("this") scheduleReportActiveLocked(String activeReason, int activeUid)3424 void scheduleReportActiveLocked(String activeReason, int activeUid) { 3425 Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid, 0, activeReason); 3426 mHandler.sendMessage(msg); 3427 } 3428 3429 @GuardedBy("this") becomeActiveLocked(String activeReason, int activeUid)3430 void becomeActiveLocked(String activeReason, int activeUid) { 3431 becomeActiveLocked(activeReason, activeUid, mConstants.INACTIVE_TIMEOUT, true); 3432 } 3433 3434 @GuardedBy("this") becomeActiveLocked(String activeReason, int activeUid, long newInactiveTimeout, boolean changeLightIdle)3435 private void becomeActiveLocked(String activeReason, int activeUid, 3436 long newInactiveTimeout, boolean changeLightIdle) { 3437 if (DEBUG) { 3438 Slog.i(TAG, "becomeActiveLocked, reason=" + activeReason 3439 + ", changeLightIdle=" + changeLightIdle); 3440 } 3441 if (mState != STATE_ACTIVE || mLightState != STATE_ACTIVE) { 3442 moveToStateLocked(STATE_ACTIVE, activeReason); 3443 mInactiveTimeout = newInactiveTimeout; 3444 resetIdleManagementLocked(); 3445 // Don't reset maintenance window start time if we're in a light idle maintenance window 3446 // because its used in the light idle budget calculation. 3447 if (mLightState != LIGHT_STATE_IDLE_MAINTENANCE) { 3448 mMaintenanceStartTime = 0; 3449 } 3450 3451 if (changeLightIdle) { 3452 moveToLightStateLocked(LIGHT_STATE_ACTIVE, activeReason); 3453 resetLightIdleManagementLocked(); 3454 // Only report active if light is also ACTIVE. 3455 scheduleReportActiveLocked(activeReason, activeUid); 3456 addEvent(EVENT_NORMAL, activeReason); 3457 } 3458 } 3459 } 3460 3461 /** Must only be used in tests. */ 3462 @VisibleForTesting setDeepEnabledForTest(boolean enabled)3463 void setDeepEnabledForTest(boolean enabled) { 3464 synchronized (this) { 3465 mDeepEnabled = enabled; 3466 } 3467 } 3468 3469 /** Must only be used in tests. */ 3470 @VisibleForTesting setLightEnabledForTest(boolean enabled)3471 void setLightEnabledForTest(boolean enabled) { 3472 synchronized (this) { 3473 mLightEnabled = enabled; 3474 } 3475 } 3476 3477 /** Sanity check to make sure DeviceIdleController and AlarmManager are on the same page. */ 3478 @GuardedBy("this") verifyAlarmStateLocked()3479 private void verifyAlarmStateLocked() { 3480 if (mState == STATE_ACTIVE && mNextAlarmTime != 0) { 3481 Slog.wtf(TAG, "mState=ACTIVE but mNextAlarmTime=" + mNextAlarmTime); 3482 } 3483 if (mState != STATE_IDLE && mLocalAlarmManager.isIdling()) { 3484 Slog.wtf(TAG, "mState=" + stateToString(mState) + " but AlarmManager is idling"); 3485 } 3486 if (mState == STATE_IDLE && !mLocalAlarmManager.isIdling()) { 3487 Slog.wtf(TAG, "mState=IDLE but AlarmManager is not idling"); 3488 } 3489 if (mLightState == LIGHT_STATE_ACTIVE && mNextLightAlarmTime != 0) { 3490 Slog.wtf(TAG, "mLightState=ACTIVE but mNextLightAlarmTime is " 3491 + TimeUtils.formatDuration(mNextLightAlarmTime - SystemClock.elapsedRealtime()) 3492 + " from now"); 3493 } 3494 } 3495 3496 @GuardedBy("this") becomeInactiveIfAppropriateLocked()3497 void becomeInactiveIfAppropriateLocked() { 3498 verifyAlarmStateLocked(); 3499 3500 final boolean isScreenBlockingInactive = 3501 mScreenOn && (!mConstants.WAIT_FOR_UNLOCK || !mScreenLocked); 3502 final boolean isEmergencyCallActive = mEmergencyCallListener.isEmergencyCallActive(); 3503 if (DEBUG) { 3504 Slog.d(TAG, "becomeInactiveIfAppropriateLocked():" 3505 + " isScreenBlockingInactive=" + isScreenBlockingInactive 3506 + " (mScreenOn=" + mScreenOn 3507 + ", WAIT_FOR_UNLOCK=" + mConstants.WAIT_FOR_UNLOCK 3508 + ", mScreenLocked=" + mScreenLocked + ")" 3509 + " mCharging=" + mCharging 3510 + " emergencyCall=" + isEmergencyCallActive 3511 + " mForceIdle=" + mForceIdle 3512 ); 3513 } 3514 if (!mForceIdle && (mCharging || isScreenBlockingInactive || isEmergencyCallActive)) { 3515 return; 3516 } 3517 // Become inactive and determine if we will ultimately go idle. 3518 if (mDeepEnabled) { 3519 if (mQuickDozeActivated) { 3520 if (mState == STATE_QUICK_DOZE_DELAY || mState == STATE_IDLE 3521 || mState == STATE_IDLE_MAINTENANCE) { 3522 // Already "idling". Don't want to restart the process. 3523 // mLightState can't be LIGHT_STATE_ACTIVE if mState is any of these 3 3524 // values, so returning here is safe. 3525 return; 3526 } 3527 moveToStateLocked(STATE_QUICK_DOZE_DELAY, "no activity"); 3528 // Make sure any motion sensing or locating is stopped. 3529 resetIdleManagementLocked(); 3530 if (isUpcomingAlarmClock()) { 3531 // If there's an upcoming AlarmClock alarm, we won't go into idle, so 3532 // setting a wakeup alarm before the upcoming alarm is futile. Set the quick 3533 // doze alarm to after the upcoming AlarmClock alarm. 3534 scheduleAlarmLocked( 3535 mAlarmManager.getNextWakeFromIdleTime() - mInjector.getElapsedRealtime() 3536 + mConstants.QUICK_DOZE_DELAY_TIMEOUT); 3537 } else { 3538 // Wait a small amount of time in case something (eg: background service from 3539 // recently closed app) needs to finish running. 3540 scheduleAlarmLocked(mConstants.QUICK_DOZE_DELAY_TIMEOUT); 3541 } 3542 } else if (mState == STATE_ACTIVE) { 3543 moveToStateLocked(STATE_INACTIVE, "no activity"); 3544 resetIdleManagementLocked(); 3545 long delay = mInactiveTimeout; 3546 if (shouldUseIdleTimeoutFactorLocked()) { 3547 delay = (long) (mPreIdleFactor * delay); 3548 } 3549 if (isUpcomingAlarmClock()) { 3550 // If there's an upcoming AlarmClock alarm, we won't go into idle, so 3551 // setting a wakeup alarm before the upcoming alarm is futile. Set the idle 3552 // alarm to after the upcoming AlarmClock alarm. 3553 scheduleAlarmLocked( 3554 mAlarmManager.getNextWakeFromIdleTime() - mInjector.getElapsedRealtime() 3555 + delay); 3556 } else { 3557 scheduleAlarmLocked(delay); 3558 } 3559 } 3560 } 3561 if (mLightState == LIGHT_STATE_ACTIVE && mLightEnabled) { 3562 moveToLightStateLocked(LIGHT_STATE_INACTIVE, "no activity"); 3563 resetLightIdleManagementLocked(); 3564 scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT, 3565 mConstants.FLEX_TIME_SHORT, true); 3566 } 3567 } 3568 3569 @GuardedBy("this") resetIdleManagementLocked()3570 private void resetIdleManagementLocked() { 3571 mNextIdlePendingDelay = 0; 3572 mNextIdleDelay = 0; 3573 mIdleStartTime = 0; 3574 mQuickDozeActivatedWhileIdling = false; 3575 cancelAlarmLocked(); 3576 cancelSensingTimeoutAlarmLocked(); 3577 cancelLocatingLocked(); 3578 maybeStopMonitoringMotionLocked(); 3579 mAnyMotionDetector.stop(); 3580 updateActiveConstraintsLocked(); 3581 } 3582 3583 @GuardedBy("this") resetLightIdleManagementLocked()3584 private void resetLightIdleManagementLocked() { 3585 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT; 3586 mMaintenanceStartTime = 0; 3587 mNextLightIdleDelayFlex = mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX; 3588 mCurLightIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET; 3589 cancelLightAlarmLocked(); 3590 } 3591 3592 @GuardedBy("this") exitForceIdleLocked()3593 void exitForceIdleLocked() { 3594 if (mForceIdle) { 3595 mForceIdle = false; 3596 if (mScreenOn || mCharging) { 3597 mActiveReason = ACTIVE_REASON_FORCED; 3598 becomeActiveLocked("exit-force", Process.myUid()); 3599 } 3600 } 3601 } 3602 3603 /** 3604 * Must only be used in tests. 3605 * 3606 * This sets the state value directly and thus doesn't trigger any behavioral changes. 3607 */ 3608 @VisibleForTesting setLightStateForTest(int lightState)3609 void setLightStateForTest(int lightState) { 3610 synchronized (this) { 3611 mLightState = lightState; 3612 } 3613 } 3614 3615 @VisibleForTesting getLightState()3616 int getLightState() { 3617 synchronized (this) { 3618 return mLightState; 3619 } 3620 } 3621 3622 @GuardedBy("this") 3623 @VisibleForTesting 3624 @SuppressLint("WakelockTimeout") stepLightIdleStateLocked(String reason)3625 void stepLightIdleStateLocked(String reason) { 3626 if (mLightState == LIGHT_STATE_ACTIVE || mLightState == LIGHT_STATE_OVERRIDE) { 3627 // If we are already in deep device idle mode, then 3628 // there is nothing left to do for light mode. 3629 return; 3630 } 3631 3632 if (DEBUG) { 3633 Slog.d(TAG, "stepLightIdleStateLocked: mLightState=" + lightStateToString(mLightState)); 3634 } 3635 EventLogTags.writeDeviceIdleLightStep(); 3636 3637 if (mEmergencyCallListener.isEmergencyCallActive()) { 3638 // The emergency call should have raised the state to ACTIVE and kept it there, 3639 // so this method shouldn't be called. Don't proceed further. 3640 Slog.wtf(TAG, "stepLightIdleStateLocked called when emergency call is active"); 3641 if (mLightState != LIGHT_STATE_ACTIVE) { 3642 mActiveReason = ACTIVE_REASON_EMERGENCY_CALL; 3643 becomeActiveLocked("emergency", Process.myUid()); 3644 } 3645 return; 3646 } 3647 3648 switch (mLightState) { 3649 case LIGHT_STATE_INACTIVE: 3650 mCurLightIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET; 3651 // Reset the upcoming idle delays. 3652 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT; 3653 mNextLightIdleDelayFlex = mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX; 3654 mMaintenanceStartTime = 0; 3655 // Fall through to immediately idle. 3656 case LIGHT_STATE_IDLE_MAINTENANCE: 3657 if (mMaintenanceStartTime != 0) { 3658 long duration = SystemClock.elapsedRealtime() - mMaintenanceStartTime; 3659 if (duration < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) { 3660 // We didn't use up all of our minimum budget; add this to the reserve. 3661 mCurLightIdleBudget += 3662 (mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET - duration); 3663 } else { 3664 // We used more than our minimum budget; this comes out of the reserve. 3665 mCurLightIdleBudget -= 3666 (duration - mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET); 3667 } 3668 } 3669 mMaintenanceStartTime = 0; 3670 scheduleLightAlarmLocked(mNextLightIdleDelay, mNextLightIdleDelayFlex, true); 3671 mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT, 3672 (long) (mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR)); 3673 mNextLightIdleDelayFlex = Math.min(mConstants.LIGHT_IDLE_TIMEOUT_MAX_FLEX, 3674 (long) (mNextLightIdleDelayFlex * mConstants.LIGHT_IDLE_FACTOR)); 3675 moveToLightStateLocked(LIGHT_STATE_IDLE, reason); 3676 addEvent(EVENT_LIGHT_IDLE, null); 3677 mGoingIdleWakeLock.acquire(); 3678 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON_LIGHT); 3679 break; 3680 case LIGHT_STATE_IDLE: 3681 case LIGHT_STATE_WAITING_FOR_NETWORK: 3682 if (mNetworkConnected || mLightState == LIGHT_STATE_WAITING_FOR_NETWORK) { 3683 // We have been idling long enough, now it is time to do some work. 3684 mActiveIdleOpCount = 1; 3685 mActiveIdleWakeLock.acquire(); 3686 mMaintenanceStartTime = SystemClock.elapsedRealtime(); 3687 if (mCurLightIdleBudget < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) { 3688 mCurLightIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET; 3689 } else if (mCurLightIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) { 3690 mCurLightIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET; 3691 } 3692 scheduleLightAlarmLocked(mCurLightIdleBudget, mConstants.FLEX_TIME_SHORT, true); 3693 moveToLightStateLocked(LIGHT_STATE_IDLE_MAINTENANCE, reason); 3694 addEvent(EVENT_LIGHT_MAINTENANCE, null); 3695 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF); 3696 } else { 3697 // We'd like to do maintenance, but currently don't have network 3698 // connectivity... let's try to wait until the network comes back. 3699 // We'll only wait for another full idle period, however, and then give up. 3700 scheduleLightAlarmLocked(mNextLightIdleDelay, 3701 mNextLightIdleDelayFlex / 2, true); 3702 moveToLightStateLocked(LIGHT_STATE_WAITING_FOR_NETWORK, reason); 3703 } 3704 break; 3705 } 3706 } 3707 3708 @VisibleForTesting getState()3709 int getState() { 3710 synchronized (this) { 3711 return mState; 3712 } 3713 } 3714 3715 /** 3716 * Returns true if there's an upcoming AlarmClock alarm that is soon enough to prevent the 3717 * device from going into idle. 3718 */ isUpcomingAlarmClock()3719 private boolean isUpcomingAlarmClock() { 3720 return mInjector.getElapsedRealtime() + mConstants.MIN_TIME_TO_ALARM 3721 >= mAlarmManager.getNextWakeFromIdleTime(); 3722 } 3723 3724 @VisibleForTesting 3725 @GuardedBy("this") stepIdleStateLocked(String reason)3726 void stepIdleStateLocked(String reason) { 3727 if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState); 3728 EventLogTags.writeDeviceIdleStep(); 3729 3730 if (mEmergencyCallListener.isEmergencyCallActive()) { 3731 // The emergency call should have raised the state to ACTIVE and kept it there, 3732 // so this method shouldn't be called. Don't proceed further. 3733 Slog.wtf(TAG, "stepIdleStateLocked called when emergency call is active"); 3734 if (mState != STATE_ACTIVE) { 3735 mActiveReason = ACTIVE_REASON_EMERGENCY_CALL; 3736 becomeActiveLocked("emergency", Process.myUid()); 3737 } 3738 return; 3739 } 3740 3741 if (isUpcomingAlarmClock()) { 3742 // Whoops, there is an upcoming alarm. We don't actually want to go idle. 3743 if (mState != STATE_ACTIVE) { 3744 mActiveReason = ACTIVE_REASON_ALARM; 3745 becomeActiveLocked("alarm", Process.myUid()); 3746 becomeInactiveIfAppropriateLocked(); 3747 } 3748 return; 3749 } 3750 3751 if (mNumBlockingConstraints != 0 && !mForceIdle) { 3752 // We have some constraints from other parts of the system server preventing 3753 // us from moving to the next state. 3754 if (DEBUG) { 3755 Slog.i(TAG, "Cannot step idle state. Blocked by: " + mConstraints.values().stream() 3756 .filter(x -> x.active) 3757 .map(x -> x.name) 3758 .collect(Collectors.joining(","))); 3759 } 3760 return; 3761 } 3762 3763 switch (mState) { 3764 case STATE_INACTIVE: 3765 // We have now been inactive long enough, it is time to start looking 3766 // for motion and sleep some more while doing so. 3767 startMonitoringMotionLocked(); 3768 long delay = mConstants.IDLE_AFTER_INACTIVE_TIMEOUT; 3769 if (shouldUseIdleTimeoutFactorLocked()) { 3770 delay = (long) (mPreIdleFactor * delay); 3771 } 3772 scheduleAlarmLocked(delay); 3773 moveToStateLocked(STATE_IDLE_PENDING, reason); 3774 break; 3775 case STATE_IDLE_PENDING: 3776 cancelLocatingLocked(); 3777 mLocated = false; 3778 mLastGenericLocation = null; 3779 mLastGpsLocation = null; 3780 moveToStateLocked(STATE_SENSING, reason); 3781 3782 // Wait for open constraints and an accelerometer reading before moving on. 3783 if (mUseMotionSensor && mAnyMotionDetector.hasSensor()) { 3784 scheduleSensingTimeoutAlarmLocked(mConstants.SENSING_TIMEOUT); 3785 mNotMoving = false; 3786 mAnyMotionDetector.checkForAnyMotion(); 3787 break; 3788 } else if (mNumBlockingConstraints != 0) { 3789 cancelAlarmLocked(); 3790 break; 3791 } 3792 3793 mNotMoving = true; 3794 // Otherwise, fall through and check this off the list of requirements. 3795 case STATE_SENSING: 3796 cancelSensingTimeoutAlarmLocked(); 3797 moveToStateLocked(STATE_LOCATING, reason); 3798 if (mIsLocationPrefetchEnabled) { 3799 scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT); 3800 LocationManager locationManager = mInjector.getLocationManager(); 3801 if (locationManager != null 3802 && locationManager.getProvider(LocationManager.FUSED_PROVIDER) 3803 != null) { 3804 locationManager.requestLocationUpdates(LocationManager.FUSED_PROVIDER, 3805 mLocationRequest, 3806 AppSchedulingModuleThread.getExecutor(), 3807 mGenericLocationListener); 3808 mLocating = true; 3809 } else { 3810 mHasFusedLocation = false; 3811 } 3812 if (locationManager != null 3813 && locationManager.getProvider(LocationManager.GPS_PROVIDER) != null) { 3814 mHasGps = true; 3815 locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3816 1000, 5, mGpsLocationListener, mHandler.getLooper()); 3817 mLocating = true; 3818 } else { 3819 mHasGps = false; 3820 } 3821 // If we have a location provider, we're all set, the listeners will move state 3822 // forward. 3823 if (mLocating) { 3824 break; 3825 } 3826 // Otherwise, we have to move from locating into idle maintenance. 3827 } else { 3828 mLocating = false; 3829 } 3830 3831 // We're not doing any locating work, so move on to the next state. 3832 case STATE_LOCATING: 3833 cancelAlarmLocked(); 3834 cancelLocatingLocked(); 3835 mAnyMotionDetector.stop(); 3836 3837 // Intentional fallthrough -- time to go into IDLE state. 3838 case STATE_QUICK_DOZE_DELAY: 3839 // Reset the upcoming idle delays. 3840 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT; 3841 mNextIdleDelay = mConstants.IDLE_TIMEOUT; 3842 3843 // Everything is in place to go into IDLE state. 3844 case STATE_IDLE_MAINTENANCE: 3845 moveToStateLocked(STATE_IDLE, reason); 3846 scheduleAlarmLocked(mNextIdleDelay); 3847 if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay + 3848 " ms."); 3849 mNextIdleDelay = (long)(mNextIdleDelay * mConstants.IDLE_FACTOR); 3850 if (DEBUG) Slog.d(TAG, "Setting mNextIdleDelay = " + mNextIdleDelay); 3851 mIdleStartTime = SystemClock.elapsedRealtime(); 3852 mNextIdleDelay = Math.min(mNextIdleDelay, mConstants.MAX_IDLE_TIMEOUT); 3853 if (mNextIdleDelay < mConstants.IDLE_TIMEOUT) { 3854 mNextIdleDelay = mConstants.IDLE_TIMEOUT; 3855 } 3856 if (mLightState != LIGHT_STATE_OVERRIDE) { 3857 moveToLightStateLocked(LIGHT_STATE_OVERRIDE, "deep"); 3858 cancelLightAlarmLocked(); 3859 } 3860 addEvent(EVENT_DEEP_IDLE, null); 3861 mGoingIdleWakeLock.acquire(); 3862 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON); 3863 break; 3864 case STATE_IDLE: 3865 // We have been idling long enough, now it is time to do some work. 3866 mActiveIdleOpCount = 1; 3867 mActiveIdleWakeLock.acquire(); 3868 moveToStateLocked(STATE_IDLE_MAINTENANCE, reason); 3869 scheduleAlarmLocked(mNextIdlePendingDelay); 3870 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE to STATE_IDLE_MAINTENANCE. " + 3871 "Next alarm in " + mNextIdlePendingDelay + " ms."); 3872 mMaintenanceStartTime = SystemClock.elapsedRealtime(); 3873 mNextIdlePendingDelay = Math.min(mConstants.MAX_IDLE_PENDING_TIMEOUT, 3874 (long)(mNextIdlePendingDelay * mConstants.IDLE_PENDING_FACTOR)); 3875 if (mNextIdlePendingDelay < mConstants.IDLE_PENDING_TIMEOUT) { 3876 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT; 3877 } 3878 addEvent(EVENT_DEEP_MAINTENANCE, null); 3879 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF); 3880 break; 3881 } 3882 } 3883 3884 @GuardedBy("this") moveToLightStateLocked(int state, String reason)3885 private void moveToLightStateLocked(int state, String reason) { 3886 if (DEBUG) { 3887 Slog.d(TAG, String.format("Moved from LIGHT_STATE_%s to LIGHT_STATE_%s.", 3888 lightStateToString(mLightState), lightStateToString(state))); 3889 } 3890 mLightState = state; 3891 EventLogTags.writeDeviceIdleLight(mLightState, reason); 3892 // This is currently how to set the current state in a trace. 3893 Trace.traceCounter(Trace.TRACE_TAG_SYSTEM_SERVER, "DozeLightState", state); 3894 } 3895 3896 @GuardedBy("this") moveToStateLocked(int state, String reason)3897 private void moveToStateLocked(int state, String reason) { 3898 if (DEBUG) { 3899 Slog.d(TAG, String.format("Moved from STATE_%s to STATE_%s.", 3900 stateToString(mState), stateToString(state))); 3901 } 3902 mState = state; 3903 EventLogTags.writeDeviceIdle(mState, reason); 3904 // This is currently how to set the current state in a trace. 3905 Trace.traceCounter(Trace.TRACE_TAG_SYSTEM_SERVER, "DozeDeepState", state); 3906 updateActiveConstraintsLocked(); 3907 } 3908 incActiveIdleOps()3909 void incActiveIdleOps() { 3910 synchronized (this) { 3911 mActiveIdleOpCount++; 3912 } 3913 } 3914 decActiveIdleOps()3915 void decActiveIdleOps() { 3916 synchronized (this) { 3917 mActiveIdleOpCount--; 3918 if (mActiveIdleOpCount <= 0) { 3919 exitMaintenanceEarlyIfNeededLocked(); 3920 mActiveIdleWakeLock.release(); 3921 } 3922 } 3923 } 3924 3925 /** Must only be used in tests. */ 3926 @VisibleForTesting setActiveIdleOpsForTest(int count)3927 void setActiveIdleOpsForTest(int count) { 3928 synchronized (this) { 3929 mActiveIdleOpCount = count; 3930 } 3931 } 3932 setJobsActive(boolean active)3933 void setJobsActive(boolean active) { 3934 synchronized (this) { 3935 mJobsActive = active; 3936 if (!active) { 3937 exitMaintenanceEarlyIfNeededLocked(); 3938 } 3939 } 3940 } 3941 setAlarmsActive(boolean active)3942 void setAlarmsActive(boolean active) { 3943 synchronized (this) { 3944 mAlarmsActive = active; 3945 if (!active) { 3946 exitMaintenanceEarlyIfNeededLocked(); 3947 } 3948 } 3949 } 3950 3951 @VisibleForTesting setPreIdleTimeoutMode(int mode)3952 int setPreIdleTimeoutMode(int mode) { 3953 return setPreIdleTimeoutFactor(getPreIdleTimeoutByMode(mode)); 3954 } 3955 3956 @VisibleForTesting getPreIdleTimeoutByMode(int mode)3957 float getPreIdleTimeoutByMode(int mode) { 3958 switch (mode) { 3959 case PowerManager.PRE_IDLE_TIMEOUT_MODE_LONG: { 3960 return mConstants.PRE_IDLE_FACTOR_LONG; 3961 } 3962 case PowerManager.PRE_IDLE_TIMEOUT_MODE_SHORT: { 3963 return mConstants.PRE_IDLE_FACTOR_SHORT; 3964 } 3965 case PowerManager.PRE_IDLE_TIMEOUT_MODE_NORMAL: { 3966 return 1.0f; 3967 } 3968 default: { 3969 Slog.w(TAG, "Invalid time out factor mode: " + mode); 3970 return 1.0f; 3971 } 3972 } 3973 } 3974 3975 @VisibleForTesting getPreIdleTimeoutFactor()3976 float getPreIdleTimeoutFactor() { 3977 synchronized (this) { 3978 return mPreIdleFactor; 3979 } 3980 } 3981 3982 @VisibleForTesting setPreIdleTimeoutFactor(float ratio)3983 int setPreIdleTimeoutFactor(float ratio) { 3984 synchronized (this) { 3985 if (!mDeepEnabled) { 3986 if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: Deep Idle disable"); 3987 return SET_IDLE_FACTOR_RESULT_NOT_SUPPORT; 3988 } else if (ratio <= MIN_PRE_IDLE_FACTOR_CHANGE) { 3989 if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: Invalid input"); 3990 return SET_IDLE_FACTOR_RESULT_INVALID; 3991 } else if (Math.abs(ratio - mPreIdleFactor) < MIN_PRE_IDLE_FACTOR_CHANGE) { 3992 if (DEBUG) { 3993 Slog.d(TAG, "setPreIdleTimeoutFactor: New factor same as previous factor"); 3994 } 3995 return SET_IDLE_FACTOR_RESULT_IGNORED; 3996 } 3997 mLastPreIdleFactor = mPreIdleFactor; 3998 mPreIdleFactor = ratio; 3999 } 4000 if (DEBUG) Slog.d(TAG, "setPreIdleTimeoutFactor: " + ratio); 4001 postUpdatePreIdleFactor(); 4002 return SET_IDLE_FACTOR_RESULT_OK; 4003 } 4004 4005 @VisibleForTesting resetPreIdleTimeoutMode()4006 void resetPreIdleTimeoutMode() { 4007 synchronized (this) { 4008 mLastPreIdleFactor = mPreIdleFactor; 4009 mPreIdleFactor = 1.0f; 4010 } 4011 if (DEBUG) Slog.d(TAG, "resetPreIdleTimeoutMode to 1.0"); 4012 postResetPreIdleTimeoutFactor(); 4013 } 4014 postUpdatePreIdleFactor()4015 private void postUpdatePreIdleFactor() { 4016 mHandler.sendEmptyMessage(MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR); 4017 } 4018 postResetPreIdleTimeoutFactor()4019 private void postResetPreIdleTimeoutFactor() { 4020 mHandler.sendEmptyMessage(MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR); 4021 } 4022 updatePreIdleFactor()4023 private void updatePreIdleFactor() { 4024 synchronized (this) { 4025 if (!shouldUseIdleTimeoutFactorLocked()) { 4026 return; 4027 } 4028 if (mState == STATE_INACTIVE || mState == STATE_IDLE_PENDING) { 4029 if (mNextAlarmTime == 0) { 4030 return; 4031 } 4032 long delay = mNextAlarmTime - SystemClock.elapsedRealtime(); 4033 if (delay < MIN_STATE_STEP_ALARM_CHANGE) { 4034 return; 4035 } 4036 long newDelay = (long) (delay / mLastPreIdleFactor * mPreIdleFactor); 4037 if (Math.abs(delay - newDelay) < MIN_STATE_STEP_ALARM_CHANGE) { 4038 return; 4039 } 4040 scheduleAlarmLocked(newDelay); 4041 } 4042 } 4043 } 4044 maybeDoImmediateMaintenance(String reason)4045 private void maybeDoImmediateMaintenance(String reason) { 4046 synchronized (this) { 4047 if (mState == STATE_IDLE) { 4048 long duration = SystemClock.elapsedRealtime() - mIdleStartTime; 4049 // Trigger an immediate maintenance window if it has been IDLE for long enough. 4050 if (duration > mConstants.IDLE_TIMEOUT) { 4051 stepIdleStateLocked(reason); 4052 } 4053 } 4054 } 4055 } 4056 4057 @GuardedBy("this") shouldUseIdleTimeoutFactorLocked()4058 private boolean shouldUseIdleTimeoutFactorLocked() { 4059 // exclude ACTIVE_REASON_MOTION, for exclude device in pocket case 4060 if (mActiveReason == ACTIVE_REASON_MOTION) { 4061 return false; 4062 } 4063 return true; 4064 } 4065 4066 /** Must only be used in tests. */ 4067 @VisibleForTesting setIdleStartTimeForTest(long idleStartTime)4068 void setIdleStartTimeForTest(long idleStartTime) { 4069 synchronized (this) { 4070 mIdleStartTime = idleStartTime; 4071 maybeDoImmediateMaintenance("testing"); 4072 } 4073 } 4074 4075 @VisibleForTesting getNextAlarmTime()4076 long getNextAlarmTime() { 4077 synchronized (this) { 4078 return mNextAlarmTime; 4079 } 4080 } 4081 4082 @VisibleForTesting isEmergencyCallActive()4083 boolean isEmergencyCallActive() { 4084 return mEmergencyCallListener.isEmergencyCallActive(); 4085 } 4086 4087 @GuardedBy("this") isOpsInactiveLocked()4088 boolean isOpsInactiveLocked() { 4089 return mActiveIdleOpCount <= 0 && !mJobsActive && !mAlarmsActive; 4090 } 4091 4092 @GuardedBy("this") exitMaintenanceEarlyIfNeededLocked()4093 void exitMaintenanceEarlyIfNeededLocked() { 4094 if (mState == STATE_IDLE_MAINTENANCE || mLightState == LIGHT_STATE_IDLE_MAINTENANCE) { 4095 if (isOpsInactiveLocked()) { 4096 final long now = SystemClock.elapsedRealtime(); 4097 if (DEBUG) { 4098 StringBuilder sb = new StringBuilder(); 4099 sb.append("Exit: start="); 4100 TimeUtils.formatDuration(mMaintenanceStartTime, sb); 4101 sb.append(" now="); 4102 TimeUtils.formatDuration(now, sb); 4103 Slog.d(TAG, sb.toString()); 4104 } 4105 if (mState == STATE_IDLE_MAINTENANCE) { 4106 stepIdleStateLocked("s:early"); 4107 } else { 4108 stepLightIdleStateLocked("s:early"); 4109 } 4110 } 4111 } 4112 } 4113 4114 @GuardedBy("this") motionLocked()4115 void motionLocked() { 4116 if (DEBUG) Slog.d(TAG, "motionLocked()"); 4117 mLastMotionEventElapsed = mInjector.getElapsedRealtime(); 4118 handleMotionDetectedLocked(mConstants.MOTION_INACTIVE_TIMEOUT, "motion"); 4119 } 4120 4121 @GuardedBy("this") handleMotionDetectedLocked(long timeout, String type)4122 void handleMotionDetectedLocked(long timeout, String type) { 4123 if (mStationaryListeners.size() > 0) { 4124 postStationaryStatusUpdated(); 4125 cancelMotionTimeoutAlarmLocked(); 4126 // We need to re-register the motion listener, but we don't want the sensors to be 4127 // constantly active or to churn the CPU by registering too early, register after some 4128 // delay. 4129 scheduleMotionRegistrationAlarmLocked(); 4130 } 4131 if (mQuickDozeActivated && !mQuickDozeActivatedWhileIdling) { 4132 // Don't exit idle due to motion if quick doze is enabled. 4133 // However, if the device started idling due to the normal progression (going through 4134 // all the states) and then had quick doze activated, come out briefly on motion so the 4135 // user can get slightly fresher content. 4136 return; 4137 } 4138 maybeStopMonitoringMotionLocked(); 4139 // The device is not yet active, so we want to go back to the pending idle 4140 // state to wait again for no motion. Note that we only monitor for motion 4141 // after moving out of the inactive state, so no need to worry about that. 4142 final boolean becomeInactive = mState != STATE_ACTIVE 4143 || mLightState == LIGHT_STATE_OVERRIDE; 4144 // We only want to change the IDLE state if it's OVERRIDE. 4145 becomeActiveLocked(type, Process.myUid(), timeout, mLightState == LIGHT_STATE_OVERRIDE); 4146 if (becomeInactive) { 4147 becomeInactiveIfAppropriateLocked(); 4148 } 4149 } 4150 4151 @GuardedBy("this") receivedGenericLocationLocked(Location location)4152 void receivedGenericLocationLocked(Location location) { 4153 if (mState != STATE_LOCATING) { 4154 cancelLocatingLocked(); 4155 return; 4156 } 4157 if (DEBUG) Slog.d(TAG, "Generic location: " + location); 4158 mLastGenericLocation = new Location(location); 4159 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHasGps) { 4160 return; 4161 } 4162 mLocated = true; 4163 if (mNotMoving) { 4164 stepIdleStateLocked("s:location"); 4165 } 4166 } 4167 4168 @GuardedBy("this") receivedGpsLocationLocked(Location location)4169 void receivedGpsLocationLocked(Location location) { 4170 if (mState != STATE_LOCATING) { 4171 cancelLocatingLocked(); 4172 return; 4173 } 4174 if (DEBUG) Slog.d(TAG, "GPS location: " + location); 4175 mLastGpsLocation = new Location(location); 4176 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY) { 4177 return; 4178 } 4179 mLocated = true; 4180 if (mNotMoving) { 4181 stepIdleStateLocked("s:gps"); 4182 } 4183 } 4184 startMonitoringMotionLocked()4185 void startMonitoringMotionLocked() { 4186 if (DEBUG) Slog.d(TAG, "startMonitoringMotionLocked()"); 4187 if (mMotionSensor != null && !mMotionListener.active) { 4188 mMotionListener.registerLocked(); 4189 } 4190 } 4191 4192 /** 4193 * Stops motion monitoring. Will not stop monitoring if there are registered stationary 4194 * listeners. 4195 */ maybeStopMonitoringMotionLocked()4196 private void maybeStopMonitoringMotionLocked() { 4197 if (DEBUG) Slog.d(TAG, "maybeStopMonitoringMotionLocked()"); 4198 if (mMotionSensor != null && mStationaryListeners.size() == 0) { 4199 if (mMotionListener.active) { 4200 mMotionListener.unregisterLocked(); 4201 cancelMotionTimeoutAlarmLocked(); 4202 } 4203 cancelMotionRegistrationAlarmLocked(); 4204 } 4205 } 4206 4207 @GuardedBy("this") cancelAlarmLocked()4208 void cancelAlarmLocked() { 4209 if (mNextAlarmTime != 0) { 4210 mNextAlarmTime = 0; 4211 mAlarmManager.cancel(mDeepAlarmListener); 4212 } 4213 } 4214 4215 @GuardedBy("this") cancelLightAlarmLocked()4216 private void cancelLightAlarmLocked() { 4217 if (mNextLightAlarmTime != 0) { 4218 mNextLightAlarmTime = 0; 4219 mAlarmManager.cancel(mLightAlarmListener); 4220 } 4221 } 4222 4223 @GuardedBy("this") cancelLocatingLocked()4224 void cancelLocatingLocked() { 4225 if (mLocating) { 4226 LocationManager locationManager = mInjector.getLocationManager(); 4227 locationManager.removeUpdates(mGenericLocationListener); 4228 locationManager.removeUpdates(mGpsLocationListener); 4229 mLocating = false; 4230 } 4231 } 4232 cancelMotionTimeoutAlarmLocked()4233 private void cancelMotionTimeoutAlarmLocked() { 4234 mAlarmManager.cancel(mMotionTimeoutAlarmListener); 4235 } 4236 cancelMotionRegistrationAlarmLocked()4237 private void cancelMotionRegistrationAlarmLocked() { 4238 mAlarmManager.cancel(mMotionRegistrationAlarmListener); 4239 } 4240 4241 @GuardedBy("this") cancelSensingTimeoutAlarmLocked()4242 void cancelSensingTimeoutAlarmLocked() { 4243 if (mNextSensingTimeoutAlarmTime != 0) { 4244 mNextSensingTimeoutAlarmTime = 0; 4245 mAlarmManager.cancel(mSensingTimeoutAlarmListener); 4246 } 4247 } 4248 4249 @GuardedBy("this") 4250 @VisibleForTesting scheduleAlarmLocked(long delay)4251 void scheduleAlarmLocked(long delay) { 4252 if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + stateToString(mState) + ")"); 4253 4254 if (mUseMotionSensor && mMotionSensor == null 4255 && mState != STATE_QUICK_DOZE_DELAY 4256 && mState != STATE_IDLE 4257 && mState != STATE_IDLE_MAINTENANCE) { 4258 // If there is no motion sensor on this device, but we need one, then we won't schedule 4259 // alarms, because we can't determine if the device is not moving. This effectively 4260 // turns off normal execution of device idling, although it is still possible to 4261 // manually poke it by pretending like the alarm is going off. 4262 // STATE_QUICK_DOZE_DELAY skips the motion sensing so if the state is past the motion 4263 // sensing stage (ie, is QUICK_DOZE_DELAY, IDLE, or IDLE_MAINTENANCE), then idling 4264 // can continue until the user interacts with the device. 4265 return; 4266 } 4267 mNextAlarmTime = SystemClock.elapsedRealtime() + delay; 4268 if (mState == STATE_IDLE) { 4269 mAlarmManager.setIdleUntil(AlarmManager.ELAPSED_REALTIME_WAKEUP, 4270 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler); 4271 } else if (mState == STATE_LOCATING) { 4272 // Use setExact so we don't keep the GPS active for too long. 4273 mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, 4274 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler); 4275 } else { 4276 if (mConstants.USE_WINDOW_ALARMS) { 4277 mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, 4278 mNextAlarmTime, mConstants.FLEX_TIME_SHORT, 4279 "DeviceIdleController.deep", mDeepAlarmListener, mHandler); 4280 } else { 4281 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 4282 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler); 4283 } 4284 } 4285 } 4286 4287 @GuardedBy("this") scheduleLightAlarmLocked(long delay, long flex, boolean wakeup)4288 void scheduleLightAlarmLocked(long delay, long flex, boolean wakeup) { 4289 if (DEBUG) { 4290 Slog.d(TAG, "scheduleLightAlarmLocked(" + delay 4291 + (mConstants.USE_WINDOW_ALARMS ? "/" + flex : "") 4292 + ", wakeup=" + wakeup + ")"); 4293 } 4294 mNextLightAlarmTime = mInjector.getElapsedRealtime() + delay; 4295 if (mConstants.USE_WINDOW_ALARMS) { 4296 mAlarmManager.setWindow( 4297 wakeup ? AlarmManager.ELAPSED_REALTIME_WAKEUP : AlarmManager.ELAPSED_REALTIME, 4298 mNextLightAlarmTime, flex, 4299 "DeviceIdleController.light", mLightAlarmListener, mHandler); 4300 } else { 4301 mAlarmManager.set( 4302 wakeup ? AlarmManager.ELAPSED_REALTIME_WAKEUP : AlarmManager.ELAPSED_REALTIME, 4303 mNextLightAlarmTime, 4304 "DeviceIdleController.light", mLightAlarmListener, mHandler); 4305 } 4306 } 4307 4308 @VisibleForTesting getNextLightAlarmTimeForTesting()4309 long getNextLightAlarmTimeForTesting() { 4310 synchronized (this) { 4311 return mNextLightAlarmTime; 4312 } 4313 } 4314 scheduleMotionRegistrationAlarmLocked()4315 private void scheduleMotionRegistrationAlarmLocked() { 4316 if (DEBUG) Slog.d(TAG, "scheduleMotionRegistrationAlarmLocked"); 4317 long nextMotionRegistrationAlarmTime = 4318 mInjector.getElapsedRealtime() + mConstants.MOTION_INACTIVE_TIMEOUT / 2; 4319 if (mConstants.USE_WINDOW_ALARMS) { 4320 mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, 4321 nextMotionRegistrationAlarmTime, mConstants.MOTION_INACTIVE_TIMEOUT_FLEX, 4322 "DeviceIdleController.motion_registration", mMotionRegistrationAlarmListener, 4323 mHandler); 4324 } else { 4325 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextMotionRegistrationAlarmTime, 4326 "DeviceIdleController.motion_registration", mMotionRegistrationAlarmListener, 4327 mHandler); 4328 } 4329 } 4330 scheduleMotionTimeoutAlarmLocked()4331 private void scheduleMotionTimeoutAlarmLocked() { 4332 if (DEBUG) Slog.d(TAG, "scheduleMotionAlarmLocked"); 4333 long nextMotionTimeoutAlarmTime = 4334 mInjector.getElapsedRealtime() + mConstants.MOTION_INACTIVE_TIMEOUT; 4335 if (mConstants.USE_WINDOW_ALARMS) { 4336 mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, 4337 nextMotionTimeoutAlarmTime, 4338 mConstants.MOTION_INACTIVE_TIMEOUT_FLEX, 4339 "DeviceIdleController.motion", mMotionTimeoutAlarmListener, mHandler); 4340 } else { 4341 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextMotionTimeoutAlarmTime, 4342 "DeviceIdleController.motion", mMotionTimeoutAlarmListener, mHandler); 4343 } 4344 } 4345 4346 @GuardedBy("this") scheduleSensingTimeoutAlarmLocked(long delay)4347 void scheduleSensingTimeoutAlarmLocked(long delay) { 4348 if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")"); 4349 mNextSensingTimeoutAlarmTime = SystemClock.elapsedRealtime() + delay; 4350 if (mConstants.USE_WINDOW_ALARMS) { 4351 mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, 4352 mNextSensingTimeoutAlarmTime, 4353 mConstants.FLEX_TIME_SHORT, 4354 "DeviceIdleController.sensing", mSensingTimeoutAlarmListener, mHandler); 4355 } else { 4356 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextSensingTimeoutAlarmTime, 4357 "DeviceIdleController.sensing", mSensingTimeoutAlarmListener, mHandler); 4358 } 4359 } 4360 buildAppIdArray(ArrayMap<String, Integer> systemApps, ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds)4361 private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps, 4362 ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds) { 4363 outAppIds.clear(); 4364 if (systemApps != null) { 4365 for (int i = 0; i < systemApps.size(); i++) { 4366 outAppIds.put(systemApps.valueAt(i), true); 4367 } 4368 } 4369 if (userApps != null) { 4370 for (int i = 0; i < userApps.size(); i++) { 4371 outAppIds.put(userApps.valueAt(i), true); 4372 } 4373 } 4374 int size = outAppIds.size(); 4375 int[] appids = new int[size]; 4376 for (int i = 0; i < size; i++) { 4377 appids[i] = outAppIds.keyAt(i); 4378 } 4379 return appids; 4380 } 4381 updateWhitelistAppIdsLocked()4382 private void updateWhitelistAppIdsLocked() { 4383 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(mPowerSaveWhitelistAppsExceptIdle, 4384 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistExceptIdleAppIds); 4385 mPowerSaveWhitelistAllAppIdArray = buildAppIdArray(mPowerSaveWhitelistApps, 4386 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistAllAppIds); 4387 mPowerSaveWhitelistUserAppIdArray = buildAppIdArray(null, 4388 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistUserAppIds); 4389 if (mLocalActivityManager != null) { 4390 mLocalActivityManager.setDeviceIdleAllowlist( 4391 mPowerSaveWhitelistAllAppIdArray, mPowerSaveWhitelistExceptIdleAppIdArray); 4392 } 4393 if (mLocalPowerManager != null) { 4394 if (DEBUG) { 4395 Slog.d(TAG, "Setting wakelock whitelist to " 4396 + Arrays.toString(mPowerSaveWhitelistAllAppIdArray)); 4397 } 4398 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); 4399 } 4400 passWhiteListsToForceAppStandbyTrackerLocked(); 4401 } 4402 4403 /** 4404 * update temp allowlist. 4405 * @param uid uid to add or remove from temp allowlist. 4406 * @param adding true to add to temp allowlist, false to remove from temp allowlist. 4407 * @param durationMs duration in milliseconds to add to temp allowlist, only valid when 4408 * param adding is true. 4409 * @param type temp allowlist type defined at {@link TempAllowListType} 4410 * @prama reasonCode one of {@Link ReasonCode} 4411 * @param reason A human-readable reason for logging purposes. 4412 * @param callingUid the callingUid that setup this temp-allowlist, only valid when param adding 4413 * is true. 4414 */ 4415 @GuardedBy("this") updateTempWhitelistAppIdsLocked(int uid, boolean adding, long durationMs, @TempAllowListType int type, @ReasonCode int reasonCode, @Nullable String reason, int callingUid)4416 private void updateTempWhitelistAppIdsLocked(int uid, boolean adding, long durationMs, 4417 @TempAllowListType int type, @ReasonCode int reasonCode, @Nullable String reason, 4418 int callingUid) { 4419 final int size = mTempWhitelistAppIdEndTimes.size(); 4420 if (mTempWhitelistAppIdArray.length != size) { 4421 mTempWhitelistAppIdArray = new int[size]; 4422 } 4423 for (int i = 0; i < size; i++) { 4424 mTempWhitelistAppIdArray[i] = mTempWhitelistAppIdEndTimes.keyAt(i); 4425 } 4426 if (mLocalActivityManager != null) { 4427 if (DEBUG) { 4428 Slog.d(TAG, "Setting activity manager temp whitelist to " 4429 + Arrays.toString(mTempWhitelistAppIdArray)); 4430 } 4431 mLocalActivityManager.updateDeviceIdleTempAllowlist(mTempWhitelistAppIdArray, uid, 4432 adding, durationMs, type, reasonCode, reason, callingUid); 4433 } 4434 if (mLocalPowerManager != null) { 4435 if (DEBUG) { 4436 Slog.d(TAG, "Setting wakelock temp whitelist to " 4437 + Arrays.toString(mTempWhitelistAppIdArray)); 4438 } 4439 mLocalPowerManager.setDeviceIdleTempWhitelist(mTempWhitelistAppIdArray); 4440 } 4441 passWhiteListsToForceAppStandbyTrackerLocked(); 4442 } 4443 reportPowerSaveWhitelistChangedLocked()4444 private void reportPowerSaveWhitelistChangedLocked() { 4445 getContext().sendBroadcastAsUser(mPowerSaveWhitelistChangedIntent, UserHandle.SYSTEM, 4446 null /* receiverPermission */, 4447 mPowerSaveWhitelistChangedOptions); 4448 } 4449 reportTempWhitelistChangedLocked(final int uid, final boolean added)4450 private void reportTempWhitelistChangedLocked(final int uid, final boolean added) { 4451 mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED, uid, added ? 1 : 0) 4452 .sendToTarget(); 4453 getContext().sendBroadcastAsUser(mPowerSaveTempWhitelistChangedIntent, UserHandle.SYSTEM, 4454 null /* receiverPermission */, 4455 mPowerSaveTempWhilelistChangedOptions); 4456 } 4457 passWhiteListsToForceAppStandbyTrackerLocked()4458 private void passWhiteListsToForceAppStandbyTrackerLocked() { 4459 mAppStateTracker.setPowerSaveExemptionListAppIds( 4460 mPowerSaveWhitelistExceptIdleAppIdArray, 4461 mPowerSaveWhitelistUserAppIdArray, 4462 mTempWhitelistAppIdArray); 4463 } 4464 4465 @GuardedBy("this") readConfigFileLocked()4466 void readConfigFileLocked() { 4467 if (DEBUG) Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile()); 4468 mPowerSaveWhitelistUserApps.clear(); 4469 FileInputStream stream; 4470 try { 4471 stream = mConfigFile.openRead(); 4472 } catch (FileNotFoundException e) { 4473 return; 4474 } 4475 try { 4476 XmlPullParser parser = Xml.newPullParser(); 4477 parser.setInput(stream, StandardCharsets.UTF_8.name()); 4478 readConfigFileLocked(parser); 4479 } catch (XmlPullParserException e) { 4480 } finally { 4481 try { 4482 stream.close(); 4483 } catch (IOException e) { 4484 } 4485 } 4486 } 4487 4488 @GuardedBy("this") readConfigFileLocked(XmlPullParser parser)4489 private void readConfigFileLocked(XmlPullParser parser) { 4490 final PackageManager pm = getContext().getPackageManager(); 4491 4492 try { 4493 int type; 4494 while ((type = parser.next()) != XmlPullParser.START_TAG 4495 && type != XmlPullParser.END_DOCUMENT) { 4496 ; 4497 } 4498 4499 if (type != XmlPullParser.START_TAG) { 4500 throw new IllegalStateException("no start tag found"); 4501 } 4502 4503 int outerDepth = parser.getDepth(); 4504 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 4505 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 4506 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 4507 continue; 4508 } 4509 4510 String tagName = parser.getName(); 4511 switch (tagName) { 4512 case "wl": 4513 String name = parser.getAttributeValue(null, "n"); 4514 if (name != null) { 4515 try { 4516 ApplicationInfo ai = pm.getApplicationInfo(name, 4517 PackageManager.MATCH_ANY_USER); 4518 mPowerSaveWhitelistUserApps.put(ai.packageName, 4519 UserHandle.getAppId(ai.uid)); 4520 } catch (PackageManager.NameNotFoundException e) { 4521 } 4522 } 4523 break; 4524 case "un-wl": 4525 final String packageName = parser.getAttributeValue(null, "n"); 4526 if (mPowerSaveWhitelistApps.containsKey(packageName)) { 4527 mRemovedFromSystemWhitelistApps.put(packageName, 4528 mPowerSaveWhitelistApps.remove(packageName)); 4529 } 4530 break; 4531 default: 4532 Slog.w(TAG, "Unknown element under <config>: " 4533 + parser.getName()); 4534 XmlUtils.skipCurrentTag(parser); 4535 break; 4536 } 4537 } 4538 4539 } catch (IllegalStateException e) { 4540 Slog.w(TAG, "Failed parsing config " + e); 4541 } catch (NullPointerException e) { 4542 Slog.w(TAG, "Failed parsing config " + e); 4543 } catch (NumberFormatException e) { 4544 Slog.w(TAG, "Failed parsing config " + e); 4545 } catch (XmlPullParserException e) { 4546 Slog.w(TAG, "Failed parsing config " + e); 4547 } catch (IOException e) { 4548 Slog.w(TAG, "Failed parsing config " + e); 4549 } catch (IndexOutOfBoundsException e) { 4550 Slog.w(TAG, "Failed parsing config " + e); 4551 } 4552 } 4553 writeConfigFileLocked()4554 void writeConfigFileLocked() { 4555 mHandler.removeMessages(MSG_WRITE_CONFIG); 4556 mHandler.sendEmptyMessageDelayed(MSG_WRITE_CONFIG, 5000); 4557 } 4558 handleWriteConfigFile()4559 void handleWriteConfigFile() { 4560 final ByteArrayOutputStream memStream = new ByteArrayOutputStream(); 4561 4562 try { 4563 synchronized (this) { 4564 XmlSerializer out = new FastXmlSerializer(); 4565 out.setOutput(memStream, StandardCharsets.UTF_8.name()); 4566 writeConfigFileLocked(out); 4567 } 4568 } catch (IOException e) { 4569 } 4570 4571 synchronized (mConfigFile) { 4572 FileOutputStream stream = null; 4573 try { 4574 stream = mConfigFile.startWrite(); 4575 memStream.writeTo(stream); 4576 mConfigFile.finishWrite(stream); 4577 } catch (IOException e) { 4578 Slog.w(TAG, "Error writing config file", e); 4579 mConfigFile.failWrite(stream); 4580 } 4581 } 4582 } 4583 writeConfigFileLocked(XmlSerializer out)4584 void writeConfigFileLocked(XmlSerializer out) throws IOException { 4585 out.startDocument(null, true); 4586 out.startTag(null, "config"); 4587 for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) { 4588 String name = mPowerSaveWhitelistUserApps.keyAt(i); 4589 out.startTag(null, "wl"); 4590 out.attribute(null, "n", name); 4591 out.endTag(null, "wl"); 4592 } 4593 for (int i = 0; i < mRemovedFromSystemWhitelistApps.size(); i++) { 4594 out.startTag(null, "un-wl"); 4595 out.attribute(null, "n", mRemovedFromSystemWhitelistApps.keyAt(i)); 4596 out.endTag(null, "un-wl"); 4597 } 4598 out.endTag(null, "config"); 4599 out.endDocument(); 4600 } 4601 dumpHelp(PrintWriter pw)4602 static void dumpHelp(PrintWriter pw) { 4603 pw.println("Device idle controller (deviceidle) commands:"); 4604 pw.println(" help"); 4605 pw.println(" Print this help text."); 4606 pw.println(" step [light|deep]"); 4607 pw.println(" Immediately step to next state, without waiting for alarm."); 4608 pw.println(" force-idle [light|deep]"); 4609 pw.println(" Force directly into idle mode, regardless of other device state."); 4610 pw.println(" force-inactive"); 4611 pw.println(" Force to be inactive, ready to freely step idle states."); 4612 pw.println(" unforce"); 4613 pw.println(" Resume normal functioning after force-idle or force-inactive."); 4614 pw.println(" get [light|deep|force|screen|charging|network]"); 4615 pw.println(" Retrieve the current given state."); 4616 pw.println(" disable [light|deep|all]"); 4617 pw.println(" Completely disable device idle mode."); 4618 pw.println(" enable [light|deep|all]"); 4619 pw.println(" Re-enable device idle mode after it had previously been disabled."); 4620 pw.println(" enabled [light|deep|all]"); 4621 pw.println(" Print 1 if device idle mode is currently enabled, else 0."); 4622 pw.println(" whitelist"); 4623 pw.println(" Print currently whitelisted apps."); 4624 pw.println(" whitelist [package ...]"); 4625 pw.println(" Add (prefix with +) or remove (prefix with -) packages."); 4626 pw.println(" sys-whitelist [package ...|reset]"); 4627 pw.println(" Prefix the package with '-' to remove it from the system whitelist or '+'" 4628 + " to put it back in the system whitelist."); 4629 pw.println(" Note that only packages that were" 4630 + " earlier removed from the system whitelist can be added back."); 4631 pw.println(" reset will reset the whitelist to the original state"); 4632 pw.println(" Prints the system whitelist if no arguments are specified"); 4633 pw.println(" except-idle-whitelist [package ...|reset]"); 4634 pw.println(" Prefix the package with '+' to add it to whitelist or " 4635 + "'=' to check if it is already whitelisted"); 4636 pw.println(" [reset] will reset the whitelist to it's original state"); 4637 pw.println(" Note that unlike <whitelist> cmd, " 4638 + "changes made using this won't be persisted across boots"); 4639 pw.println(" tempwhitelist"); 4640 pw.println(" Print packages that are temporarily whitelisted."); 4641 pw.println(" tempwhitelist [-u USER] [-d DURATION] [-r] [package]"); 4642 pw.println(" Temporarily place package in whitelist for DURATION milliseconds."); 4643 pw.println(" If no DURATION is specified, 10 seconds is used"); 4644 pw.println(" If [-r] option is used, then the package is removed from temp whitelist " 4645 + "and any [-d] is ignored"); 4646 pw.println(" motion"); 4647 pw.println(" Simulate a motion event to bring the device out of deep doze"); 4648 pw.println(" pre-idle-factor [0|1|2]"); 4649 pw.println(" Set a new factor to idle time before step to idle" 4650 + "(inactive_to and idle_after_inactive_to)"); 4651 pw.println(" reset-pre-idle-factor"); 4652 pw.println(" Reset factor to idle time to default"); 4653 } 4654 4655 class Shell extends ShellCommand { 4656 int userId = UserHandle.USER_SYSTEM; 4657 4658 @Override onCommand(String cmd)4659 public int onCommand(String cmd) { 4660 return onShellCommand(this, cmd); 4661 } 4662 4663 @Override onHelp()4664 public void onHelp() { 4665 PrintWriter pw = getOutPrintWriter(); 4666 dumpHelp(pw); 4667 } 4668 } 4669 onShellCommand(Shell shell, String cmd)4670 int onShellCommand(Shell shell, String cmd) { 4671 PrintWriter pw = shell.getOutPrintWriter(); 4672 if ("step".equals(cmd)) { 4673 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 4674 null); 4675 synchronized (this) { 4676 final long token = Binder.clearCallingIdentity(); 4677 String arg = shell.getNextArg(); 4678 try { 4679 if (arg == null || "deep".equals(arg)) { 4680 stepIdleStateLocked("s:shell"); 4681 pw.print("Stepped to deep: "); 4682 pw.println(stateToString(mState)); 4683 } else if ("light".equals(arg)) { 4684 stepLightIdleStateLocked("s:shell"); 4685 pw.print("Stepped to light: "); pw.println(lightStateToString(mLightState)); 4686 } else { 4687 pw.println("Unknown idle mode: " + arg); 4688 } 4689 } finally { 4690 Binder.restoreCallingIdentity(token); 4691 } 4692 } 4693 } else if ("force-active".equals(cmd)) { 4694 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 4695 null); 4696 synchronized (this) { 4697 final long token = Binder.clearCallingIdentity(); 4698 try { 4699 mForceIdle = true; 4700 becomeActiveLocked("force-active", Process.myUid()); 4701 pw.print("Light state: "); 4702 pw.print(lightStateToString(mLightState)); 4703 pw.print(", deep state: "); 4704 pw.println(stateToString(mState)); 4705 } finally { 4706 Binder.restoreCallingIdentity(token); 4707 } 4708 } 4709 } else if ("force-idle".equals(cmd)) { 4710 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 4711 null); 4712 synchronized (this) { 4713 final long token = Binder.clearCallingIdentity(); 4714 String arg = shell.getNextArg(); 4715 try { 4716 if (arg == null || "deep".equals(arg)) { 4717 if (!mDeepEnabled) { 4718 pw.println("Unable to go deep idle; not enabled"); 4719 return -1; 4720 } 4721 mForceIdle = true; 4722 becomeInactiveIfAppropriateLocked(); 4723 int curState = mState; 4724 while (curState != STATE_IDLE) { 4725 stepIdleStateLocked("s:shell"); 4726 if (curState == mState) { 4727 pw.print("Unable to go deep idle; stopped at "); 4728 pw.println(stateToString(mState)); 4729 exitForceIdleLocked(); 4730 return -1; 4731 } 4732 curState = mState; 4733 } 4734 pw.println("Now forced in to deep idle mode"); 4735 } else if ("light".equals(arg)) { 4736 mForceIdle = true; 4737 becomeInactiveIfAppropriateLocked(); 4738 int curLightState = mLightState; 4739 while (curLightState != LIGHT_STATE_IDLE) { 4740 stepLightIdleStateLocked("s:shell"); 4741 if (curLightState == mLightState) { 4742 pw.print("Unable to go light idle; stopped at "); 4743 pw.println(lightStateToString(mLightState)); 4744 exitForceIdleLocked(); 4745 return -1; 4746 } 4747 curLightState = mLightState; 4748 } 4749 pw.println("Now forced in to light idle mode"); 4750 } else { 4751 pw.println("Unknown idle mode: " + arg); 4752 } 4753 } finally { 4754 Binder.restoreCallingIdentity(token); 4755 } 4756 } 4757 } else if ("force-inactive".equals(cmd)) { 4758 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 4759 null); 4760 synchronized (this) { 4761 final long token = Binder.clearCallingIdentity(); 4762 try { 4763 mForceIdle = true; 4764 becomeInactiveIfAppropriateLocked(); 4765 pw.print("Light state: "); 4766 pw.print(lightStateToString(mLightState)); 4767 pw.print(", deep state: "); 4768 pw.println(stateToString(mState)); 4769 } finally { 4770 Binder.restoreCallingIdentity(token); 4771 } 4772 } 4773 } else if ("unforce".equals(cmd)) { 4774 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 4775 null); 4776 synchronized (this) { 4777 final long token = Binder.clearCallingIdentity(); 4778 try { 4779 exitForceIdleLocked(); 4780 pw.print("Light state: "); 4781 pw.print(lightStateToString(mLightState)); 4782 pw.print(", deep state: "); 4783 pw.println(stateToString(mState)); 4784 } finally { 4785 Binder.restoreCallingIdentity(token); 4786 } 4787 } 4788 } else if ("get".equals(cmd)) { 4789 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 4790 null); 4791 synchronized (this) { 4792 String arg = shell.getNextArg(); 4793 if (arg != null) { 4794 final long token = Binder.clearCallingIdentity(); 4795 try { 4796 switch (arg) { 4797 case "light": pw.println(lightStateToString(mLightState)); break; 4798 case "deep": pw.println(stateToString(mState)); break; 4799 case "force": pw.println(mForceIdle); break; 4800 case "quick": pw.println(mQuickDozeActivated); break; 4801 case "screen": pw.println(mScreenOn); break; 4802 case "charging": pw.println(mCharging); break; 4803 case "network": pw.println(mNetworkConnected); break; 4804 default: pw.println("Unknown get option: " + arg); break; 4805 } 4806 } finally { 4807 Binder.restoreCallingIdentity(token); 4808 } 4809 } else { 4810 pw.println("Argument required"); 4811 } 4812 } 4813 } else if ("disable".equals(cmd)) { 4814 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 4815 null); 4816 synchronized (this) { 4817 final long token = Binder.clearCallingIdentity(); 4818 String arg = shell.getNextArg(); 4819 try { 4820 boolean becomeActive = false; 4821 boolean valid = false; 4822 if (arg == null || "deep".equals(arg) || "all".equals(arg)) { 4823 valid = true; 4824 if (mDeepEnabled) { 4825 mDeepEnabled = false; 4826 becomeActive = true; 4827 pw.println("Deep idle mode disabled"); 4828 } 4829 } 4830 if (arg == null || "light".equals(arg) || "all".equals(arg)) { 4831 valid = true; 4832 if (mLightEnabled) { 4833 mLightEnabled = false; 4834 becomeActive = true; 4835 pw.println("Light idle mode disabled"); 4836 } 4837 } 4838 if (becomeActive) { 4839 mActiveReason = ACTIVE_REASON_FORCED; 4840 becomeActiveLocked((arg == null ? "all" : arg) + "-disabled", 4841 Process.myUid()); 4842 } 4843 if (!valid) { 4844 pw.println("Unknown idle mode: " + arg); 4845 } 4846 } finally { 4847 Binder.restoreCallingIdentity(token); 4848 } 4849 } 4850 } else if ("enable".equals(cmd)) { 4851 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 4852 null); 4853 synchronized (this) { 4854 final long token = Binder.clearCallingIdentity(); 4855 String arg = shell.getNextArg(); 4856 try { 4857 boolean becomeInactive = false; 4858 boolean valid = false; 4859 if (arg == null || "deep".equals(arg) || "all".equals(arg)) { 4860 valid = true; 4861 if (!mDeepEnabled) { 4862 mDeepEnabled = true; 4863 becomeInactive = true; 4864 pw.println("Deep idle mode enabled"); 4865 } 4866 } 4867 if (arg == null || "light".equals(arg) || "all".equals(arg)) { 4868 valid = true; 4869 if (!mLightEnabled) { 4870 mLightEnabled = true; 4871 becomeInactive = true; 4872 pw.println("Light idle mode enable"); 4873 } 4874 } 4875 if (becomeInactive) { 4876 becomeInactiveIfAppropriateLocked(); 4877 } 4878 if (!valid) { 4879 pw.println("Unknown idle mode: " + arg); 4880 } 4881 } finally { 4882 Binder.restoreCallingIdentity(token); 4883 } 4884 } 4885 } else if ("enabled".equals(cmd)) { 4886 synchronized (this) { 4887 String arg = shell.getNextArg(); 4888 if (arg == null || "all".equals(arg)) { 4889 pw.println(mDeepEnabled && mLightEnabled ? "1" : 0); 4890 } else if ("deep".equals(arg)) { 4891 pw.println(mDeepEnabled ? "1" : 0); 4892 } else if ("light".equals(arg)) { 4893 pw.println(mLightEnabled ? "1" : 0); 4894 } else { 4895 pw.println("Unknown idle mode: " + arg); 4896 } 4897 } 4898 } else if ("whitelist".equals(cmd)) { 4899 String arg = shell.getNextArg(); 4900 if (arg != null) { 4901 getContext().enforceCallingOrSelfPermission( 4902 android.Manifest.permission.DEVICE_POWER, null); 4903 final long token = Binder.clearCallingIdentity(); 4904 try { 4905 do { 4906 if (arg.length() < 1 || (arg.charAt(0) != '-' 4907 && arg.charAt(0) != '+' && arg.charAt(0) != '=')) { 4908 pw.println("Package must be prefixed with +, -, or =: " + arg); 4909 return -1; 4910 } 4911 char op = arg.charAt(0); 4912 String pkg = arg.substring(1); 4913 if (op == '+') { 4914 if (addPowerSaveWhitelistAppsInternal(Collections.singletonList(pkg)) 4915 == 1) { 4916 pw.println("Added: " + pkg); 4917 } else { 4918 pw.println("Unknown package: " + pkg); 4919 } 4920 } else if (op == '-') { 4921 if (removePowerSaveWhitelistAppInternal(pkg)) { 4922 pw.println("Removed: " + pkg); 4923 } 4924 } else { 4925 pw.println(getPowerSaveWhitelistAppInternal(pkg)); 4926 } 4927 } while ((arg=shell.getNextArg()) != null); 4928 } finally { 4929 Binder.restoreCallingIdentity(token); 4930 } 4931 } else { 4932 if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) { 4933 return -1; 4934 } 4935 synchronized (this) { 4936 for (int j=0; j<mPowerSaveWhitelistAppsExceptIdle.size(); j++) { 4937 pw.print("system-excidle,"); 4938 pw.print(mPowerSaveWhitelistAppsExceptIdle.keyAt(j)); 4939 pw.print(","); 4940 pw.println(mPowerSaveWhitelistAppsExceptIdle.valueAt(j)); 4941 } 4942 for (int j=0; j<mPowerSaveWhitelistApps.size(); j++) { 4943 pw.print("system,"); 4944 pw.print(mPowerSaveWhitelistApps.keyAt(j)); 4945 pw.print(","); 4946 pw.println(mPowerSaveWhitelistApps.valueAt(j)); 4947 } 4948 for (int j=0; j<mPowerSaveWhitelistUserApps.size(); j++) { 4949 pw.print("user,"); 4950 pw.print(mPowerSaveWhitelistUserApps.keyAt(j)); 4951 pw.print(","); 4952 pw.println(mPowerSaveWhitelistUserApps.valueAt(j)); 4953 } 4954 } 4955 } 4956 } else if ("tempwhitelist".equals(cmd)) { 4957 long duration = 10000; 4958 boolean removePkg = false; 4959 String opt; 4960 while ((opt=shell.getNextOption()) != null) { 4961 if ("-u".equals(opt)) { 4962 opt = shell.getNextArg(); 4963 if (opt == null) { 4964 pw.println("-u requires a user number"); 4965 return -1; 4966 } 4967 shell.userId = Integer.parseInt(opt); 4968 } else if ("-d".equals(opt)) { 4969 opt = shell.getNextArg(); 4970 if (opt == null) { 4971 pw.println("-d requires a duration"); 4972 return -1; 4973 } 4974 duration = Long.parseLong(opt); 4975 } else if ("-r".equals(opt)) { 4976 removePkg = true; 4977 } 4978 } 4979 String arg = shell.getNextArg(); 4980 if (arg != null) { 4981 try { 4982 if (removePkg) { 4983 removePowerSaveTempAllowlistAppChecked(arg, shell.userId); 4984 } else { 4985 addPowerSaveTempAllowlistAppChecked(arg, duration, shell.userId, 4986 REASON_SHELL, "shell"); 4987 } 4988 } catch (Exception e) { 4989 pw.println("Failed: " + e); 4990 return -1; 4991 } 4992 } else if (removePkg) { 4993 pw.println("[-r] requires a package name"); 4994 return -1; 4995 } else { 4996 if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) { 4997 return -1; 4998 } 4999 dumpTempWhitelistSchedule(pw, false); 5000 } 5001 } else if ("except-idle-whitelist".equals(cmd)) { 5002 getContext().enforceCallingOrSelfPermission( 5003 android.Manifest.permission.DEVICE_POWER, null); 5004 final long token = Binder.clearCallingIdentity(); 5005 try { 5006 String arg = shell.getNextArg(); 5007 if (arg == null) { 5008 pw.println("No arguments given"); 5009 return -1; 5010 } else if ("reset".equals(arg)) { 5011 resetPowerSaveWhitelistExceptIdleInternal(); 5012 } else { 5013 do { 5014 if (arg.length() < 1 || (arg.charAt(0) != '-' 5015 && arg.charAt(0) != '+' && arg.charAt(0) != '=')) { 5016 pw.println("Package must be prefixed with +, -, or =: " + arg); 5017 return -1; 5018 } 5019 char op = arg.charAt(0); 5020 String pkg = arg.substring(1); 5021 if (op == '+') { 5022 if (addPowerSaveWhitelistExceptIdleInternal(pkg)) { 5023 pw.println("Added: " + pkg); 5024 } else { 5025 pw.println("Unknown package: " + pkg); 5026 } 5027 } else if (op == '=') { 5028 pw.println(getPowerSaveWhitelistExceptIdleInternal(pkg)); 5029 } else { 5030 pw.println("Unknown argument: " + arg); 5031 return -1; 5032 } 5033 } while ((arg = shell.getNextArg()) != null); 5034 } 5035 } finally { 5036 Binder.restoreCallingIdentity(token); 5037 } 5038 } else if ("sys-whitelist".equals(cmd)) { 5039 String arg = shell.getNextArg(); 5040 if (arg != null) { 5041 getContext().enforceCallingOrSelfPermission( 5042 android.Manifest.permission.DEVICE_POWER, null); 5043 final long token = Binder.clearCallingIdentity(); 5044 try { 5045 if ("reset".equals(arg)) { 5046 resetSystemPowerWhitelistInternal(); 5047 } else { 5048 do { 5049 if (arg.length() < 1 5050 || (arg.charAt(0) != '-' && arg.charAt(0) != '+')) { 5051 pw.println("Package must be prefixed with + or - " + arg); 5052 return -1; 5053 } 5054 final char op = arg.charAt(0); 5055 final String pkg = arg.substring(1); 5056 switch (op) { 5057 case '+': 5058 if (restoreSystemPowerWhitelistAppInternal(pkg)) { 5059 pw.println("Restored " + pkg); 5060 } 5061 break; 5062 case '-': 5063 if (removeSystemPowerWhitelistAppInternal(pkg)) { 5064 pw.println("Removed " + pkg); 5065 } 5066 break; 5067 } 5068 } while ((arg = shell.getNextArg()) != null); 5069 } 5070 } finally { 5071 Binder.restoreCallingIdentity(token); 5072 } 5073 } else { 5074 if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) { 5075 return -1; 5076 } 5077 synchronized (this) { 5078 for (int j = 0; j < mPowerSaveWhitelistApps.size(); j++) { 5079 pw.print(mPowerSaveWhitelistApps.keyAt(j)); 5080 pw.print(","); 5081 pw.println(mPowerSaveWhitelistApps.valueAt(j)); 5082 } 5083 } 5084 } 5085 } else if ("motion".equals(cmd)) { 5086 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 5087 null); 5088 synchronized (this) { 5089 final long token = Binder.clearCallingIdentity(); 5090 try { 5091 motionLocked(); 5092 pw.print("Light state: "); 5093 pw.print(lightStateToString(mLightState)); 5094 pw.print(", deep state: "); 5095 pw.println(stateToString(mState)); 5096 } finally { 5097 Binder.restoreCallingIdentity(token); 5098 } 5099 } 5100 } else if ("pre-idle-factor".equals(cmd)) { 5101 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 5102 null); 5103 synchronized (this) { 5104 final long token = Binder.clearCallingIdentity(); 5105 int ret = SET_IDLE_FACTOR_RESULT_UNINIT; 5106 try { 5107 String arg = shell.getNextArg(); 5108 boolean valid = false; 5109 int mode = 0; 5110 if (arg != null) { 5111 mode = Integer.parseInt(arg); 5112 ret = setPreIdleTimeoutMode(mode); 5113 if (ret == SET_IDLE_FACTOR_RESULT_OK) { 5114 pw.println("pre-idle-factor: " + mode); 5115 valid = true; 5116 } else if (ret == SET_IDLE_FACTOR_RESULT_NOT_SUPPORT) { 5117 valid = true; 5118 pw.println("Deep idle not supported"); 5119 } else if (ret == SET_IDLE_FACTOR_RESULT_IGNORED) { 5120 valid = true; 5121 pw.println("Idle timeout factor not changed"); 5122 } 5123 } 5124 if (!valid) { 5125 pw.println("Unknown idle timeout factor: " + arg 5126 + ",(error code: " + ret + ")"); 5127 } 5128 } catch (NumberFormatException e) { 5129 pw.println("Unknown idle timeout factor" 5130 + ",(error code: " + ret + ")"); 5131 } finally { 5132 Binder.restoreCallingIdentity(token); 5133 } 5134 } 5135 } else if ("reset-pre-idle-factor".equals(cmd)) { 5136 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 5137 null); 5138 synchronized (this) { 5139 final long token = Binder.clearCallingIdentity(); 5140 try { 5141 resetPreIdleTimeoutMode(); 5142 } finally { 5143 Binder.restoreCallingIdentity(token); 5144 } 5145 } 5146 } else { 5147 return shell.handleDefaultCommands(cmd); 5148 } 5149 return 0; 5150 } 5151 dump(FileDescriptor fd, PrintWriter pw, String[] args)5152 void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 5153 if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return; 5154 5155 if (args != null) { 5156 int userId = UserHandle.USER_SYSTEM; 5157 for (int i=0; i<args.length; i++) { 5158 String arg = args[i]; 5159 if ("-h".equals(arg)) { 5160 dumpHelp(pw); 5161 return; 5162 } else if ("-u".equals(arg)) { 5163 i++; 5164 if (i < args.length) { 5165 arg = args[i]; 5166 userId = Integer.parseInt(arg); 5167 } 5168 } else if ("-a".equals(arg)) { 5169 // Ignore, we always dump all. 5170 } else if (arg.length() > 0 && arg.charAt(0) == '-'){ 5171 pw.println("Unknown option: " + arg); 5172 return; 5173 } else { 5174 Shell shell = new Shell(); 5175 shell.userId = userId; 5176 String[] newArgs = new String[args.length-i]; 5177 System.arraycopy(args, i, newArgs, 0, args.length-i); 5178 shell.exec(mBinderService, null, fd, null, newArgs, null, 5179 new ResultReceiver(null)); 5180 return; 5181 } 5182 } 5183 } 5184 5185 synchronized (this) { 5186 mConstants.dump(pw); 5187 5188 if (mEventCmds[0] != EVENT_NULL) { 5189 pw.println(" Idling history:"); 5190 long now = SystemClock.elapsedRealtime(); 5191 for (int i=EVENT_BUFFER_SIZE-1; i>=0; i--) { 5192 int cmd = mEventCmds[i]; 5193 if (cmd == EVENT_NULL) { 5194 continue; 5195 } 5196 String label; 5197 switch (mEventCmds[i]) { 5198 case EVENT_NORMAL: label = " normal"; break; 5199 case EVENT_LIGHT_IDLE: label = " light-idle"; break; 5200 case EVENT_LIGHT_MAINTENANCE: label = "light-maint"; break; 5201 case EVENT_DEEP_IDLE: label = " deep-idle"; break; 5202 case EVENT_DEEP_MAINTENANCE: label = " deep-maint"; break; 5203 default: label = " ??"; break; 5204 } 5205 pw.print(" "); 5206 pw.print(label); 5207 pw.print(": "); 5208 TimeUtils.formatDuration(mEventTimes[i], now, pw); 5209 if (mEventReasons[i] != null) { 5210 pw.print(" ("); 5211 pw.print(mEventReasons[i]); 5212 pw.print(")"); 5213 } 5214 pw.println(); 5215 5216 } 5217 } 5218 5219 int size = mPowerSaveWhitelistAppsExceptIdle.size(); 5220 if (size > 0) { 5221 pw.println(" Whitelist (except idle) system apps:"); 5222 for (int i = 0; i < size; i++) { 5223 pw.print(" "); 5224 pw.println(mPowerSaveWhitelistAppsExceptIdle.keyAt(i)); 5225 } 5226 } 5227 size = mPowerSaveWhitelistApps.size(); 5228 if (size > 0) { 5229 pw.println(" Whitelist system apps:"); 5230 for (int i = 0; i < size; i++) { 5231 pw.print(" "); 5232 pw.println(mPowerSaveWhitelistApps.keyAt(i)); 5233 } 5234 } 5235 size = mRemovedFromSystemWhitelistApps.size(); 5236 if (size > 0) { 5237 pw.println(" Removed from whitelist system apps:"); 5238 for (int i = 0; i < size; i++) { 5239 pw.print(" "); 5240 pw.println(mRemovedFromSystemWhitelistApps.keyAt(i)); 5241 } 5242 } 5243 size = mPowerSaveWhitelistUserApps.size(); 5244 if (size > 0) { 5245 pw.println(" Whitelist user apps:"); 5246 for (int i = 0; i < size; i++) { 5247 pw.print(" "); 5248 pw.println(mPowerSaveWhitelistUserApps.keyAt(i)); 5249 } 5250 } 5251 size = mPowerSaveWhitelistExceptIdleAppIds.size(); 5252 if (size > 0) { 5253 pw.println(" Whitelist (except idle) all app ids:"); 5254 for (int i = 0; i < size; i++) { 5255 pw.print(" "); 5256 pw.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i)); 5257 pw.println(); 5258 } 5259 } 5260 size = mPowerSaveWhitelistUserAppIds.size(); 5261 if (size > 0) { 5262 pw.println(" Whitelist user app ids:"); 5263 for (int i = 0; i < size; i++) { 5264 pw.print(" "); 5265 pw.print(mPowerSaveWhitelistUserAppIds.keyAt(i)); 5266 pw.println(); 5267 } 5268 } 5269 size = mPowerSaveWhitelistAllAppIds.size(); 5270 if (size > 0) { 5271 pw.println(" Whitelist all app ids:"); 5272 for (int i = 0; i < size; i++) { 5273 pw.print(" "); 5274 pw.print(mPowerSaveWhitelistAllAppIds.keyAt(i)); 5275 pw.println(); 5276 } 5277 } 5278 dumpTempWhitelistSchedule(pw, true); 5279 5280 size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0; 5281 if (size > 0) { 5282 pw.println(" Temp whitelist app ids:"); 5283 for (int i = 0; i < size; i++) { 5284 pw.print(" "); 5285 pw.print(mTempWhitelistAppIdArray[i]); 5286 pw.println(); 5287 } 5288 } 5289 5290 pw.print(" mLightEnabled="); pw.print(mLightEnabled); 5291 pw.print(" mDeepEnabled="); pw.println(mDeepEnabled); 5292 pw.print(" mForceIdle="); pw.println(mForceIdle); 5293 pw.print(" mUseMotionSensor="); pw.print(mUseMotionSensor); 5294 if (mUseMotionSensor) { 5295 pw.print(" mMotionSensor="); pw.println(mMotionSensor); 5296 } else { 5297 pw.println(); 5298 } 5299 pw.print(" mScreenOn="); pw.println(mScreenOn); 5300 pw.print(" mScreenLocked="); pw.println(mScreenLocked); 5301 pw.print(" mNetworkConnected="); pw.println(mNetworkConnected); 5302 pw.print(" mCharging="); pw.println(mCharging); 5303 pw.print(" activeEmergencyCall="); 5304 pw.println(mEmergencyCallListener.isEmergencyCallActive()); 5305 if (mConstraints.size() != 0) { 5306 pw.println(" mConstraints={"); 5307 for (int i = 0; i < mConstraints.size(); i++) { 5308 final DeviceIdleConstraintTracker tracker = mConstraints.valueAt(i); 5309 pw.print(" \""); pw.print(tracker.name); pw.print("\"="); 5310 if (tracker.minState == mState) { 5311 pw.println(tracker.active); 5312 } else { 5313 pw.print("ignored <mMinState="); pw.print(stateToString(tracker.minState)); 5314 pw.println(">"); 5315 } 5316 } 5317 pw.println(" }"); 5318 } 5319 if (mUseMotionSensor || mStationaryListeners.size() > 0) { 5320 pw.print(" mMotionActive="); pw.println(mMotionListener.active); 5321 pw.print(" mNotMoving="); pw.println(mNotMoving); 5322 pw.print(" mMotionListener.activatedTimeElapsed="); 5323 pw.println(mMotionListener.activatedTimeElapsed); 5324 pw.print(" mLastMotionEventElapsed="); pw.println(mLastMotionEventElapsed); 5325 pw.print(" "); pw.print(mStationaryListeners.size()); 5326 pw.println(" stationary listeners registered"); 5327 } 5328 if (mIsLocationPrefetchEnabled) { 5329 pw.print(" mLocating="); pw.print(mLocating); 5330 pw.print(" mHasGps="); pw.print(mHasGps); 5331 pw.print(" mHasFused="); pw.print(mHasFusedLocation); 5332 pw.print(" mLocated="); pw.println(mLocated); 5333 if (mLastGenericLocation != null) { 5334 pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation); 5335 } 5336 if (mLastGpsLocation != null) { 5337 pw.print(" mLastGpsLocation="); pw.println(mLastGpsLocation); 5338 } 5339 } else { 5340 pw.println(" Location prefetching disabled"); 5341 } 5342 pw.print(" mState="); pw.print(stateToString(mState)); 5343 pw.print(" mLightState="); 5344 pw.println(lightStateToString(mLightState)); 5345 pw.print(" mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw); 5346 pw.println(); 5347 if (mActiveIdleOpCount != 0) { 5348 pw.print(" mActiveIdleOpCount="); pw.println(mActiveIdleOpCount); 5349 } 5350 if (mNextAlarmTime != 0) { 5351 pw.print(" mNextAlarmTime="); 5352 TimeUtils.formatDuration(mNextAlarmTime, SystemClock.elapsedRealtime(), pw); 5353 pw.println(); 5354 } 5355 if (mNextIdlePendingDelay != 0) { 5356 pw.print(" mNextIdlePendingDelay="); 5357 TimeUtils.formatDuration(mNextIdlePendingDelay, pw); 5358 pw.println(); 5359 } 5360 if (mNextIdleDelay != 0) { 5361 pw.print(" mNextIdleDelay="); 5362 TimeUtils.formatDuration(mNextIdleDelay, pw); 5363 pw.println(); 5364 } 5365 if (mNextLightIdleDelay != 0) { 5366 pw.print(" mNextLightIdleDelay="); 5367 TimeUtils.formatDuration(mNextLightIdleDelay, pw); 5368 if (mConstants.USE_WINDOW_ALARMS) { 5369 pw.print(" (flex="); 5370 TimeUtils.formatDuration(mNextLightIdleDelayFlex, pw); 5371 pw.println(")"); 5372 } else { 5373 pw.println(); 5374 } 5375 } 5376 if (mNextLightAlarmTime != 0) { 5377 pw.print(" mNextLightAlarmTime="); 5378 TimeUtils.formatDuration(mNextLightAlarmTime, SystemClock.elapsedRealtime(), pw); 5379 pw.println(); 5380 } 5381 if (mCurLightIdleBudget != 0) { 5382 pw.print(" mCurLightIdleBudget="); 5383 TimeUtils.formatDuration(mCurLightIdleBudget, pw); 5384 pw.println(); 5385 } 5386 if (mMaintenanceStartTime != 0) { 5387 pw.print(" mMaintenanceStartTime="); 5388 TimeUtils.formatDuration(mMaintenanceStartTime, SystemClock.elapsedRealtime(), pw); 5389 pw.println(); 5390 } 5391 if (mJobsActive) { 5392 pw.print(" mJobsActive="); pw.println(mJobsActive); 5393 } 5394 if (mAlarmsActive) { 5395 pw.print(" mAlarmsActive="); pw.println(mAlarmsActive); 5396 } 5397 if (Math.abs(mPreIdleFactor - 1.0f) > MIN_PRE_IDLE_FACTOR_CHANGE) { 5398 pw.print(" mPreIdleFactor="); pw.println(mPreIdleFactor); 5399 } 5400 } 5401 } 5402 dumpTempWhitelistSchedule(PrintWriter pw, boolean printTitle)5403 void dumpTempWhitelistSchedule(PrintWriter pw, boolean printTitle) { 5404 final int size = mTempWhitelistAppIdEndTimes.size(); 5405 if (size > 0) { 5406 String prefix = ""; 5407 if (printTitle) { 5408 pw.println(" Temp whitelist schedule:"); 5409 prefix = " "; 5410 } 5411 final long timeNow = SystemClock.elapsedRealtime(); 5412 for (int i = 0; i < size; i++) { 5413 pw.print(prefix); 5414 pw.print("UID="); 5415 pw.print(mTempWhitelistAppIdEndTimes.keyAt(i)); 5416 pw.print(": "); 5417 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.valueAt(i); 5418 TimeUtils.formatDuration(entry.first.value, timeNow, pw); 5419 pw.print(" - "); 5420 pw.println(entry.second); 5421 } 5422 } 5423 } 5424 } 5425