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