DeviceIdleController.java revision 92f15e65d93dc15a55e756fb8f545e7c4f652457
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 17package com.android.server; 18 19import android.Manifest; 20import android.app.ActivityManagerNative; 21import android.app.AlarmManager; 22import android.content.BroadcastReceiver; 23import android.content.ContentResolver; 24import android.content.Context; 25import android.content.Intent; 26import android.content.IntentFilter; 27import android.content.pm.ApplicationInfo; 28import android.content.pm.PackageManager; 29import android.content.pm.PackageManager.NameNotFoundException; 30import android.database.ContentObserver; 31import android.hardware.Sensor; 32import android.hardware.SensorManager; 33import android.hardware.SensorEvent; 34import android.hardware.SensorEventListener; 35import android.hardware.TriggerEvent; 36import android.hardware.TriggerEventListener; 37import android.hardware.display.DisplayManager; 38import android.location.LocationRequest; 39import android.location.Location; 40import android.location.LocationListener; 41import android.location.LocationManager; 42import android.net.INetworkPolicyManager; 43import android.net.Uri; 44import android.os.BatteryStats; 45import android.os.Binder; 46import android.os.Bundle; 47import android.os.Environment; 48import android.os.FileUtils; 49import android.os.Handler; 50import android.os.IBinder; 51import android.os.IDeviceIdleController; 52import android.os.IMaintenanceActivityListener; 53import android.os.Looper; 54import android.os.Message; 55import android.os.PowerManager; 56import android.os.PowerManagerInternal; 57import android.os.Process; 58import android.os.RemoteCallbackList; 59import android.os.RemoteException; 60import android.os.ResultReceiver; 61import android.os.ServiceManager; 62import android.os.ShellCommand; 63import android.os.SystemClock; 64import android.os.UserHandle; 65import android.provider.Settings; 66import android.util.ArrayMap; 67import android.util.ArraySet; 68import android.util.KeyValueListParser; 69import android.util.MutableLong; 70import android.util.Pair; 71import android.util.Slog; 72import android.util.SparseArray; 73import android.util.SparseBooleanArray; 74import android.util.TimeUtils; 75import android.util.Xml; 76import android.view.Display; 77 78import com.android.internal.app.IBatteryStats; 79import com.android.internal.os.AtomicFile; 80import com.android.internal.os.BackgroundThread; 81import com.android.internal.util.FastXmlSerializer; 82import com.android.internal.util.XmlUtils; 83import com.android.server.am.BatteryStatsService; 84 85import org.xmlpull.v1.XmlPullParser; 86import org.xmlpull.v1.XmlPullParserException; 87import org.xmlpull.v1.XmlSerializer; 88 89import java.io.ByteArrayOutputStream; 90import java.io.File; 91import java.io.FileDescriptor; 92import java.io.FileInputStream; 93import java.io.FileNotFoundException; 94import java.io.FileOutputStream; 95import java.io.IOException; 96import java.io.PrintWriter; 97import java.nio.charset.StandardCharsets; 98import java.util.Arrays; 99 100/** 101 * Keeps track of device idleness and drives low power mode based on that. 102 */ 103public class DeviceIdleController extends SystemService 104 implements AnyMotionDetector.DeviceIdleCallback { 105 private static final String TAG = "DeviceIdleController"; 106 107 private static final boolean DEBUG = false; 108 109 private static final boolean COMPRESS_TIME = false; 110 111 private static final int EVENT_BUFFER_SIZE = 100; 112 113 private AlarmManager mAlarmManager; 114 private IBatteryStats mBatteryStats; 115 private PowerManagerInternal mLocalPowerManager; 116 private PowerManager mPowerManager; 117 private AlarmManagerService.LocalService mLocalAlarmManager; 118 private INetworkPolicyManager mNetworkPolicyManager; 119 private DisplayManager mDisplayManager; 120 private SensorManager mSensorManager; 121 private Sensor mMotionSensor; 122 private LocationManager mLocationManager; 123 private LocationRequest mLocationRequest; 124 private Intent mIdleIntent; 125 private Intent mLightIdleIntent; 126 private Display mCurDisplay; 127 private AnyMotionDetector mAnyMotionDetector; 128 private boolean mLightEnabled; 129 private boolean mDeepEnabled; 130 private boolean mForceIdle; 131 private boolean mScreenOn; 132 private boolean mCharging; 133 private boolean mNotMoving; 134 private boolean mLocating; 135 private boolean mLocated; 136 private boolean mHasGps; 137 private boolean mHasNetworkLocation; 138 private Location mLastGenericLocation; 139 private Location mLastGpsLocation; 140 141 /** Device is currently active. */ 142 private static final int STATE_ACTIVE = 0; 143 /** Device is inactive (screen off, no motion) and we are waiting to for idle. */ 144 private static final int STATE_INACTIVE = 1; 145 /** Device is past the initial inactive period, and waiting for the next idle period. */ 146 private static final int STATE_IDLE_PENDING = 2; 147 /** Device is currently sensing motion. */ 148 private static final int STATE_SENSING = 3; 149 /** Device is currently finding location (and may still be sensing). */ 150 private static final int STATE_LOCATING = 4; 151 /** Device is in the idle state, trying to stay asleep as much as possible. */ 152 private static final int STATE_IDLE = 5; 153 /** Device is in the idle state, but temporarily out of idle to do regular maintenance. */ 154 private static final int STATE_IDLE_MAINTENANCE = 6; 155 private static String stateToString(int state) { 156 switch (state) { 157 case STATE_ACTIVE: return "ACTIVE"; 158 case STATE_INACTIVE: return "INACTIVE"; 159 case STATE_IDLE_PENDING: return "IDLE_PENDING"; 160 case STATE_SENSING: return "SENSING"; 161 case STATE_LOCATING: return "LOCATING"; 162 case STATE_IDLE: return "IDLE"; 163 case STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE"; 164 default: return Integer.toString(state); 165 } 166 } 167 168 /** Device is currently active. */ 169 private static final int LIGHT_STATE_ACTIVE = 0; 170 /** Device is inactive (screen off) and we are waiting to for the first light idle. */ 171 private static final int LIGHT_STATE_INACTIVE = 1; 172 /** Device is about to go idle for the first time, wait for current work to complete. */ 173 private static final int LIGHT_STATE_PRE_IDLE = 3; 174 /** Device is in the light idle state, trying to stay asleep as much as possible. */ 175 private static final int LIGHT_STATE_IDLE = 4; 176 /** Device is in the light idle state, but temporarily out of idle to do regular maintenance. */ 177 private static final int LIGHT_STATE_IDLE_MAINTENANCE = 5; 178 /** Device light idle state is overriden, now applying deep doze state. */ 179 private static final int LIGHT_STATE_OVERRIDE = 6; 180 private static String lightStateToString(int state) { 181 switch (state) { 182 case LIGHT_STATE_ACTIVE: return "ACTIVE"; 183 case LIGHT_STATE_INACTIVE: return "INACTIVE"; 184 case LIGHT_STATE_PRE_IDLE: return "PRE_IDLE"; 185 case LIGHT_STATE_IDLE: return "IDLE"; 186 case LIGHT_STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE"; 187 case LIGHT_STATE_OVERRIDE: return "OVERRIDE"; 188 default: return Integer.toString(state); 189 } 190 } 191 192 private int mState; 193 private int mLightState; 194 195 private long mInactiveTimeout; 196 private long mNextAlarmTime; 197 private long mNextIdlePendingDelay; 198 private long mNextIdleDelay; 199 private long mNextLightIdleDelay; 200 private long mNextLightAlarmTime; 201 private long mNextSensingTimeoutAlarmTime; 202 private long mCurIdleBudget; 203 private long mMaintenanceStartTime; 204 205 private int mActiveIdleOpCount; 206 private PowerManager.WakeLock mActiveIdleWakeLock; 207 private IBinder mDownloadServiceActive; 208 private boolean mJobsActive; 209 private boolean mAlarmsActive; 210 private boolean mReportedMaintenanceActivity; 211 212 public final AtomicFile mConfigFile; 213 214 private final RemoteCallbackList<IMaintenanceActivityListener> mMaintenanceActivityListeners = 215 new RemoteCallbackList<IMaintenanceActivityListener>(); 216 217 /** 218 * Package names the system has white-listed to opt out of power save restrictions, 219 * except for device idle mode. 220 */ 221 private final ArrayMap<String, Integer> mPowerSaveWhitelistAppsExceptIdle = new ArrayMap<>(); 222 223 /** 224 * Package names the system has white-listed to opt out of power save restrictions for 225 * all modes. 226 */ 227 private final ArrayMap<String, Integer> mPowerSaveWhitelistApps = new ArrayMap<>(); 228 229 /** 230 * Package names the user has white-listed to opt out of power save restrictions. 231 */ 232 private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>(); 233 234 /** 235 * App IDs of built-in system apps that have been white-listed except for idle modes. 236 */ 237 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIdsExceptIdle 238 = new SparseBooleanArray(); 239 240 /** 241 * App IDs of built-in system apps that have been white-listed. 242 */ 243 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray(); 244 245 /** 246 * App IDs that have been white-listed to opt out of power save restrictions, except 247 * for device idle modes. 248 */ 249 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray(); 250 251 /** 252 * Current app IDs that are in the complete power save white list, but shouldn't be 253 * excluded from idle modes. This array can be shared with others because it will not be 254 * modified once set. 255 */ 256 private int[] mPowerSaveWhitelistExceptIdleAppIdArray = new int[0]; 257 258 /** 259 * App IDs that have been white-listed to opt out of power save restrictions. 260 */ 261 private final SparseBooleanArray mPowerSaveWhitelistAllAppIds = new SparseBooleanArray(); 262 263 /** 264 * Current app IDs that are in the complete power save white list. This array can 265 * be shared with others because it will not be modified once set. 266 */ 267 private int[] mPowerSaveWhitelistAllAppIdArray = new int[0]; 268 269 /** 270 * App IDs that have been white-listed by the user to opt out of power save restrictions. 271 */ 272 private final SparseBooleanArray mPowerSaveWhitelistUserAppIds = new SparseBooleanArray(); 273 274 /** 275 * Current app IDs that are in the user power save white list. This array can 276 * be shared with others because it will not be modified once set. 277 */ 278 private int[] mPowerSaveWhitelistUserAppIdArray = new int[0]; 279 280 /** 281 * List of end times for UIDs that are temporarily marked as being allowed to access 282 * the network and acquire wakelocks. Times are in milliseconds. 283 */ 284 private final SparseArray<Pair<MutableLong, String>> mTempWhitelistAppIdEndTimes 285 = new SparseArray<>(); 286 287 /** 288 * Callback to the NetworkPolicyManagerService to tell it that the temp whitelist has changed. 289 */ 290 Runnable mNetworkPolicyTempWhitelistCallback; 291 292 /** 293 * Current app IDs of temporarily whitelist apps for high-priority messages. 294 */ 295 private int[] mTempWhitelistAppIdArray = new int[0]; 296 297 private static final int EVENT_NULL = 0; 298 private static final int EVENT_NORMAL = 1; 299 private static final int EVENT_LIGHT_IDLE = 2; 300 private static final int EVENT_LIGHT_MAINTENANCE = 3; 301 private static final int EVENT_DEEP_IDLE = 4; 302 private static final int EVENT_DEEP_MAINTENANCE = 5; 303 304 private int[] mEventCmds = new int[EVENT_BUFFER_SIZE]; 305 private long[] mEventTimes = new long[EVENT_BUFFER_SIZE]; 306 307 private void addEvent(int cmd) { 308 if (mEventCmds[0] != cmd) { 309 System.arraycopy(mEventCmds, 0, mEventCmds, 1, EVENT_BUFFER_SIZE - 1); 310 System.arraycopy(mEventTimes, 0, mEventTimes, 1, EVENT_BUFFER_SIZE - 1); 311 mEventCmds[0] = cmd; 312 mEventTimes[0] = SystemClock.elapsedRealtime(); 313 } 314 } 315 316 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 317 @Override public void onReceive(Context context, Intent intent) { 318 if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) { 319 int plugged = intent.getIntExtra("plugged", 0); 320 updateChargingLocked(plugged != 0); 321 } else if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 322 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 323 Uri data = intent.getData(); 324 String ssp; 325 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 326 removePowerSaveWhitelistAppInternal(ssp); 327 } 328 } 329 } 330 } 331 }; 332 333 private final AlarmManager.OnAlarmListener mLightAlarmListener 334 = new AlarmManager.OnAlarmListener() { 335 @Override 336 public void onAlarm() { 337 synchronized (DeviceIdleController.this) { 338 stepLightIdleStateLocked("s:alarm"); 339 } 340 } 341 }; 342 343 private final AlarmManager.OnAlarmListener mSensingTimeoutAlarmListener 344 = new AlarmManager.OnAlarmListener() { 345 @Override 346 public void onAlarm() { 347 if (mState == STATE_SENSING) { 348 synchronized (DeviceIdleController.this) { 349 becomeInactiveIfAppropriateLocked(); 350 } 351 } 352 } 353 }; 354 355 private final AlarmManager.OnAlarmListener mDeepAlarmListener 356 = new AlarmManager.OnAlarmListener() { 357 @Override 358 public void onAlarm() { 359 synchronized (DeviceIdleController.this) { 360 stepIdleStateLocked("s:alarm"); 361 } 362 } 363 }; 364 365 private final BroadcastReceiver mIdleStartedDoneReceiver = new BroadcastReceiver() { 366 @Override public void onReceive(Context context, Intent intent) { 367 // When coming out of a deep idle, we will add in some delay before we allow 368 // the system to settle down and finish the maintenance window. This is 369 // to give a chance for any pending work to be scheduled. 370 if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(intent.getAction())) { 371 mHandler.sendEmptyMessageDelayed(MSG_FINISH_IDLE_OP, 372 mConstants.MIN_DEEP_MAINTENANCE_TIME); 373 } else { 374 mHandler.sendEmptyMessageDelayed(MSG_FINISH_IDLE_OP, 375 mConstants.MIN_LIGHT_MAINTENANCE_TIME); 376 } 377 } 378 }; 379 380 private final DisplayManager.DisplayListener mDisplayListener 381 = new DisplayManager.DisplayListener() { 382 @Override public void onDisplayAdded(int displayId) { 383 } 384 385 @Override public void onDisplayRemoved(int displayId) { 386 } 387 388 @Override public void onDisplayChanged(int displayId) { 389 if (displayId == Display.DEFAULT_DISPLAY) { 390 synchronized (DeviceIdleController.this) { 391 updateDisplayLocked(); 392 } 393 } 394 } 395 }; 396 397 private final class MotionListener extends TriggerEventListener 398 implements SensorEventListener { 399 400 boolean active = false; 401 402 @Override 403 public void onTrigger(TriggerEvent event) { 404 synchronized (DeviceIdleController.this) { 405 active = false; 406 motionLocked(); 407 } 408 } 409 410 @Override 411 public void onSensorChanged(SensorEvent event) { 412 synchronized (DeviceIdleController.this) { 413 mSensorManager.unregisterListener(this, mMotionSensor); 414 active = false; 415 motionLocked(); 416 } 417 } 418 419 @Override 420 public void onAccuracyChanged(Sensor sensor, int accuracy) {} 421 422 public boolean registerLocked() { 423 boolean success; 424 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) { 425 success = mSensorManager.requestTriggerSensor(mMotionListener, mMotionSensor); 426 } else { 427 success = mSensorManager.registerListener( 428 mMotionListener, mMotionSensor, SensorManager.SENSOR_DELAY_NORMAL); 429 } 430 if (success) { 431 active = true; 432 } else { 433 Slog.e(TAG, "Unable to register for " + mMotionSensor); 434 } 435 return success; 436 } 437 438 public void unregisterLocked() { 439 if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) { 440 mSensorManager.cancelTriggerSensor(mMotionListener, mMotionSensor); 441 } else { 442 mSensorManager.unregisterListener(mMotionListener); 443 } 444 active = false; 445 } 446 } 447 private final MotionListener mMotionListener = new MotionListener(); 448 449 private final LocationListener mGenericLocationListener = new LocationListener() { 450 @Override 451 public void onLocationChanged(Location location) { 452 synchronized (DeviceIdleController.this) { 453 receivedGenericLocationLocked(location); 454 } 455 } 456 457 @Override 458 public void onStatusChanged(String provider, int status, Bundle extras) { 459 } 460 461 @Override 462 public void onProviderEnabled(String provider) { 463 } 464 465 @Override 466 public void onProviderDisabled(String provider) { 467 } 468 }; 469 470 private final LocationListener mGpsLocationListener = new LocationListener() { 471 @Override 472 public void onLocationChanged(Location location) { 473 synchronized (DeviceIdleController.this) { 474 receivedGpsLocationLocked(location); 475 } 476 } 477 478 @Override 479 public void onStatusChanged(String provider, int status, Bundle extras) { 480 } 481 482 @Override 483 public void onProviderEnabled(String provider) { 484 } 485 486 @Override 487 public void onProviderDisabled(String provider) { 488 } 489 }; 490 491 /** 492 * All times are in milliseconds. These constants are kept synchronized with the system 493 * global Settings. Any access to this class or its fields should be done while 494 * holding the DeviceIdleController lock. 495 */ 496 private final class Constants extends ContentObserver { 497 // Key names stored in the settings value. 498 private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT 499 = "light_after_inactive_to"; 500 private static final String KEY_LIGHT_PRE_IDLE_TIMEOUT = "light_pre_idle_to"; 501 private static final String KEY_LIGHT_IDLE_TIMEOUT = "light_idle_to"; 502 private static final String KEY_LIGHT_IDLE_FACTOR = "light_idle_factor"; 503 private static final String KEY_LIGHT_MAX_IDLE_TIMEOUT = "light_max_idle_to"; 504 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET 505 = "light_idle_maintenance_min_budget"; 506 private static final String KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET 507 = "light_idle_maintenance_max_budget"; 508 private static final String KEY_MIN_LIGHT_MAINTENANCE_TIME = "min_light_maintenance_time"; 509 private static final String KEY_MIN_DEEP_MAINTENANCE_TIME = "min_deep_maintenance_time"; 510 private static final String KEY_INACTIVE_TIMEOUT = "inactive_to"; 511 private static final String KEY_SENSING_TIMEOUT = "sensing_to"; 512 private static final String KEY_LOCATING_TIMEOUT = "locating_to"; 513 private static final String KEY_LOCATION_ACCURACY = "location_accuracy"; 514 private static final String KEY_MOTION_INACTIVE_TIMEOUT = "motion_inactive_to"; 515 private static final String KEY_IDLE_AFTER_INACTIVE_TIMEOUT = "idle_after_inactive_to"; 516 private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to"; 517 private static final String KEY_MAX_IDLE_PENDING_TIMEOUT = "max_idle_pending_to"; 518 private static final String KEY_IDLE_PENDING_FACTOR = "idle_pending_factor"; 519 private static final String KEY_IDLE_TIMEOUT = "idle_to"; 520 private static final String KEY_MAX_IDLE_TIMEOUT = "max_idle_to"; 521 private static final String KEY_IDLE_FACTOR = "idle_factor"; 522 private static final String KEY_MIN_TIME_TO_ALARM = "min_time_to_alarm"; 523 private static final String KEY_MAX_TEMP_APP_WHITELIST_DURATION = 524 "max_temp_app_whitelist_duration"; 525 private static final String KEY_MMS_TEMP_APP_WHITELIST_DURATION = 526 "mms_temp_app_whitelist_duration"; 527 private static final String KEY_SMS_TEMP_APP_WHITELIST_DURATION = 528 "sms_temp_app_whitelist_duration"; 529 530 /** 531 * This is the time, after becoming inactive, that we go in to the first 532 * light-weight idle mode. 533 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 534 * @see #KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT 535 */ 536 public long LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT; 537 538 /** 539 * This is amount of time we will wait from the point where we decide we would 540 * like to go idle until we actually do, while waiting for jobs and other current 541 * activity to finish. 542 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 543 * @see #KEY_LIGHT_PRE_IDLE_TIMEOUT 544 */ 545 public long LIGHT_PRE_IDLE_TIMEOUT; 546 547 /** 548 * This is the initial time that we will run in idle maintenance mode. 549 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 550 * @see #KEY_LIGHT_IDLE_TIMEOUT 551 */ 552 public long LIGHT_IDLE_TIMEOUT; 553 554 /** 555 * Scaling factor to apply to the light idle mode time each time we complete a cycle. 556 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 557 * @see #KEY_LIGHT_IDLE_FACTOR 558 */ 559 public float LIGHT_IDLE_FACTOR; 560 561 /** 562 * This is the maximum time we will run in idle maintenence mode. 563 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 564 * @see #KEY_LIGHT_MAX_IDLE_TIMEOUT 565 */ 566 public long LIGHT_MAX_IDLE_TIMEOUT; 567 568 /** 569 * This is the minimum amount of time we want to make available for maintenance mode 570 * when lightly idling. That is, we will always have at least this amount of time 571 * available maintenance before timing out and cutting off maintenance mode. 572 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 573 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET 574 */ 575 public long LIGHT_IDLE_MAINTENANCE_MIN_BUDGET; 576 577 /** 578 * This is the maximum amount of time we want to make available for maintenance mode 579 * when lightly idling. That is, if the system isn't using up its minimum maintenance 580 * budget and this time is being added to the budget reserve, this is the maximum 581 * reserve size we will allow to grow and thus the maximum amount of time we will 582 * allow for the maintenance window. 583 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 584 * @see #KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET 585 */ 586 public long LIGHT_IDLE_MAINTENANCE_MAX_BUDGET; 587 588 /** 589 * This is the minimum amount of time that we will stay in maintenance mode after 590 * a light doze. We have this minimum to allow various things to respond to switching 591 * in to maintenance mode and scheduling their work -- otherwise we may 592 * see there is nothing to do (no jobs or downloads pending) and go out of maintenance 593 * mode immediately. 594 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 595 * @see #KEY_MIN_LIGHT_MAINTENANCE_TIME 596 */ 597 public long MIN_LIGHT_MAINTENANCE_TIME; 598 599 /** 600 * This is the minimum amount of time that we will stay in maintenance mode after 601 * a full doze. We have this minimum to allow various things to respond to switching 602 * in to maintenance mode and scheduling their work -- otherwise we may 603 * see there is nothing to do (no jobs or downloads pending) and go out of maintenance 604 * mode immediately. 605 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 606 * @see #KEY_MIN_DEEP_MAINTENANCE_TIME 607 */ 608 public long MIN_DEEP_MAINTENANCE_TIME; 609 610 /** 611 * This is the time, after becoming inactive, at which we start looking at the 612 * motion sensor to determine if the device is being left alone. We don't do this 613 * immediately after going inactive just because we don't want to be continually running 614 * the motion sensor whenever the screen is off. 615 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 616 * @see #KEY_INACTIVE_TIMEOUT 617 */ 618 public long INACTIVE_TIMEOUT; 619 620 /** 621 * If we don't receive a callback from AnyMotion in this amount of time + 622 * {@link #LOCATING_TIMEOUT}, we will change from 623 * STATE_SENSING to STATE_INACTIVE, and any AnyMotion callbacks while not in STATE_SENSING 624 * will be ignored. 625 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 626 * @see #KEY_SENSING_TIMEOUT 627 */ 628 public long SENSING_TIMEOUT; 629 630 /** 631 * This is how long we will wait to try to get a good location fix before going in to 632 * idle mode. 633 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 634 * @see #KEY_LOCATING_TIMEOUT 635 */ 636 public long LOCATING_TIMEOUT; 637 638 /** 639 * The desired maximum accuracy (in meters) we consider the location to be good enough to go 640 * on to idle. We will be trying to get an accuracy fix at least this good or until 641 * {@link #LOCATING_TIMEOUT} expires. 642 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 643 * @see #KEY_LOCATION_ACCURACY 644 */ 645 public float LOCATION_ACCURACY; 646 647 /** 648 * This is the time, after seeing motion, that we wait after becoming inactive from 649 * that until we start looking for motion again. 650 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 651 * @see #KEY_MOTION_INACTIVE_TIMEOUT 652 */ 653 public long MOTION_INACTIVE_TIMEOUT; 654 655 /** 656 * This is the time, after the inactive timeout elapses, that we will wait looking 657 * for motion until we truly consider the device to be idle. 658 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 659 * @see #KEY_IDLE_AFTER_INACTIVE_TIMEOUT 660 */ 661 public long IDLE_AFTER_INACTIVE_TIMEOUT; 662 663 /** 664 * This is the initial time, after being idle, that we will allow ourself to be back 665 * in the IDLE_MAINTENANCE state allowing the system to run normally until we return to 666 * idle. 667 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 668 * @see #KEY_IDLE_PENDING_TIMEOUT 669 */ 670 public long IDLE_PENDING_TIMEOUT; 671 672 /** 673 * Maximum pending idle timeout (time spent running) we will be allowed to use. 674 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 675 * @see #KEY_MAX_IDLE_PENDING_TIMEOUT 676 */ 677 public long MAX_IDLE_PENDING_TIMEOUT; 678 679 /** 680 * Scaling factor to apply to current pending idle timeout each time we cycle through 681 * that state. 682 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 683 * @see #KEY_IDLE_PENDING_FACTOR 684 */ 685 public float IDLE_PENDING_FACTOR; 686 687 /** 688 * This is the initial time that we want to sit in the idle state before waking up 689 * again to return to pending idle and allowing normal work to run. 690 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 691 * @see #KEY_IDLE_TIMEOUT 692 */ 693 public long IDLE_TIMEOUT; 694 695 /** 696 * Maximum idle duration we will be allowed to use. 697 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 698 * @see #KEY_MAX_IDLE_TIMEOUT 699 */ 700 public long MAX_IDLE_TIMEOUT; 701 702 /** 703 * Scaling factor to apply to current idle timeout each time we cycle through that state. 704 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 705 * @see #KEY_IDLE_FACTOR 706 */ 707 public float IDLE_FACTOR; 708 709 /** 710 * This is the minimum time we will allow until the next upcoming alarm for us to 711 * actually go in to idle mode. 712 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 713 * @see #KEY_MIN_TIME_TO_ALARM 714 */ 715 public long MIN_TIME_TO_ALARM; 716 717 /** 718 * Max amount of time to temporarily whitelist an app when it receives a high priority 719 * tickle. 720 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 721 * @see #KEY_MAX_TEMP_APP_WHITELIST_DURATION 722 */ 723 public long MAX_TEMP_APP_WHITELIST_DURATION; 724 725 /** 726 * Amount of time we would like to whitelist an app that is receiving an MMS. 727 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 728 * @see #KEY_MMS_TEMP_APP_WHITELIST_DURATION 729 */ 730 public long MMS_TEMP_APP_WHITELIST_DURATION; 731 732 /** 733 * Amount of time we would like to whitelist an app that is receiving an SMS. 734 * @see Settings.Global#DEVICE_IDLE_CONSTANTS 735 * @see #KEY_SMS_TEMP_APP_WHITELIST_DURATION 736 */ 737 public long SMS_TEMP_APP_WHITELIST_DURATION; 738 739 private final ContentResolver mResolver; 740 private final boolean mHasWatch; 741 private final KeyValueListParser mParser = new KeyValueListParser(','); 742 743 public Constants(Handler handler, ContentResolver resolver) { 744 super(handler); 745 mResolver = resolver; 746 mHasWatch = getContext().getPackageManager().hasSystemFeature( 747 PackageManager.FEATURE_WATCH); 748 mResolver.registerContentObserver(Settings.Global.getUriFor( 749 mHasWatch ? Settings.Global.DEVICE_IDLE_CONSTANTS_WATCH 750 : Settings.Global.DEVICE_IDLE_CONSTANTS), 751 false, this); 752 updateConstants(); 753 } 754 755 @Override 756 public void onChange(boolean selfChange, Uri uri) { 757 updateConstants(); 758 } 759 760 private void updateConstants() { 761 synchronized (DeviceIdleController.this) { 762 try { 763 mParser.setString(Settings.Global.getString(mResolver, 764 mHasWatch ? Settings.Global.DEVICE_IDLE_CONSTANTS_WATCH 765 : Settings.Global.DEVICE_IDLE_CONSTANTS)); 766 } catch (IllegalArgumentException e) { 767 // Failed to parse the settings string, log this and move on 768 // with defaults. 769 Slog.e(TAG, "Bad device idle settings", e); 770 } 771 772 LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getLong( 773 KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT, 774 !COMPRESS_TIME ? 5 * 60 * 1000L : 15 * 1000L); 775 LIGHT_PRE_IDLE_TIMEOUT = mParser.getLong(KEY_LIGHT_PRE_IDLE_TIMEOUT, 776 !COMPRESS_TIME ? 10 * 60 * 1000L : 30 * 1000L); 777 LIGHT_IDLE_TIMEOUT = mParser.getLong(KEY_LIGHT_IDLE_TIMEOUT, 778 !COMPRESS_TIME ? 5 * 60 * 1000L : 15 * 1000L); 779 LIGHT_IDLE_FACTOR = mParser.getFloat(KEY_LIGHT_IDLE_FACTOR, 780 2f); 781 LIGHT_MAX_IDLE_TIMEOUT = mParser.getLong(KEY_LIGHT_MAX_IDLE_TIMEOUT, 782 !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L); 783 LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = mParser.getLong( 784 KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET, 785 !COMPRESS_TIME ? 1 * 60 * 1000L : 15 * 1000L); 786 LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = mParser.getLong( 787 KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET, 788 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L); 789 MIN_LIGHT_MAINTENANCE_TIME = mParser.getLong( 790 KEY_MIN_LIGHT_MAINTENANCE_TIME, 791 !COMPRESS_TIME ? 5 * 1000L : 1 * 1000L); 792 MIN_DEEP_MAINTENANCE_TIME = mParser.getLong( 793 KEY_MIN_DEEP_MAINTENANCE_TIME, 794 !COMPRESS_TIME ? 30 * 1000L : 5 * 1000L); 795 long inactiveTimeoutDefault = (mHasWatch ? 15 : 30) * 60 * 1000L; 796 INACTIVE_TIMEOUT = mParser.getLong(KEY_INACTIVE_TIMEOUT, 797 !COMPRESS_TIME ? inactiveTimeoutDefault : (inactiveTimeoutDefault / 10)); 798 SENSING_TIMEOUT = mParser.getLong(KEY_SENSING_TIMEOUT, 799 !DEBUG ? 4 * 60 * 1000L : 60 * 1000L); 800 LOCATING_TIMEOUT = mParser.getLong(KEY_LOCATING_TIMEOUT, 801 !DEBUG ? 30 * 1000L : 15 * 1000L); 802 LOCATION_ACCURACY = mParser.getFloat(KEY_LOCATION_ACCURACY, 20); 803 MOTION_INACTIVE_TIMEOUT = mParser.getLong(KEY_MOTION_INACTIVE_TIMEOUT, 804 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L); 805 long idleAfterInactiveTimeout = (mHasWatch ? 15 : 30) * 60 * 1000L; 806 IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getLong(KEY_IDLE_AFTER_INACTIVE_TIMEOUT, 807 !COMPRESS_TIME ? idleAfterInactiveTimeout 808 : (idleAfterInactiveTimeout / 10)); 809 IDLE_PENDING_TIMEOUT = mParser.getLong(KEY_IDLE_PENDING_TIMEOUT, 810 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L); 811 MAX_IDLE_PENDING_TIMEOUT = mParser.getLong(KEY_MAX_IDLE_PENDING_TIMEOUT, 812 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L); 813 IDLE_PENDING_FACTOR = mParser.getFloat(KEY_IDLE_PENDING_FACTOR, 814 2f); 815 IDLE_TIMEOUT = mParser.getLong(KEY_IDLE_TIMEOUT, 816 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L); 817 MAX_IDLE_TIMEOUT = mParser.getLong(KEY_MAX_IDLE_TIMEOUT, 818 !COMPRESS_TIME ? 6 * 60 * 60 * 1000L : 30 * 60 * 1000L); 819 IDLE_FACTOR = mParser.getFloat(KEY_IDLE_FACTOR, 820 2f); 821 MIN_TIME_TO_ALARM = mParser.getLong(KEY_MIN_TIME_TO_ALARM, 822 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L); 823 MAX_TEMP_APP_WHITELIST_DURATION = mParser.getLong( 824 KEY_MAX_TEMP_APP_WHITELIST_DURATION, 5 * 60 * 1000L); 825 MMS_TEMP_APP_WHITELIST_DURATION = mParser.getLong( 826 KEY_MMS_TEMP_APP_WHITELIST_DURATION, 60 * 1000L); 827 SMS_TEMP_APP_WHITELIST_DURATION = mParser.getLong( 828 KEY_SMS_TEMP_APP_WHITELIST_DURATION, 20 * 1000L); 829 } 830 } 831 832 void dump(PrintWriter pw) { 833 pw.println(" Settings:"); 834 835 pw.print(" "); pw.print(KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("="); 836 TimeUtils.formatDuration(LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT, pw); 837 pw.println(); 838 839 pw.print(" "); pw.print(KEY_LIGHT_PRE_IDLE_TIMEOUT); pw.print("="); 840 TimeUtils.formatDuration(LIGHT_PRE_IDLE_TIMEOUT, pw); 841 pw.println(); 842 843 pw.print(" "); pw.print(KEY_LIGHT_IDLE_TIMEOUT); pw.print("="); 844 TimeUtils.formatDuration(LIGHT_IDLE_TIMEOUT, pw); 845 pw.println(); 846 847 pw.print(" "); pw.print(KEY_LIGHT_IDLE_FACTOR); pw.print("="); 848 pw.print(LIGHT_IDLE_FACTOR); 849 pw.println(); 850 851 pw.print(" "); pw.print(KEY_LIGHT_MAX_IDLE_TIMEOUT); pw.print("="); 852 TimeUtils.formatDuration(LIGHT_MAX_IDLE_TIMEOUT, pw); 853 pw.println(); 854 855 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET); pw.print("="); 856 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MIN_BUDGET, pw); 857 pw.println(); 858 859 pw.print(" "); pw.print(KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET); pw.print("="); 860 TimeUtils.formatDuration(LIGHT_IDLE_MAINTENANCE_MAX_BUDGET, pw); 861 pw.println(); 862 863 pw.print(" "); pw.print(KEY_MIN_LIGHT_MAINTENANCE_TIME); pw.print("="); 864 TimeUtils.formatDuration(MIN_LIGHT_MAINTENANCE_TIME, pw); 865 pw.println(); 866 867 pw.print(" "); pw.print(KEY_MIN_DEEP_MAINTENANCE_TIME); pw.print("="); 868 TimeUtils.formatDuration(MIN_DEEP_MAINTENANCE_TIME, pw); 869 pw.println(); 870 871 pw.print(" "); pw.print(KEY_INACTIVE_TIMEOUT); pw.print("="); 872 TimeUtils.formatDuration(INACTIVE_TIMEOUT, pw); 873 pw.println(); 874 875 pw.print(" "); pw.print(KEY_SENSING_TIMEOUT); pw.print("="); 876 TimeUtils.formatDuration(SENSING_TIMEOUT, pw); 877 pw.println(); 878 879 pw.print(" "); pw.print(KEY_LOCATING_TIMEOUT); pw.print("="); 880 TimeUtils.formatDuration(LOCATING_TIMEOUT, pw); 881 pw.println(); 882 883 pw.print(" "); pw.print(KEY_LOCATION_ACCURACY); pw.print("="); 884 pw.print(LOCATION_ACCURACY); pw.print("m"); 885 pw.println(); 886 887 pw.print(" "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT); pw.print("="); 888 TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT, pw); 889 pw.println(); 890 891 pw.print(" "); pw.print(KEY_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("="); 892 TimeUtils.formatDuration(IDLE_AFTER_INACTIVE_TIMEOUT, pw); 893 pw.println(); 894 895 pw.print(" "); pw.print(KEY_IDLE_PENDING_TIMEOUT); pw.print("="); 896 TimeUtils.formatDuration(IDLE_PENDING_TIMEOUT, pw); 897 pw.println(); 898 899 pw.print(" "); pw.print(KEY_MAX_IDLE_PENDING_TIMEOUT); pw.print("="); 900 TimeUtils.formatDuration(MAX_IDLE_PENDING_TIMEOUT, pw); 901 pw.println(); 902 903 pw.print(" "); pw.print(KEY_IDLE_PENDING_FACTOR); pw.print("="); 904 pw.println(IDLE_PENDING_FACTOR); 905 906 pw.print(" "); pw.print(KEY_IDLE_TIMEOUT); pw.print("="); 907 TimeUtils.formatDuration(IDLE_TIMEOUT, pw); 908 pw.println(); 909 910 pw.print(" "); pw.print(KEY_MAX_IDLE_TIMEOUT); pw.print("="); 911 TimeUtils.formatDuration(MAX_IDLE_TIMEOUT, pw); 912 pw.println(); 913 914 pw.print(" "); pw.print(KEY_IDLE_FACTOR); pw.print("="); 915 pw.println(IDLE_FACTOR); 916 917 pw.print(" "); pw.print(KEY_MIN_TIME_TO_ALARM); pw.print("="); 918 TimeUtils.formatDuration(MIN_TIME_TO_ALARM, pw); 919 pw.println(); 920 921 pw.print(" "); pw.print(KEY_MAX_TEMP_APP_WHITELIST_DURATION); pw.print("="); 922 TimeUtils.formatDuration(MAX_TEMP_APP_WHITELIST_DURATION, pw); 923 pw.println(); 924 925 pw.print(" "); pw.print(KEY_MMS_TEMP_APP_WHITELIST_DURATION); pw.print("="); 926 TimeUtils.formatDuration(MMS_TEMP_APP_WHITELIST_DURATION, pw); 927 pw.println(); 928 929 pw.print(" "); pw.print(KEY_SMS_TEMP_APP_WHITELIST_DURATION); pw.print("="); 930 TimeUtils.formatDuration(SMS_TEMP_APP_WHITELIST_DURATION, pw); 931 pw.println(); 932 } 933 } 934 935 private Constants mConstants; 936 937 @Override 938 public void onAnyMotionResult(int result) { 939 if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")"); 940 if (result != AnyMotionDetector.RESULT_UNKNOWN) { 941 synchronized (this) { 942 cancelSensingTimeoutAlarmLocked(); 943 } 944 } 945 if (result == AnyMotionDetector.RESULT_MOVED) { 946 if (DEBUG) Slog.d(TAG, "RESULT_MOVED received."); 947 synchronized (this) { 948 handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "sense_motion"); 949 } 950 } else if (result == AnyMotionDetector.RESULT_STATIONARY) { 951 if (DEBUG) Slog.d(TAG, "RESULT_STATIONARY received."); 952 if (mState == STATE_SENSING) { 953 // If we are currently sensing, it is time to move to locating. 954 synchronized (this) { 955 mNotMoving = true; 956 stepIdleStateLocked("s:stationary"); 957 } 958 } else if (mState == STATE_LOCATING) { 959 // If we are currently locating, note that we are not moving and step 960 // if we have located the position. 961 synchronized (this) { 962 mNotMoving = true; 963 if (mLocated) { 964 stepIdleStateLocked("s:stationary"); 965 } 966 } 967 } 968 } 969 } 970 971 static final int MSG_WRITE_CONFIG = 1; 972 static final int MSG_REPORT_IDLE_ON = 2; 973 static final int MSG_REPORT_IDLE_ON_LIGHT = 3; 974 static final int MSG_REPORT_IDLE_OFF = 4; 975 static final int MSG_REPORT_ACTIVE = 5; 976 static final int MSG_TEMP_APP_WHITELIST_TIMEOUT = 6; 977 static final int MSG_REPORT_MAINTENANCE_ACTIVITY = 7; 978 static final int MSG_FINISH_IDLE_OP = 8; 979 980 final class MyHandler extends Handler { 981 MyHandler(Looper looper) { 982 super(looper); 983 } 984 985 @Override public void handleMessage(Message msg) { 986 if (DEBUG) Slog.d(TAG, "handleMessage(" + msg.what + ")"); 987 switch (msg.what) { 988 case MSG_WRITE_CONFIG: { 989 handleWriteConfigFile(); 990 } break; 991 case MSG_REPORT_IDLE_ON: 992 case MSG_REPORT_IDLE_ON_LIGHT: { 993 EventLogTags.writeDeviceIdleOnStart(); 994 final boolean deepChanged; 995 final boolean lightChanged; 996 if (msg.what == MSG_REPORT_IDLE_ON) { 997 deepChanged = mLocalPowerManager.setDeviceIdleMode(true); 998 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false); 999 } else { 1000 deepChanged = mLocalPowerManager.setDeviceIdleMode(false); 1001 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(true); 1002 } 1003 try { 1004 mNetworkPolicyManager.setDeviceIdleMode(true); 1005 mBatteryStats.noteDeviceIdleMode(msg.what == MSG_REPORT_IDLE_ON 1006 ? BatteryStats.DEVICE_IDLE_MODE_DEEP 1007 : BatteryStats.DEVICE_IDLE_MODE_LIGHT, null, Process.myUid()); 1008 } catch (RemoteException e) { 1009 } 1010 if (deepChanged) { 1011 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL); 1012 } 1013 if (lightChanged) { 1014 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL); 1015 } 1016 EventLogTags.writeDeviceIdleOnComplete(); 1017 } break; 1018 case MSG_REPORT_IDLE_OFF: { 1019 EventLogTags.writeDeviceIdleOffStart("unknown"); 1020 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false); 1021 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false); 1022 try { 1023 mNetworkPolicyManager.setDeviceIdleMode(false); 1024 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF, 1025 null, Process.myUid()); 1026 } catch (RemoteException e) { 1027 } 1028 if (deepChanged) { 1029 incActiveIdleOps(); 1030 getContext().sendOrderedBroadcastAsUser(mIdleIntent, UserHandle.ALL, 1031 null, mIdleStartedDoneReceiver, null, 0, null, null); 1032 } 1033 if (lightChanged) { 1034 incActiveIdleOps(); 1035 getContext().sendOrderedBroadcastAsUser(mLightIdleIntent, UserHandle.ALL, 1036 null, mIdleStartedDoneReceiver, null, 0, null, null); 1037 } 1038 // Always start with one active op for the message being sent here. 1039 // Now we are done! 1040 decActiveIdleOps(); 1041 EventLogTags.writeDeviceIdleOffComplete(); 1042 } break; 1043 case MSG_REPORT_ACTIVE: { 1044 String activeReason = (String)msg.obj; 1045 int activeUid = msg.arg1; 1046 EventLogTags.writeDeviceIdleOffStart( 1047 activeReason != null ? activeReason : "unknown"); 1048 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false); 1049 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false); 1050 try { 1051 mNetworkPolicyManager.setDeviceIdleMode(false); 1052 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF, 1053 activeReason, activeUid); 1054 } catch (RemoteException e) { 1055 } 1056 if (deepChanged) { 1057 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL); 1058 } 1059 if (lightChanged) { 1060 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL); 1061 } 1062 EventLogTags.writeDeviceIdleOffComplete(); 1063 } break; 1064 case MSG_TEMP_APP_WHITELIST_TIMEOUT: { 1065 int uid = msg.arg1; 1066 checkTempAppWhitelistTimeout(uid); 1067 } break; 1068 case MSG_REPORT_MAINTENANCE_ACTIVITY: { 1069 boolean active = (msg.arg1 == 1); 1070 final int size = mMaintenanceActivityListeners.beginBroadcast(); 1071 try { 1072 for (int i = 0; i < size; i++) { 1073 try { 1074 mMaintenanceActivityListeners.getBroadcastItem(i) 1075 .onMaintenanceActivityChanged(active); 1076 } catch (RemoteException ignored) { 1077 } 1078 } 1079 } finally { 1080 mMaintenanceActivityListeners.finishBroadcast(); 1081 } 1082 } break; 1083 case MSG_FINISH_IDLE_OP: { 1084 decActiveIdleOps(); 1085 } break; 1086 } 1087 } 1088 } 1089 1090 final MyHandler mHandler; 1091 1092 BinderService mBinderService; 1093 1094 private final class BinderService extends IDeviceIdleController.Stub { 1095 @Override public void addPowerSaveWhitelistApp(String name) { 1096 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 1097 null); 1098 long ident = Binder.clearCallingIdentity(); 1099 try { 1100 addPowerSaveWhitelistAppInternal(name); 1101 } finally { 1102 Binder.restoreCallingIdentity(ident); 1103 } 1104 } 1105 1106 @Override public void removePowerSaveWhitelistApp(String name) { 1107 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 1108 null); 1109 long ident = Binder.clearCallingIdentity(); 1110 try { 1111 removePowerSaveWhitelistAppInternal(name); 1112 } finally { 1113 Binder.restoreCallingIdentity(ident); 1114 } 1115 } 1116 1117 @Override public String[] getSystemPowerWhitelistExceptIdle() { 1118 return getSystemPowerWhitelistExceptIdleInternal(); 1119 } 1120 1121 @Override public String[] getSystemPowerWhitelist() { 1122 return getSystemPowerWhitelistInternal(); 1123 } 1124 1125 @Override public String[] getUserPowerWhitelist() { 1126 return getUserPowerWhitelistInternal(); 1127 } 1128 1129 @Override public String[] getFullPowerWhitelistExceptIdle() { 1130 return getFullPowerWhitelistExceptIdleInternal(); 1131 } 1132 1133 @Override public String[] getFullPowerWhitelist() { 1134 return getFullPowerWhitelistInternal(); 1135 } 1136 1137 @Override public int[] getAppIdWhitelistExceptIdle() { 1138 return getAppIdWhitelistExceptIdleInternal(); 1139 } 1140 1141 @Override public int[] getAppIdWhitelist() { 1142 return getAppIdWhitelistInternal(); 1143 } 1144 1145 @Override public int[] getAppIdUserWhitelist() { 1146 return getAppIdUserWhitelistInternal(); 1147 } 1148 1149 @Override public int[] getAppIdTempWhitelist() { 1150 return getAppIdTempWhitelistInternal(); 1151 } 1152 1153 @Override public boolean isPowerSaveWhitelistExceptIdleApp(String name) { 1154 return isPowerSaveWhitelistExceptIdleAppInternal(name); 1155 } 1156 1157 @Override public boolean isPowerSaveWhitelistApp(String name) { 1158 return isPowerSaveWhitelistAppInternal(name); 1159 } 1160 1161 @Override public void addPowerSaveTempWhitelistApp(String packageName, long duration, 1162 int userId, String reason) throws RemoteException { 1163 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason); 1164 } 1165 1166 @Override public long addPowerSaveTempWhitelistAppForMms(String packageName, 1167 int userId, String reason) throws RemoteException { 1168 long duration = mConstants.MMS_TEMP_APP_WHITELIST_DURATION; 1169 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason); 1170 return duration; 1171 } 1172 1173 @Override public long addPowerSaveTempWhitelistAppForSms(String packageName, 1174 int userId, String reason) throws RemoteException { 1175 long duration = mConstants.SMS_TEMP_APP_WHITELIST_DURATION; 1176 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason); 1177 return duration; 1178 } 1179 1180 @Override public void exitIdle(String reason) { 1181 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER, 1182 null); 1183 long ident = Binder.clearCallingIdentity(); 1184 try { 1185 exitIdleInternal(reason); 1186 } finally { 1187 Binder.restoreCallingIdentity(ident); 1188 } 1189 } 1190 1191 @Override public void downloadServiceActive(IBinder token) { 1192 getContext().enforceCallingOrSelfPermission( 1193 "android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS", null); 1194 long ident = Binder.clearCallingIdentity(); 1195 try { 1196 DeviceIdleController.this.downloadServiceActive(token); 1197 } finally { 1198 Binder.restoreCallingIdentity(ident); 1199 } 1200 } 1201 1202 @Override public void downloadServiceInactive() { 1203 getContext().enforceCallingOrSelfPermission( 1204 "android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS", null); 1205 long ident = Binder.clearCallingIdentity(); 1206 try { 1207 DeviceIdleController.this.downloadServiceInactive(); 1208 } finally { 1209 Binder.restoreCallingIdentity(ident); 1210 } 1211 } 1212 1213 @Override public boolean registerMaintenanceActivityListener( 1214 IMaintenanceActivityListener listener) { 1215 return DeviceIdleController.this.registerMaintenanceActivityListener(listener); 1216 } 1217 1218 @Override public void unregisterMaintenanceActivityListener( 1219 IMaintenanceActivityListener listener) { 1220 DeviceIdleController.this.unregisterMaintenanceActivityListener(listener); 1221 } 1222 1223 @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1224 DeviceIdleController.this.dump(fd, pw, args); 1225 } 1226 1227 @Override public void onShellCommand(FileDescriptor in, FileDescriptor out, 1228 FileDescriptor err, String[] args, ResultReceiver resultReceiver) { 1229 (new Shell()).exec(this, in, out, err, args, resultReceiver); 1230 } 1231 } 1232 1233 public final class LocalService { 1234 public void addPowerSaveTempWhitelistAppDirect(int appId, long duration, boolean sync, 1235 String reason) { 1236 addPowerSaveTempWhitelistAppDirectInternal(0, appId, duration, sync, reason); 1237 } 1238 1239 public void setNetworkPolicyTempWhitelistCallback(Runnable callback) { 1240 setNetworkPolicyTempWhitelistCallbackInternal(callback); 1241 } 1242 1243 public void setJobsActive(boolean active) { 1244 DeviceIdleController.this.setJobsActive(active); 1245 } 1246 1247 // Up-call from alarm manager. 1248 public void setAlarmsActive(boolean active) { 1249 DeviceIdleController.this.setAlarmsActive(active); 1250 } 1251 1252 /** 1253 * Returns the array of app ids whitelisted by user. Take care not to 1254 * modify this, as it is a reference to the original copy. But the reference 1255 * can change when the list changes, so it needs to be re-acquired when 1256 * {@link PowerManager#ACTION_POWER_SAVE_WHITELIST_CHANGED} is sent. 1257 */ 1258 public int[] getPowerSaveWhitelistUserAppIds() { 1259 return DeviceIdleController.this.getPowerSaveWhitelistUserAppIds(); 1260 } 1261 } 1262 1263 public DeviceIdleController(Context context) { 1264 super(context); 1265 mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml")); 1266 mHandler = new MyHandler(BackgroundThread.getHandler().getLooper()); 1267 } 1268 1269 int[] getPowerSaveWhitelistUserAppIds() { 1270 synchronized (this) { 1271 return mPowerSaveWhitelistUserAppIdArray; 1272 } 1273 } 1274 1275 private static File getSystemDir() { 1276 return new File(Environment.getDataDirectory(), "system"); 1277 } 1278 1279 @Override 1280 public void onStart() { 1281 final PackageManager pm = getContext().getPackageManager(); 1282 1283 synchronized (this) { 1284 mLightEnabled = mDeepEnabled = getContext().getResources().getBoolean( 1285 com.android.internal.R.bool.config_enableAutoPowerModes); 1286 SystemConfig sysConfig = SystemConfig.getInstance(); 1287 ArraySet<String> allowPowerExceptIdle = sysConfig.getAllowInPowerSaveExceptIdle(); 1288 for (int i=0; i<allowPowerExceptIdle.size(); i++) { 1289 String pkg = allowPowerExceptIdle.valueAt(i); 1290 try { 1291 ApplicationInfo ai = pm.getApplicationInfo(pkg, 1292 PackageManager.MATCH_SYSTEM_ONLY); 1293 int appid = UserHandle.getAppId(ai.uid); 1294 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid); 1295 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true); 1296 } catch (PackageManager.NameNotFoundException e) { 1297 } 1298 } 1299 ArraySet<String> allowPower = sysConfig.getAllowInPowerSave(); 1300 for (int i=0; i<allowPower.size(); i++) { 1301 String pkg = allowPower.valueAt(i); 1302 try { 1303 ApplicationInfo ai = pm.getApplicationInfo(pkg, 1304 PackageManager.MATCH_SYSTEM_ONLY); 1305 int appid = UserHandle.getAppId(ai.uid); 1306 // These apps are on both the whitelist-except-idle as well 1307 // as the full whitelist, so they apply in all cases. 1308 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid); 1309 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true); 1310 mPowerSaveWhitelistApps.put(ai.packageName, appid); 1311 mPowerSaveWhitelistSystemAppIds.put(appid, true); 1312 } catch (PackageManager.NameNotFoundException e) { 1313 } 1314 } 1315 1316 mConstants = new Constants(mHandler, getContext().getContentResolver()); 1317 1318 readConfigFileLocked(); 1319 updateWhitelistAppIdsLocked(); 1320 1321 mScreenOn = true; 1322 // Start out assuming we are charging. If we aren't, we will at least get 1323 // a battery update the next time the level drops. 1324 mCharging = true; 1325 mState = STATE_ACTIVE; 1326 mLightState = LIGHT_STATE_ACTIVE; 1327 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT; 1328 } 1329 1330 mBinderService = new BinderService(); 1331 publishBinderService(Context.DEVICE_IDLE_CONTROLLER, mBinderService); 1332 publishLocalService(LocalService.class, new LocalService()); 1333 } 1334 1335 @Override 1336 public void onBootPhase(int phase) { 1337 if (phase == PHASE_SYSTEM_SERVICES_READY) { 1338 synchronized (this) { 1339 mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); 1340 mBatteryStats = BatteryStatsService.getService(); 1341 mLocalPowerManager = getLocalService(PowerManagerInternal.class); 1342 mPowerManager = getContext().getSystemService(PowerManager.class); 1343 mActiveIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 1344 "deviceidle_maint"); 1345 mActiveIdleWakeLock.setReferenceCounted(false); 1346 mLocalAlarmManager = getLocalService(AlarmManagerService.LocalService.class); 1347 mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface( 1348 ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)); 1349 mDisplayManager = (DisplayManager) getContext().getSystemService( 1350 Context.DISPLAY_SERVICE); 1351 mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE); 1352 int sigMotionSensorId = getContext().getResources().getInteger( 1353 com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor); 1354 if (sigMotionSensorId > 0) { 1355 mMotionSensor = mSensorManager.getDefaultSensor(sigMotionSensorId, true); 1356 } 1357 if (mMotionSensor == null && getContext().getResources().getBoolean( 1358 com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) { 1359 mMotionSensor = mSensorManager.getDefaultSensor( 1360 Sensor.TYPE_WRIST_TILT_GESTURE, true); 1361 } 1362 if (mMotionSensor == null) { 1363 // As a last ditch, fall back to SMD. 1364 mMotionSensor = mSensorManager.getDefaultSensor( 1365 Sensor.TYPE_SIGNIFICANT_MOTION, true); 1366 } 1367 1368 if (getContext().getResources().getBoolean( 1369 com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) { 1370 mLocationManager = (LocationManager) getContext().getSystemService( 1371 Context.LOCATION_SERVICE); 1372 mLocationRequest = new LocationRequest() 1373 .setQuality(LocationRequest.ACCURACY_FINE) 1374 .setInterval(0) 1375 .setFastestInterval(0) 1376 .setNumUpdates(1); 1377 } 1378 1379 float angleThreshold = getContext().getResources().getInteger( 1380 com.android.internal.R.integer.config_autoPowerModeThresholdAngle) / 100f; 1381 mAnyMotionDetector = new AnyMotionDetector( 1382 (PowerManager) getContext().getSystemService(Context.POWER_SERVICE), 1383 mHandler, mSensorManager, this, angleThreshold); 1384 1385 mIdleIntent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); 1386 mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1387 | Intent.FLAG_RECEIVER_FOREGROUND); 1388 mLightIdleIntent = new Intent(PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED); 1389 mLightIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1390 | Intent.FLAG_RECEIVER_FOREGROUND); 1391 1392 IntentFilter filter = new IntentFilter(); 1393 filter.addAction(Intent.ACTION_BATTERY_CHANGED); 1394 getContext().registerReceiver(mReceiver, filter); 1395 filter = new IntentFilter(); 1396 filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 1397 filter.addDataScheme("package"); 1398 getContext().registerReceiver(mReceiver, filter); 1399 1400 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); 1401 mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray); 1402 mDisplayManager.registerDisplayListener(mDisplayListener, null); 1403 updateDisplayLocked(); 1404 } 1405 } 1406 } 1407 1408 public boolean addPowerSaveWhitelistAppInternal(String name) { 1409 synchronized (this) { 1410 try { 1411 ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name, 1412 PackageManager.MATCH_UNINSTALLED_PACKAGES); 1413 if (mPowerSaveWhitelistUserApps.put(name, UserHandle.getAppId(ai.uid)) == null) { 1414 reportPowerSaveWhitelistChangedLocked(); 1415 updateWhitelistAppIdsLocked(); 1416 writeConfigFileLocked(); 1417 } 1418 return true; 1419 } catch (PackageManager.NameNotFoundException e) { 1420 return false; 1421 } 1422 } 1423 } 1424 1425 public boolean removePowerSaveWhitelistAppInternal(String name) { 1426 synchronized (this) { 1427 if (mPowerSaveWhitelistUserApps.remove(name) != null) { 1428 reportPowerSaveWhitelistChangedLocked(); 1429 updateWhitelistAppIdsLocked(); 1430 writeConfigFileLocked(); 1431 return true; 1432 } 1433 } 1434 return false; 1435 } 1436 1437 public boolean getPowerSaveWhitelistAppInternal(String name) { 1438 synchronized (this) { 1439 return mPowerSaveWhitelistUserApps.containsKey(name); 1440 } 1441 } 1442 1443 public String[] getSystemPowerWhitelistExceptIdleInternal() { 1444 synchronized (this) { 1445 int size = mPowerSaveWhitelistAppsExceptIdle.size(); 1446 String[] apps = new String[size]; 1447 for (int i = 0; i < size; i++) { 1448 apps[i] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i); 1449 } 1450 return apps; 1451 } 1452 } 1453 1454 public String[] getSystemPowerWhitelistInternal() { 1455 synchronized (this) { 1456 int size = mPowerSaveWhitelistApps.size(); 1457 String[] apps = new String[size]; 1458 for (int i = 0; i < size; i++) { 1459 apps[i] = mPowerSaveWhitelistApps.keyAt(i); 1460 } 1461 return apps; 1462 } 1463 } 1464 1465 public String[] getUserPowerWhitelistInternal() { 1466 synchronized (this) { 1467 int size = mPowerSaveWhitelistUserApps.size(); 1468 String[] apps = new String[size]; 1469 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) { 1470 apps[i] = mPowerSaveWhitelistUserApps.keyAt(i); 1471 } 1472 return apps; 1473 } 1474 } 1475 1476 public String[] getFullPowerWhitelistExceptIdleInternal() { 1477 synchronized (this) { 1478 int size = mPowerSaveWhitelistAppsExceptIdle.size() + mPowerSaveWhitelistUserApps.size(); 1479 String[] apps = new String[size]; 1480 int cur = 0; 1481 for (int i = 0; i < mPowerSaveWhitelistAppsExceptIdle.size(); i++) { 1482 apps[cur] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i); 1483 cur++; 1484 } 1485 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) { 1486 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i); 1487 cur++; 1488 } 1489 return apps; 1490 } 1491 } 1492 1493 public String[] getFullPowerWhitelistInternal() { 1494 synchronized (this) { 1495 int size = mPowerSaveWhitelistApps.size() + mPowerSaveWhitelistUserApps.size(); 1496 String[] apps = new String[size]; 1497 int cur = 0; 1498 for (int i = 0; i < mPowerSaveWhitelistApps.size(); i++) { 1499 apps[cur] = mPowerSaveWhitelistApps.keyAt(i); 1500 cur++; 1501 } 1502 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) { 1503 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i); 1504 cur++; 1505 } 1506 return apps; 1507 } 1508 } 1509 1510 public boolean isPowerSaveWhitelistExceptIdleAppInternal(String packageName) { 1511 synchronized (this) { 1512 return mPowerSaveWhitelistAppsExceptIdle.containsKey(packageName) 1513 || mPowerSaveWhitelistUserApps.containsKey(packageName); 1514 } 1515 } 1516 1517 public boolean isPowerSaveWhitelistAppInternal(String packageName) { 1518 synchronized (this) { 1519 return mPowerSaveWhitelistApps.containsKey(packageName) 1520 || mPowerSaveWhitelistUserApps.containsKey(packageName); 1521 } 1522 } 1523 1524 public int[] getAppIdWhitelistExceptIdleInternal() { 1525 synchronized (this) { 1526 return mPowerSaveWhitelistExceptIdleAppIdArray; 1527 } 1528 } 1529 1530 public int[] getAppIdWhitelistInternal() { 1531 synchronized (this) { 1532 return mPowerSaveWhitelistAllAppIdArray; 1533 } 1534 } 1535 1536 public int[] getAppIdUserWhitelistInternal() { 1537 synchronized (this) { 1538 return mPowerSaveWhitelistUserAppIdArray; 1539 } 1540 } 1541 1542 public int[] getAppIdTempWhitelistInternal() { 1543 synchronized (this) { 1544 return mTempWhitelistAppIdArray; 1545 } 1546 } 1547 1548 void addPowerSaveTempWhitelistAppChecked(String packageName, long duration, 1549 int userId, String reason) throws RemoteException { 1550 getContext().enforceCallingPermission( 1551 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, 1552 "No permission to change device idle whitelist"); 1553 final int callingUid = Binder.getCallingUid(); 1554 userId = ActivityManagerNative.getDefault().handleIncomingUser( 1555 Binder.getCallingPid(), 1556 callingUid, 1557 userId, 1558 /*allowAll=*/ false, 1559 /*requireFull=*/ false, 1560 "addPowerSaveTempWhitelistApp", null); 1561 final long token = Binder.clearCallingIdentity(); 1562 try { 1563 addPowerSaveTempWhitelistAppInternal(callingUid, 1564 packageName, duration, userId, true, reason); 1565 } finally { 1566 Binder.restoreCallingIdentity(token); 1567 } 1568 } 1569 1570 /** 1571 * Adds an app to the temporary whitelist and resets the endTime for granting the 1572 * app an exemption to access network and acquire wakelocks. 1573 */ 1574 void addPowerSaveTempWhitelistAppInternal(int callingUid, String packageName, 1575 long duration, int userId, boolean sync, String reason) { 1576 try { 1577 int uid = getContext().getPackageManager().getPackageUidAsUser(packageName, userId); 1578 int appId = UserHandle.getAppId(uid); 1579 addPowerSaveTempWhitelistAppDirectInternal(callingUid, appId, duration, sync, reason); 1580 } catch (NameNotFoundException e) { 1581 } 1582 } 1583 1584 /** 1585 * Adds an app to the temporary whitelist and resets the endTime for granting the 1586 * app an exemption to access network and acquire wakelocks. 1587 */ 1588 void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int appId, 1589 long duration, boolean sync, String reason) { 1590 final long timeNow = SystemClock.elapsedRealtime(); 1591 Runnable networkPolicyTempWhitelistCallback = null; 1592 synchronized (this) { 1593 int callingAppId = UserHandle.getAppId(callingUid); 1594 if (callingAppId >= Process.FIRST_APPLICATION_UID) { 1595 if (!mPowerSaveWhitelistSystemAppIds.get(callingAppId)) { 1596 throw new SecurityException("Calling app " + UserHandle.formatUid(callingUid) 1597 + " is not on whitelist"); 1598 } 1599 } 1600 duration = Math.min(duration, mConstants.MAX_TEMP_APP_WHITELIST_DURATION); 1601 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId); 1602 final boolean newEntry = entry == null; 1603 // Set the new end time 1604 if (newEntry) { 1605 entry = new Pair<>(new MutableLong(0), reason); 1606 mTempWhitelistAppIdEndTimes.put(appId, entry); 1607 } 1608 entry.first.value = timeNow + duration; 1609 if (DEBUG) { 1610 Slog.d(TAG, "Adding AppId " + appId + " to temp whitelist"); 1611 } 1612 if (newEntry) { 1613 // No pending timeout for the app id, post a delayed message 1614 try { 1615 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_START, 1616 reason, appId); 1617 } catch (RemoteException e) { 1618 } 1619 postTempActiveTimeoutMessage(appId, duration); 1620 updateTempWhitelistAppIdsLocked(); 1621 if (mNetworkPolicyTempWhitelistCallback != null) { 1622 if (!sync) { 1623 mHandler.post(mNetworkPolicyTempWhitelistCallback); 1624 } else { 1625 networkPolicyTempWhitelistCallback = mNetworkPolicyTempWhitelistCallback; 1626 } 1627 } 1628 reportTempWhitelistChangedLocked(); 1629 } 1630 } 1631 if (networkPolicyTempWhitelistCallback != null) { 1632 networkPolicyTempWhitelistCallback.run(); 1633 } 1634 } 1635 1636 public void setNetworkPolicyTempWhitelistCallbackInternal(Runnable callback) { 1637 synchronized (this) { 1638 mNetworkPolicyTempWhitelistCallback = callback; 1639 } 1640 } 1641 1642 private void postTempActiveTimeoutMessage(int uid, long delay) { 1643 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, uid, 0), 1644 delay); 1645 } 1646 1647 void checkTempAppWhitelistTimeout(int uid) { 1648 final long timeNow = SystemClock.elapsedRealtime(); 1649 synchronized (this) { 1650 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(uid); 1651 if (entry == null) { 1652 // Nothing to do 1653 return; 1654 } 1655 if (timeNow >= entry.first.value) { 1656 mTempWhitelistAppIdEndTimes.delete(uid); 1657 if (DEBUG) { 1658 Slog.d(TAG, "Removing UID " + uid + " from temp whitelist"); 1659 } 1660 updateTempWhitelistAppIdsLocked(); 1661 if (mNetworkPolicyTempWhitelistCallback != null) { 1662 mHandler.post(mNetworkPolicyTempWhitelistCallback); 1663 } 1664 reportTempWhitelistChangedLocked(); 1665 try { 1666 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH, 1667 entry.second, uid); 1668 } catch (RemoteException e) { 1669 } 1670 } else { 1671 // Need more time 1672 postTempActiveTimeoutMessage(uid, entry.first.value - timeNow); 1673 } 1674 } 1675 } 1676 1677 public void exitIdleInternal(String reason) { 1678 synchronized (this) { 1679 becomeActiveLocked(reason, Binder.getCallingUid()); 1680 } 1681 } 1682 1683 void updateDisplayLocked() { 1684 mCurDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY); 1685 // We consider any situation where the display is showing something to be it on, 1686 // because if there is anything shown we are going to be updating it at some 1687 // frequency so can't be allowed to go into deep sleeps. 1688 boolean screenOn = mCurDisplay.getState() == Display.STATE_ON; 1689 if (DEBUG) Slog.d(TAG, "updateDisplayLocked: screenOn=" + screenOn); 1690 if (!screenOn && mScreenOn) { 1691 mScreenOn = false; 1692 if (!mForceIdle) { 1693 becomeInactiveIfAppropriateLocked(); 1694 } 1695 } else if (screenOn) { 1696 mScreenOn = true; 1697 if (!mForceIdle) { 1698 becomeActiveLocked("screen", Process.myUid()); 1699 } 1700 } 1701 } 1702 1703 void updateChargingLocked(boolean charging) { 1704 if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging); 1705 if (!charging && mCharging) { 1706 mCharging = false; 1707 if (!mForceIdle) { 1708 becomeInactiveIfAppropriateLocked(); 1709 } 1710 } else if (charging) { 1711 mCharging = charging; 1712 if (!mForceIdle) { 1713 becomeActiveLocked("charging", Process.myUid()); 1714 } 1715 } 1716 } 1717 1718 void scheduleReportActiveLocked(String activeReason, int activeUid) { 1719 Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid, 0, activeReason); 1720 mHandler.sendMessage(msg); 1721 } 1722 1723 void becomeActiveLocked(String activeReason, int activeUid) { 1724 if (DEBUG) Slog.i(TAG, "becomeActiveLocked, reason = " + activeReason); 1725 if (mState != STATE_ACTIVE || mLightState != STATE_ACTIVE) { 1726 EventLogTags.writeDeviceIdle(STATE_ACTIVE, activeReason); 1727 EventLogTags.writeDeviceIdleLight(LIGHT_STATE_ACTIVE, activeReason); 1728 scheduleReportActiveLocked(activeReason, activeUid); 1729 mState = STATE_ACTIVE; 1730 mLightState = LIGHT_STATE_ACTIVE; 1731 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT; 1732 mCurIdleBudget = 0; 1733 mMaintenanceStartTime = 0; 1734 resetIdleManagementLocked(); 1735 resetLightIdleManagementLocked(); 1736 addEvent(EVENT_NORMAL); 1737 } 1738 } 1739 1740 void becomeInactiveIfAppropriateLocked() { 1741 if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()"); 1742 if ((!mScreenOn && !mCharging) || mForceIdle) { 1743 // Screen has turned off; we are now going to become inactive and start 1744 // waiting to see if we will ultimately go idle. 1745 if (mState == STATE_ACTIVE && mDeepEnabled) { 1746 mState = STATE_INACTIVE; 1747 if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE"); 1748 resetIdleManagementLocked(); 1749 scheduleAlarmLocked(mInactiveTimeout, false); 1750 EventLogTags.writeDeviceIdle(mState, "no activity"); 1751 } 1752 if (mLightState == LIGHT_STATE_ACTIVE && mLightEnabled) { 1753 mLightState = LIGHT_STATE_INACTIVE; 1754 if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE"); 1755 resetLightIdleManagementLocked(); 1756 scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT); 1757 EventLogTags.writeDeviceIdleLight(mLightState, "no activity"); 1758 } 1759 } 1760 } 1761 1762 void resetIdleManagementLocked() { 1763 mNextIdlePendingDelay = 0; 1764 mNextIdleDelay = 0; 1765 mNextLightIdleDelay = 0; 1766 cancelAlarmLocked(); 1767 cancelSensingTimeoutAlarmLocked(); 1768 cancelLocatingLocked(); 1769 stopMonitoringMotionLocked(); 1770 mAnyMotionDetector.stop(); 1771 } 1772 1773 void resetLightIdleManagementLocked() { 1774 cancelLightAlarmLocked(); 1775 } 1776 1777 void exitForceIdleLocked() { 1778 if (mForceIdle) { 1779 mForceIdle = false; 1780 if (mScreenOn || mCharging) { 1781 becomeActiveLocked("exit-force-idle", Process.myUid()); 1782 } 1783 } 1784 } 1785 1786 void stepLightIdleStateLocked(String reason) { 1787 if (mLightState == LIGHT_STATE_OVERRIDE) { 1788 // If we are already in deep device idle mode, then 1789 // there is nothing left to do for light mode. 1790 return; 1791 } 1792 1793 if (DEBUG) Slog.d(TAG, "stepLightIdleStateLocked: mLightState=" + mLightState); 1794 EventLogTags.writeDeviceIdleLightStep(); 1795 1796 switch (mLightState) { 1797 case LIGHT_STATE_INACTIVE: 1798 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET; 1799 // Reset the upcoming idle delays. 1800 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT; 1801 mMaintenanceStartTime = 0; 1802 if (!isOpsInactiveLocked()) { 1803 // We have some active ops going on... give them a chance to finish 1804 // before going in to our first idle. 1805 mLightState = LIGHT_STATE_PRE_IDLE; 1806 EventLogTags.writeDeviceIdleLight(mLightState, reason); 1807 scheduleLightAlarmLocked(mConstants.LIGHT_PRE_IDLE_TIMEOUT); 1808 break; 1809 } 1810 // Nothing active, fall through to immediately idle. 1811 case LIGHT_STATE_PRE_IDLE: 1812 case LIGHT_STATE_IDLE_MAINTENANCE: 1813 if (mMaintenanceStartTime != 0) { 1814 long duration = SystemClock.elapsedRealtime() - mMaintenanceStartTime; 1815 if (duration < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) { 1816 // We didn't use up all of our minimum budget; add this to the reserve. 1817 mCurIdleBudget += (mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET-duration); 1818 } else { 1819 // We used more than our minimum budget; this comes out of the reserve. 1820 mCurIdleBudget -= (duration-mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET); 1821 } 1822 } 1823 mMaintenanceStartTime = 0; 1824 scheduleLightAlarmLocked(mNextLightIdleDelay); 1825 mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT, 1826 (long)(mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR)); 1827 if (mNextLightIdleDelay < mConstants.LIGHT_IDLE_TIMEOUT) { 1828 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT; 1829 } 1830 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_STATE_IDLE."); 1831 mLightState = LIGHT_STATE_IDLE; 1832 EventLogTags.writeDeviceIdleLight(mLightState, reason); 1833 addEvent(EVENT_LIGHT_IDLE); 1834 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON_LIGHT); 1835 break; 1836 case LIGHT_STATE_IDLE: 1837 // We have been idling long enough, now it is time to do some work. 1838 mActiveIdleOpCount = 1; 1839 mActiveIdleWakeLock.acquire(); 1840 mMaintenanceStartTime = SystemClock.elapsedRealtime(); 1841 if (mCurIdleBudget < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) { 1842 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET; 1843 } else if (mCurIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) { 1844 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET; 1845 } 1846 scheduleLightAlarmLocked(mCurIdleBudget); 1847 if (DEBUG) Slog.d(TAG, 1848 "Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE."); 1849 mLightState = LIGHT_STATE_IDLE_MAINTENANCE; 1850 EventLogTags.writeDeviceIdleLight(mLightState, reason); 1851 addEvent(EVENT_LIGHT_MAINTENANCE); 1852 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF); 1853 break; 1854 } 1855 } 1856 1857 void stepIdleStateLocked(String reason) { 1858 if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState); 1859 EventLogTags.writeDeviceIdleStep(); 1860 1861 final long now = SystemClock.elapsedRealtime(); 1862 if ((now+mConstants.MIN_TIME_TO_ALARM) > mAlarmManager.getNextWakeFromIdleTime()) { 1863 // Whoops, there is an upcoming alarm. We don't actually want to go idle. 1864 if (mState != STATE_ACTIVE) { 1865 becomeActiveLocked("alarm", Process.myUid()); 1866 becomeInactiveIfAppropriateLocked(); 1867 } 1868 return; 1869 } 1870 1871 switch (mState) { 1872 case STATE_INACTIVE: 1873 // We have now been inactive long enough, it is time to start looking 1874 // for motion and sleep some more while doing so. 1875 startMonitoringMotionLocked(); 1876 scheduleAlarmLocked(mConstants.IDLE_AFTER_INACTIVE_TIMEOUT, false); 1877 // Reset the upcoming idle delays. 1878 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT; 1879 mNextIdleDelay = mConstants.IDLE_TIMEOUT; 1880 mState = STATE_IDLE_PENDING; 1881 if (DEBUG) Slog.d(TAG, "Moved from STATE_INACTIVE to STATE_IDLE_PENDING."); 1882 EventLogTags.writeDeviceIdle(mState, reason); 1883 break; 1884 case STATE_IDLE_PENDING: 1885 mState = STATE_SENSING; 1886 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING."); 1887 EventLogTags.writeDeviceIdle(mState, reason); 1888 scheduleSensingTimeoutAlarmLocked(mConstants.SENSING_TIMEOUT); 1889 cancelLocatingLocked(); 1890 mNotMoving = false; 1891 mLocated = false; 1892 mLastGenericLocation = null; 1893 mLastGpsLocation = null; 1894 mAnyMotionDetector.checkForAnyMotion(); 1895 break; 1896 case STATE_SENSING: 1897 cancelSensingTimeoutAlarmLocked(); 1898 mState = STATE_LOCATING; 1899 if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING."); 1900 EventLogTags.writeDeviceIdle(mState, reason); 1901 scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT, false); 1902 if (mLocationManager != null 1903 && mLocationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) { 1904 mLocationManager.requestLocationUpdates(mLocationRequest, 1905 mGenericLocationListener, mHandler.getLooper()); 1906 mLocating = true; 1907 } else { 1908 mHasNetworkLocation = false; 1909 } 1910 if (mLocationManager != null 1911 && mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) { 1912 mHasGps = true; 1913 mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5, 1914 mGpsLocationListener, mHandler.getLooper()); 1915 mLocating = true; 1916 } else { 1917 mHasGps = false; 1918 } 1919 // If we have a location provider, we're all set, the listeners will move state 1920 // forward. 1921 if (mLocating) { 1922 break; 1923 } 1924 1925 // Otherwise, we have to move from locating into idle maintenance. 1926 case STATE_LOCATING: 1927 cancelAlarmLocked(); 1928 cancelLocatingLocked(); 1929 mAnyMotionDetector.stop(); 1930 1931 case STATE_IDLE_MAINTENANCE: 1932 scheduleAlarmLocked(mNextIdleDelay, true); 1933 if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay + 1934 " ms."); 1935 mNextIdleDelay = (long)(mNextIdleDelay * mConstants.IDLE_FACTOR); 1936 if (DEBUG) Slog.d(TAG, "Setting mNextIdleDelay = " + mNextIdleDelay); 1937 mNextIdleDelay = Math.min(mNextIdleDelay, mConstants.MAX_IDLE_TIMEOUT); 1938 if (mNextIdleDelay < mConstants.IDLE_TIMEOUT) { 1939 mNextIdleDelay = mConstants.IDLE_TIMEOUT; 1940 } 1941 mState = STATE_IDLE; 1942 if (mLightState != LIGHT_STATE_OVERRIDE) { 1943 mLightState = LIGHT_STATE_OVERRIDE; 1944 cancelLightAlarmLocked(); 1945 } 1946 EventLogTags.writeDeviceIdle(mState, reason); 1947 addEvent(EVENT_DEEP_IDLE); 1948 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON); 1949 break; 1950 case STATE_IDLE: 1951 // We have been idling long enough, now it is time to do some work. 1952 mActiveIdleOpCount = 1; 1953 mActiveIdleWakeLock.acquire(); 1954 scheduleAlarmLocked(mNextIdlePendingDelay, false); 1955 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE to STATE_IDLE_MAINTENANCE. " + 1956 "Next alarm in " + mNextIdlePendingDelay + " ms."); 1957 mMaintenanceStartTime = SystemClock.elapsedRealtime(); 1958 mNextIdlePendingDelay = Math.min(mConstants.MAX_IDLE_PENDING_TIMEOUT, 1959 (long)(mNextIdlePendingDelay * mConstants.IDLE_PENDING_FACTOR)); 1960 if (mNextIdlePendingDelay < mConstants.IDLE_PENDING_TIMEOUT) { 1961 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT; 1962 } 1963 mState = STATE_IDLE_MAINTENANCE; 1964 EventLogTags.writeDeviceIdle(mState, reason); 1965 addEvent(EVENT_DEEP_MAINTENANCE); 1966 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF); 1967 break; 1968 } 1969 } 1970 1971 void incActiveIdleOps() { 1972 synchronized (this) { 1973 mActiveIdleOpCount++; 1974 } 1975 } 1976 1977 void decActiveIdleOps() { 1978 synchronized (this) { 1979 mActiveIdleOpCount--; 1980 if (mActiveIdleOpCount <= 0) { 1981 exitMaintenanceEarlyIfNeededLocked(); 1982 mActiveIdleWakeLock.release(); 1983 } 1984 } 1985 } 1986 1987 void downloadServiceActive(IBinder token) { 1988 synchronized (this) { 1989 mDownloadServiceActive = token; 1990 reportMaintenanceActivityIfNeededLocked(); 1991 try { 1992 token.linkToDeath(new IBinder.DeathRecipient() { 1993 @Override public void binderDied() { 1994 downloadServiceInactive(); 1995 } 1996 }, 0); 1997 } catch (RemoteException e) { 1998 mDownloadServiceActive = null; 1999 } 2000 } 2001 } 2002 2003 void downloadServiceInactive() { 2004 synchronized (this) { 2005 mDownloadServiceActive = null; 2006 reportMaintenanceActivityIfNeededLocked(); 2007 exitMaintenanceEarlyIfNeededLocked(); 2008 } 2009 } 2010 2011 void setJobsActive(boolean active) { 2012 synchronized (this) { 2013 mJobsActive = active; 2014 reportMaintenanceActivityIfNeededLocked(); 2015 if (!active) { 2016 exitMaintenanceEarlyIfNeededLocked(); 2017 } 2018 } 2019 } 2020 2021 void setAlarmsActive(boolean active) { 2022 synchronized (this) { 2023 mAlarmsActive = active; 2024 if (!active) { 2025 exitMaintenanceEarlyIfNeededLocked(); 2026 } 2027 } 2028 } 2029 2030 boolean registerMaintenanceActivityListener(IMaintenanceActivityListener listener) { 2031 synchronized (this) { 2032 mMaintenanceActivityListeners.register(listener); 2033 return mReportedMaintenanceActivity; 2034 } 2035 } 2036 2037 void unregisterMaintenanceActivityListener(IMaintenanceActivityListener listener) { 2038 synchronized (this) { 2039 mMaintenanceActivityListeners.unregister(listener); 2040 } 2041 } 2042 2043 void reportMaintenanceActivityIfNeededLocked() { 2044 boolean active = mJobsActive | (mDownloadServiceActive != null); 2045 if (active == mReportedMaintenanceActivity) { 2046 return; 2047 } 2048 mReportedMaintenanceActivity = active; 2049 Message msg = mHandler.obtainMessage(MSG_REPORT_MAINTENANCE_ACTIVITY, 2050 mReportedMaintenanceActivity ? 1 : 0, 0); 2051 mHandler.sendMessage(msg); 2052 } 2053 2054 boolean isOpsInactiveLocked() { 2055 return mActiveIdleOpCount <= 0 && mDownloadServiceActive == null 2056 && !mJobsActive && !mAlarmsActive; 2057 } 2058 2059 void exitMaintenanceEarlyIfNeededLocked() { 2060 if (mState == STATE_IDLE_MAINTENANCE || mLightState == LIGHT_STATE_IDLE_MAINTENANCE 2061 || mLightState == LIGHT_STATE_PRE_IDLE) { 2062 if (isOpsInactiveLocked()) { 2063 final long now = SystemClock.elapsedRealtime(); 2064 if (DEBUG) { 2065 StringBuilder sb = new StringBuilder(); 2066 sb.append("Exit: start="); 2067 TimeUtils.formatDuration(mMaintenanceStartTime, sb); 2068 sb.append(" now="); 2069 TimeUtils.formatDuration(now, sb); 2070 Slog.d(TAG, sb.toString()); 2071 } 2072 if (mState == STATE_IDLE_MAINTENANCE) { 2073 stepIdleStateLocked("s:early"); 2074 } else if (mLightState == LIGHT_STATE_PRE_IDLE) { 2075 stepLightIdleStateLocked("s:predone"); 2076 } else { 2077 stepLightIdleStateLocked("s:early"); 2078 } 2079 } 2080 } 2081 } 2082 2083 void motionLocked() { 2084 if (DEBUG) Slog.d(TAG, "motionLocked()"); 2085 // The motion sensor will have been disabled at this point 2086 handleMotionDetectedLocked(mConstants.MOTION_INACTIVE_TIMEOUT, "motion"); 2087 } 2088 2089 void handleMotionDetectedLocked(long timeout, String type) { 2090 // The device is not yet active, so we want to go back to the pending idle 2091 // state to wait again for no motion. Note that we only monitor for motion 2092 // after moving out of the inactive state, so no need to worry about that. 2093 boolean becomeInactive = false; 2094 if (mState != STATE_ACTIVE) { 2095 scheduleReportActiveLocked(type, Process.myUid()); 2096 mState = STATE_ACTIVE; 2097 mInactiveTimeout = timeout; 2098 mCurIdleBudget = 0; 2099 mMaintenanceStartTime = 0; 2100 EventLogTags.writeDeviceIdle(mState, type); 2101 addEvent(EVENT_NORMAL); 2102 becomeInactive = true; 2103 } 2104 if (mLightState == LIGHT_STATE_OVERRIDE) { 2105 // We went out of light idle mode because we had started deep idle mode... let's 2106 // now go back and reset things so we resume light idling if appropriate. 2107 mLightState = STATE_ACTIVE; 2108 EventLogTags.writeDeviceIdleLight(mLightState, type); 2109 becomeInactive = true; 2110 } 2111 if (becomeInactive) { 2112 becomeInactiveIfAppropriateLocked(); 2113 } 2114 } 2115 2116 void receivedGenericLocationLocked(Location location) { 2117 if (mState != STATE_LOCATING) { 2118 cancelLocatingLocked(); 2119 return; 2120 } 2121 if (DEBUG) Slog.d(TAG, "Generic location: " + location); 2122 mLastGenericLocation = new Location(location); 2123 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHasGps) { 2124 return; 2125 } 2126 mLocated = true; 2127 if (mNotMoving) { 2128 stepIdleStateLocked("s:location"); 2129 } 2130 } 2131 2132 void receivedGpsLocationLocked(Location location) { 2133 if (mState != STATE_LOCATING) { 2134 cancelLocatingLocked(); 2135 return; 2136 } 2137 if (DEBUG) Slog.d(TAG, "GPS location: " + location); 2138 mLastGpsLocation = new Location(location); 2139 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY) { 2140 return; 2141 } 2142 mLocated = true; 2143 if (mNotMoving) { 2144 stepIdleStateLocked("s:gps"); 2145 } 2146 } 2147 2148 void startMonitoringMotionLocked() { 2149 if (DEBUG) Slog.d(TAG, "startMonitoringMotionLocked()"); 2150 if (mMotionSensor != null && !mMotionListener.active) { 2151 mMotionListener.registerLocked(); 2152 } 2153 } 2154 2155 void stopMonitoringMotionLocked() { 2156 if (DEBUG) Slog.d(TAG, "stopMonitoringMotionLocked()"); 2157 if (mMotionSensor != null && mMotionListener.active) { 2158 mMotionListener.unregisterLocked(); 2159 } 2160 } 2161 2162 void cancelAlarmLocked() { 2163 if (mNextAlarmTime != 0) { 2164 mNextAlarmTime = 0; 2165 mAlarmManager.cancel(mDeepAlarmListener); 2166 } 2167 } 2168 2169 void cancelLightAlarmLocked() { 2170 if (mNextLightAlarmTime != 0) { 2171 mNextLightAlarmTime = 0; 2172 mAlarmManager.cancel(mLightAlarmListener); 2173 } 2174 } 2175 2176 void cancelLocatingLocked() { 2177 if (mLocating) { 2178 mLocationManager.removeUpdates(mGenericLocationListener); 2179 mLocationManager.removeUpdates(mGpsLocationListener); 2180 mLocating = false; 2181 } 2182 } 2183 2184 void cancelSensingTimeoutAlarmLocked() { 2185 if (mNextSensingTimeoutAlarmTime != 0) { 2186 mNextSensingTimeoutAlarmTime = 0; 2187 mAlarmManager.cancel(mSensingTimeoutAlarmListener); 2188 } 2189 } 2190 2191 void scheduleAlarmLocked(long delay, boolean idleUntil) { 2192 if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")"); 2193 if (mMotionSensor == null) { 2194 // If there is no motion sensor on this device, then we won't schedule 2195 // alarms, because we can't determine if the device is not moving. This effectively 2196 // turns off normal execution of device idling, although it is still possible to 2197 // manually poke it by pretending like the alarm is going off. 2198 return; 2199 } 2200 mNextAlarmTime = SystemClock.elapsedRealtime() + delay; 2201 if (idleUntil) { 2202 mAlarmManager.setIdleUntil(AlarmManager.ELAPSED_REALTIME_WAKEUP, 2203 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler); 2204 } else { 2205 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 2206 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler); 2207 } 2208 } 2209 2210 void scheduleLightAlarmLocked(long delay) { 2211 if (DEBUG) Slog.d(TAG, "scheduleLightAlarmLocked(" + delay + ")"); 2212 if (mMotionSensor == null) { 2213 // If there is no motion sensor on this device, then we won't schedule 2214 // alarms, because we can't determine if the device is not moving. This effectively 2215 // turns off normal execution of device idling, although it is still possible to 2216 // manually poke it by pretending like the alarm is going off. 2217 return; 2218 } 2219 mNextLightAlarmTime = SystemClock.elapsedRealtime() + delay; 2220 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 2221 mNextLightAlarmTime, "DeviceIdleController.light", mLightAlarmListener, mHandler); 2222 } 2223 2224 void scheduleSensingTimeoutAlarmLocked(long delay) { 2225 if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")"); 2226 mNextSensingTimeoutAlarmTime = SystemClock.elapsedRealtime() + delay; 2227 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextSensingTimeoutAlarmTime, 2228 "DeviceIdleController.sensing", mSensingTimeoutAlarmListener, mHandler); 2229 } 2230 2231 private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps, 2232 ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds) { 2233 outAppIds.clear(); 2234 if (systemApps != null) { 2235 for (int i = 0; i < systemApps.size(); i++) { 2236 outAppIds.put(systemApps.valueAt(i), true); 2237 } 2238 } 2239 if (userApps != null) { 2240 for (int i = 0; i < userApps.size(); i++) { 2241 outAppIds.put(userApps.valueAt(i), true); 2242 } 2243 } 2244 int size = outAppIds.size(); 2245 int[] appids = new int[size]; 2246 for (int i = 0; i < size; i++) { 2247 appids[i] = outAppIds.keyAt(i); 2248 } 2249 return appids; 2250 } 2251 2252 private void updateWhitelistAppIdsLocked() { 2253 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(mPowerSaveWhitelistAppsExceptIdle, 2254 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistExceptIdleAppIds); 2255 mPowerSaveWhitelistAllAppIdArray = buildAppIdArray(mPowerSaveWhitelistApps, 2256 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistAllAppIds); 2257 mPowerSaveWhitelistUserAppIdArray = buildAppIdArray(null, 2258 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistUserAppIds); 2259 if (mLocalPowerManager != null) { 2260 if (DEBUG) { 2261 Slog.d(TAG, "Setting wakelock whitelist to " 2262 + Arrays.toString(mPowerSaveWhitelistAllAppIdArray)); 2263 } 2264 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); 2265 } 2266 if (mLocalAlarmManager != null) { 2267 if (DEBUG) { 2268 Slog.d(TAG, "Setting alarm whitelist to " 2269 + Arrays.toString(mPowerSaveWhitelistUserAppIdArray)); 2270 } 2271 mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray); 2272 } 2273 } 2274 2275 private void updateTempWhitelistAppIdsLocked() { 2276 final int size = mTempWhitelistAppIdEndTimes.size(); 2277 if (mTempWhitelistAppIdArray.length != size) { 2278 mTempWhitelistAppIdArray = new int[size]; 2279 } 2280 for (int i = 0; i < size; i++) { 2281 mTempWhitelistAppIdArray[i] = mTempWhitelistAppIdEndTimes.keyAt(i); 2282 } 2283 if (mLocalPowerManager != null) { 2284 if (DEBUG) { 2285 Slog.d(TAG, "Setting wakelock temp whitelist to " 2286 + Arrays.toString(mTempWhitelistAppIdArray)); 2287 } 2288 mLocalPowerManager.setDeviceIdleTempWhitelist(mTempWhitelistAppIdArray); 2289 } 2290 } 2291 2292 private void reportPowerSaveWhitelistChangedLocked() { 2293 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED); 2294 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 2295 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM); 2296 } 2297 2298 private void reportTempWhitelistChangedLocked() { 2299 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED); 2300 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 2301 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM); 2302 } 2303 2304 void readConfigFileLocked() { 2305 if (DEBUG) Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile()); 2306 mPowerSaveWhitelistUserApps.clear(); 2307 FileInputStream stream; 2308 try { 2309 stream = mConfigFile.openRead(); 2310 } catch (FileNotFoundException e) { 2311 return; 2312 } 2313 try { 2314 XmlPullParser parser = Xml.newPullParser(); 2315 parser.setInput(stream, StandardCharsets.UTF_8.name()); 2316 readConfigFileLocked(parser); 2317 } catch (XmlPullParserException e) { 2318 } finally { 2319 try { 2320 stream.close(); 2321 } catch (IOException e) { 2322 } 2323 } 2324 } 2325 2326 private void readConfigFileLocked(XmlPullParser parser) { 2327 final PackageManager pm = getContext().getPackageManager(); 2328 2329 try { 2330 int type; 2331 while ((type = parser.next()) != XmlPullParser.START_TAG 2332 && type != XmlPullParser.END_DOCUMENT) { 2333 ; 2334 } 2335 2336 if (type != XmlPullParser.START_TAG) { 2337 throw new IllegalStateException("no start tag found"); 2338 } 2339 2340 int outerDepth = parser.getDepth(); 2341 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 2342 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 2343 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 2344 continue; 2345 } 2346 2347 String tagName = parser.getName(); 2348 if (tagName.equals("wl")) { 2349 String name = parser.getAttributeValue(null, "n"); 2350 if (name != null) { 2351 try { 2352 ApplicationInfo ai = pm.getApplicationInfo(name, 2353 PackageManager.MATCH_UNINSTALLED_PACKAGES); 2354 mPowerSaveWhitelistUserApps.put(ai.packageName, 2355 UserHandle.getAppId(ai.uid)); 2356 } catch (PackageManager.NameNotFoundException e) { 2357 } 2358 } 2359 } else { 2360 Slog.w(TAG, "Unknown element under <config>: " 2361 + parser.getName()); 2362 XmlUtils.skipCurrentTag(parser); 2363 } 2364 } 2365 2366 } catch (IllegalStateException e) { 2367 Slog.w(TAG, "Failed parsing config " + e); 2368 } catch (NullPointerException e) { 2369 Slog.w(TAG, "Failed parsing config " + e); 2370 } catch (NumberFormatException e) { 2371 Slog.w(TAG, "Failed parsing config " + e); 2372 } catch (XmlPullParserException e) { 2373 Slog.w(TAG, "Failed parsing config " + e); 2374 } catch (IOException e) { 2375 Slog.w(TAG, "Failed parsing config " + e); 2376 } catch (IndexOutOfBoundsException e) { 2377 Slog.w(TAG, "Failed parsing config " + e); 2378 } 2379 } 2380 2381 void writeConfigFileLocked() { 2382 mHandler.removeMessages(MSG_WRITE_CONFIG); 2383 mHandler.sendEmptyMessageDelayed(MSG_WRITE_CONFIG, 5000); 2384 } 2385 2386 void handleWriteConfigFile() { 2387 final ByteArrayOutputStream memStream = new ByteArrayOutputStream(); 2388 2389 try { 2390 synchronized (this) { 2391 XmlSerializer out = new FastXmlSerializer(); 2392 out.setOutput(memStream, StandardCharsets.UTF_8.name()); 2393 writeConfigFileLocked(out); 2394 } 2395 } catch (IOException e) { 2396 } 2397 2398 synchronized (mConfigFile) { 2399 FileOutputStream stream = null; 2400 try { 2401 stream = mConfigFile.startWrite(); 2402 memStream.writeTo(stream); 2403 stream.flush(); 2404 FileUtils.sync(stream); 2405 stream.close(); 2406 mConfigFile.finishWrite(stream); 2407 } catch (IOException e) { 2408 Slog.w(TAG, "Error writing config file", e); 2409 mConfigFile.failWrite(stream); 2410 } 2411 } 2412 } 2413 2414 void writeConfigFileLocked(XmlSerializer out) throws IOException { 2415 out.startDocument(null, true); 2416 out.startTag(null, "config"); 2417 for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) { 2418 String name = mPowerSaveWhitelistUserApps.keyAt(i); 2419 out.startTag(null, "wl"); 2420 out.attribute(null, "n", name); 2421 out.endTag(null, "wl"); 2422 } 2423 out.endTag(null, "config"); 2424 out.endDocument(); 2425 } 2426 2427 static void dumpHelp(PrintWriter pw) { 2428 pw.println("Device idle controller (deviceidle) commands:"); 2429 pw.println(" help"); 2430 pw.println(" Print this help text."); 2431 pw.println(" step [light|deep]"); 2432 pw.println(" Immediately step to next state, without waiting for alarm."); 2433 pw.println(" force-idle"); 2434 pw.println(" Force directly into idle mode, regardless of other device state."); 2435 pw.println(" Use \"step\" to get out."); 2436 pw.println(" disable [light|deep|all]"); 2437 pw.println(" Completely disable device idle mode."); 2438 pw.println(" enable [light|deep|all]"); 2439 pw.println(" Re-enable device idle mode after it had previously been disabled."); 2440 pw.println(" enabled [light|deep|all]"); 2441 pw.println(" Print 1 if device idle mode is currently enabled, else 0."); 2442 pw.println(" whitelist"); 2443 pw.println(" Print currently whitelisted apps."); 2444 pw.println(" whitelist [package ...]"); 2445 pw.println(" Add (prefix with +) or remove (prefix with -) packages."); 2446 pw.println(" tempwhitelist [-u] [package ..]"); 2447 pw.println(" Temporarily place packages in whitelist for 10 seconds."); 2448 } 2449 2450 class Shell extends ShellCommand { 2451 int userId = UserHandle.USER_SYSTEM; 2452 2453 @Override 2454 public int onCommand(String cmd) { 2455 return onShellCommand(this, cmd); 2456 } 2457 2458 @Override 2459 public void onHelp() { 2460 PrintWriter pw = getOutPrintWriter(); 2461 dumpHelp(pw); 2462 } 2463 } 2464 2465 int onShellCommand(Shell shell, String cmd) { 2466 PrintWriter pw = shell.getOutPrintWriter(); 2467 if ("step".equals(cmd)) { 2468 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 2469 null); 2470 synchronized (this) { 2471 long token = Binder.clearCallingIdentity(); 2472 String arg = shell.getNextArg(); 2473 try { 2474 if (arg == null || "deep".equals(arg)) { 2475 exitForceIdleLocked(); 2476 stepIdleStateLocked("s:shell"); 2477 pw.print("Stepped to deep: "); 2478 pw.println(stateToString(mState)); 2479 } else if ("light".equals(arg)) { 2480 exitForceIdleLocked(); 2481 stepLightIdleStateLocked("s:shell"); 2482 pw.print("Stepped to light: "); pw.println(lightStateToString(mLightState)); 2483 } else { 2484 pw.println("Unknown idle mode: " + arg); 2485 } 2486 } finally { 2487 Binder.restoreCallingIdentity(token); 2488 } 2489 } 2490 } else if ("force-idle".equals(cmd)) { 2491 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 2492 null); 2493 synchronized (this) { 2494 long token = Binder.clearCallingIdentity(); 2495 try { 2496 if (!mDeepEnabled) { 2497 pw.println("Unable to go idle; not enabled"); 2498 return -1; 2499 } 2500 mForceIdle = true; 2501 becomeInactiveIfAppropriateLocked(); 2502 int curState = mState; 2503 while (curState != STATE_IDLE) { 2504 stepIdleStateLocked("s:shell"); 2505 if (curState == mState) { 2506 pw.print("Unable to go idle; stopped at "); 2507 pw.println(stateToString(mState)); 2508 exitForceIdleLocked(); 2509 return -1; 2510 } 2511 curState = mState; 2512 } 2513 pw.println("Now forced in to idle mode"); 2514 } finally { 2515 Binder.restoreCallingIdentity(token); 2516 } 2517 } 2518 } else if ("disable".equals(cmd)) { 2519 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 2520 null); 2521 synchronized (this) { 2522 long token = Binder.clearCallingIdentity(); 2523 String arg = shell.getNextArg(); 2524 try { 2525 boolean becomeActive = false; 2526 boolean valid = false; 2527 if (arg == null || "deep".equals(arg) || "all".equals(arg)) { 2528 valid = true; 2529 if (mDeepEnabled) { 2530 mDeepEnabled = false; 2531 becomeActive = true; 2532 pw.println("Deep idle mode disabled"); 2533 } 2534 } 2535 if (arg == null || "light".equals(arg) || "all".equals(arg)) { 2536 valid = true; 2537 if (mLightEnabled) { 2538 mLightEnabled = false; 2539 becomeActive = true; 2540 pw.println("Light idle mode disabled"); 2541 } 2542 } 2543 if (becomeActive) { 2544 becomeActiveLocked((arg == null ? "all" : arg) + "-disabled", 2545 Process.myUid()); 2546 } 2547 if (!valid) { 2548 pw.println("Unknown idle mode: " + arg); 2549 } 2550 } finally { 2551 Binder.restoreCallingIdentity(token); 2552 } 2553 } 2554 } else if ("enable".equals(cmd)) { 2555 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 2556 null); 2557 synchronized (this) { 2558 long token = Binder.clearCallingIdentity(); 2559 String arg = shell.getNextArg(); 2560 try { 2561 boolean becomeInactive = false; 2562 boolean valid = false; 2563 if (arg == null || "deep".equals(arg) || "all".equals(arg)) { 2564 valid = true; 2565 if (!mDeepEnabled) { 2566 mDeepEnabled = true; 2567 becomeInactive = true; 2568 pw.println("Deep idle mode enabled"); 2569 } 2570 } 2571 if (arg == null || "light".equals(arg) || "all".equals(arg)) { 2572 valid = true; 2573 if (!mLightEnabled) { 2574 mLightEnabled = true; 2575 becomeInactive = true; 2576 pw.println("Light idle mode enable"); 2577 } 2578 } 2579 if (becomeInactive) { 2580 becomeInactiveIfAppropriateLocked(); 2581 } 2582 if (!valid) { 2583 pw.println("Unknown idle mode: " + arg); 2584 } 2585 } finally { 2586 Binder.restoreCallingIdentity(token); 2587 } 2588 } 2589 } else if ("enabled".equals(cmd)) { 2590 synchronized (this) { 2591 String arg = shell.getNextArg(); 2592 if (arg == null || "all".equals(arg)) { 2593 pw.println(mDeepEnabled && mLightEnabled ? "1" : 0); 2594 } else if ("deep".equals(arg)) { 2595 pw.println(mDeepEnabled ? "1" : 0); 2596 } else if ("light".equals(arg)) { 2597 pw.println(mLightEnabled ? "1" : 0); 2598 } else { 2599 pw.println("Unknown idle mode: " + arg); 2600 } 2601 } 2602 } else if ("whitelist".equals(cmd)) { 2603 long token = Binder.clearCallingIdentity(); 2604 try { 2605 String arg = shell.getNextArg(); 2606 if (arg != null) { 2607 getContext().enforceCallingOrSelfPermission( 2608 android.Manifest.permission.DEVICE_POWER, null); 2609 do { 2610 if (arg.length() < 1 || (arg.charAt(0) != '-' 2611 && arg.charAt(0) != '+' && arg.charAt(0) != '=')) { 2612 pw.println("Package must be prefixed with +, -, or =: " + arg); 2613 return -1; 2614 } 2615 char op = arg.charAt(0); 2616 String pkg = arg.substring(1); 2617 if (op == '+') { 2618 if (addPowerSaveWhitelistAppInternal(pkg)) { 2619 pw.println("Added: " + pkg); 2620 } else { 2621 pw.println("Unknown package: " + pkg); 2622 } 2623 } else if (op == '-') { 2624 if (removePowerSaveWhitelistAppInternal(pkg)) { 2625 pw.println("Removed: " + pkg); 2626 } 2627 } else { 2628 pw.println(getPowerSaveWhitelistAppInternal(pkg)); 2629 } 2630 } while ((arg=shell.getNextArg()) != null); 2631 } else { 2632 synchronized (this) { 2633 for (int j=0; j<mPowerSaveWhitelistAppsExceptIdle.size(); j++) { 2634 pw.print("system-excidle,"); 2635 pw.print(mPowerSaveWhitelistAppsExceptIdle.keyAt(j)); 2636 pw.print(","); 2637 pw.println(mPowerSaveWhitelistAppsExceptIdle.valueAt(j)); 2638 } 2639 for (int j=0; j<mPowerSaveWhitelistApps.size(); j++) { 2640 pw.print("system,"); 2641 pw.print(mPowerSaveWhitelistApps.keyAt(j)); 2642 pw.print(","); 2643 pw.println(mPowerSaveWhitelistApps.valueAt(j)); 2644 } 2645 for (int j=0; j<mPowerSaveWhitelistUserApps.size(); j++) { 2646 pw.print("user,"); 2647 pw.print(mPowerSaveWhitelistUserApps.keyAt(j)); 2648 pw.print(","); 2649 pw.println(mPowerSaveWhitelistUserApps.valueAt(j)); 2650 } 2651 } 2652 } 2653 } finally { 2654 Binder.restoreCallingIdentity(token); 2655 } 2656 } else if ("tempwhitelist".equals(cmd)) { 2657 String opt; 2658 while ((opt=shell.getNextOption()) != null) { 2659 if ("-u".equals(opt)) { 2660 opt = shell.getNextArg(); 2661 if (opt == null) { 2662 pw.println("-u requires a user number"); 2663 return -1; 2664 } 2665 shell.userId = Integer.parseInt(opt); 2666 } 2667 } 2668 String arg = shell.getNextArg(); 2669 if (arg != null) { 2670 try { 2671 addPowerSaveTempWhitelistAppChecked(arg, 10000L, shell.userId, "shell"); 2672 } catch (RemoteException re) { 2673 pw.println("Failed: " + re); 2674 } 2675 } else { 2676 pw.println("At least one package name must be specified"); 2677 return -1; 2678 } 2679 } else { 2680 return shell.handleDefaultCommands(cmd); 2681 } 2682 return 0; 2683 } 2684 2685 void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2686 if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 2687 != PackageManager.PERMISSION_GRANTED) { 2688 pw.println("Permission Denial: can't dump DeviceIdleController from from pid=" 2689 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2690 + " without permission " + android.Manifest.permission.DUMP); 2691 return; 2692 } 2693 2694 if (args != null) { 2695 int userId = UserHandle.USER_SYSTEM; 2696 for (int i=0; i<args.length; i++) { 2697 String arg = args[i]; 2698 if ("-h".equals(arg)) { 2699 dumpHelp(pw); 2700 return; 2701 } else if ("-u".equals(arg)) { 2702 i++; 2703 if (i < args.length) { 2704 arg = args[i]; 2705 userId = Integer.parseInt(arg); 2706 } 2707 } else if ("-a".equals(arg)) { 2708 // Ignore, we always dump all. 2709 } else if (arg.length() > 0 && arg.charAt(0) == '-'){ 2710 pw.println("Unknown option: " + arg); 2711 return; 2712 } else { 2713 Shell shell = new Shell(); 2714 shell.userId = userId; 2715 String[] newArgs = new String[args.length-i]; 2716 System.arraycopy(args, i, newArgs, 0, args.length-i); 2717 shell.exec(mBinderService, null, fd, null, newArgs, new ResultReceiver(null)); 2718 return; 2719 } 2720 } 2721 } 2722 2723 synchronized (this) { 2724 mConstants.dump(pw); 2725 2726 if (mEventCmds[0] != EVENT_NULL) { 2727 pw.println(" Idling history:"); 2728 long now = SystemClock.elapsedRealtime(); 2729 for (int i=EVENT_BUFFER_SIZE-1; i>=0; i--) { 2730 int cmd = mEventCmds[i]; 2731 if (cmd == EVENT_NULL) { 2732 continue; 2733 } 2734 String label; 2735 switch (mEventCmds[i]) { 2736 case EVENT_NORMAL: label = " normal"; break; 2737 case EVENT_LIGHT_IDLE: label = " light-idle"; break; 2738 case EVENT_LIGHT_MAINTENANCE: label = "light-maint"; break; 2739 case EVENT_DEEP_IDLE: label = " deep-idle"; break; 2740 case EVENT_DEEP_MAINTENANCE: label = " deep-maint"; break; 2741 default: label = " ??"; break; 2742 } 2743 pw.print(" "); 2744 pw.print(label); 2745 pw.print(": "); 2746 TimeUtils.formatDuration(mEventTimes[i], now, pw);; 2747 pw.println(); 2748 } 2749 } 2750 2751 int size = mPowerSaveWhitelistAppsExceptIdle.size(); 2752 if (size > 0) { 2753 pw.println(" Whitelist (except idle) system apps:"); 2754 for (int i = 0; i < size; i++) { 2755 pw.print(" "); 2756 pw.println(mPowerSaveWhitelistAppsExceptIdle.keyAt(i)); 2757 } 2758 } 2759 size = mPowerSaveWhitelistApps.size(); 2760 if (size > 0) { 2761 pw.println(" Whitelist system apps:"); 2762 for (int i = 0; i < size; i++) { 2763 pw.print(" "); 2764 pw.println(mPowerSaveWhitelistApps.keyAt(i)); 2765 } 2766 } 2767 size = mPowerSaveWhitelistUserApps.size(); 2768 if (size > 0) { 2769 pw.println(" Whitelist user apps:"); 2770 for (int i = 0; i < size; i++) { 2771 pw.print(" "); 2772 pw.println(mPowerSaveWhitelistUserApps.keyAt(i)); 2773 } 2774 } 2775 size = mPowerSaveWhitelistExceptIdleAppIds.size(); 2776 if (size > 0) { 2777 pw.println(" Whitelist (except idle) all app ids:"); 2778 for (int i = 0; i < size; i++) { 2779 pw.print(" "); 2780 pw.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i)); 2781 pw.println(); 2782 } 2783 } 2784 size = mPowerSaveWhitelistUserAppIds.size(); 2785 if (size > 0) { 2786 pw.println(" Whitelist user app ids:"); 2787 for (int i = 0; i < size; i++) { 2788 pw.print(" "); 2789 pw.print(mPowerSaveWhitelistUserAppIds.keyAt(i)); 2790 pw.println(); 2791 } 2792 } 2793 size = mPowerSaveWhitelistAllAppIds.size(); 2794 if (size > 0) { 2795 pw.println(" Whitelist all app ids:"); 2796 for (int i = 0; i < size; i++) { 2797 pw.print(" "); 2798 pw.print(mPowerSaveWhitelistAllAppIds.keyAt(i)); 2799 pw.println(); 2800 } 2801 } 2802 size = mTempWhitelistAppIdEndTimes.size(); 2803 if (size > 0) { 2804 pw.println(" Temp whitelist schedule:"); 2805 final long timeNow = SystemClock.elapsedRealtime(); 2806 for (int i = 0; i < size; i++) { 2807 pw.print(" UID="); 2808 pw.print(mTempWhitelistAppIdEndTimes.keyAt(i)); 2809 pw.print(": "); 2810 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.valueAt(i); 2811 TimeUtils.formatDuration(entry.first.value, timeNow, pw); 2812 pw.print(" - "); 2813 pw.println(entry.second); 2814 } 2815 } 2816 size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0; 2817 if (size > 0) { 2818 pw.println(" Temp whitelist app ids:"); 2819 for (int i = 0; i < size; i++) { 2820 pw.print(" "); 2821 pw.print(mTempWhitelistAppIdArray[i]); 2822 pw.println(); 2823 } 2824 } 2825 2826 pw.print(" mLightEnabled="); pw.print(mLightEnabled); 2827 pw.print(" mDeepEnabled="); pw.println(mDeepEnabled); 2828 pw.print(" mForceIdle="); pw.println(mForceIdle); 2829 pw.print(" mMotionSensor="); pw.println(mMotionSensor); 2830 pw.print(" mCurDisplay="); pw.println(mCurDisplay); 2831 pw.print(" mScreenOn="); pw.println(mScreenOn); 2832 pw.print(" mCharging="); pw.println(mCharging); 2833 pw.print(" mMotionActive="); pw.println(mMotionListener.active); 2834 pw.print(" mNotMoving="); pw.println(mNotMoving); 2835 pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHasGps="); 2836 pw.print(mHasGps); pw.print(" mHasNetwork="); 2837 pw.print(mHasNetworkLocation); pw.print(" mLocated="); pw.println(mLocated); 2838 if (mLastGenericLocation != null) { 2839 pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation); 2840 } 2841 if (mLastGpsLocation != null) { 2842 pw.print(" mLastGpsLocation="); pw.println(mLastGpsLocation); 2843 } 2844 pw.print(" mState="); pw.print(stateToString(mState)); 2845 pw.print(" mLightState="); 2846 pw.println(lightStateToString(mLightState)); 2847 pw.print(" mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw); 2848 pw.println(); 2849 if (mActiveIdleOpCount != 0) { 2850 pw.print(" mActiveIdleOpCount="); pw.println(mActiveIdleOpCount); 2851 } 2852 if (mNextAlarmTime != 0) { 2853 pw.print(" mNextAlarmTime="); 2854 TimeUtils.formatDuration(mNextAlarmTime, SystemClock.elapsedRealtime(), pw); 2855 pw.println(); 2856 } 2857 if (mNextIdlePendingDelay != 0) { 2858 pw.print(" mNextIdlePendingDelay="); 2859 TimeUtils.formatDuration(mNextIdlePendingDelay, pw); 2860 pw.println(); 2861 } 2862 if (mNextIdleDelay != 0) { 2863 pw.print(" mNextIdleDelay="); 2864 TimeUtils.formatDuration(mNextIdleDelay, pw); 2865 pw.println(); 2866 } 2867 if (mNextLightIdleDelay != 0) { 2868 pw.print(" mNextIdleDelay="); 2869 TimeUtils.formatDuration(mNextLightIdleDelay, pw); 2870 pw.println(); 2871 } 2872 if (mNextLightAlarmTime != 0) { 2873 pw.print(" mNextLightAlarmTime="); 2874 TimeUtils.formatDuration(mNextLightAlarmTime, SystemClock.elapsedRealtime(), pw); 2875 pw.println(); 2876 } 2877 if (mCurIdleBudget != 0) { 2878 pw.print(" mCurIdleBudget="); 2879 TimeUtils.formatDuration(mCurIdleBudget, pw); 2880 pw.println(); 2881 } 2882 if (mMaintenanceStartTime != 0) { 2883 pw.print(" mMaintenanceStartTime="); 2884 TimeUtils.formatDuration(mMaintenanceStartTime, SystemClock.elapsedRealtime(), pw); 2885 pw.println(); 2886 } 2887 if (mJobsActive) { 2888 pw.print(" mJobsActive="); pw.println(mJobsActive); 2889 } 2890 if (mAlarmsActive) { 2891 pw.print(" mAlarmsActive="); pw.println(mAlarmsActive); 2892 } 2893 if (mDownloadServiceActive != null) { 2894 pw.print(" mDownloadServiceActive="); pw.println(mDownloadServiceActive); 2895 } 2896 } 2897 } 2898} 2899