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