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