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