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