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