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