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.ActivityManager; 21 import android.app.ActivityManagerInternal; 22 import android.app.AlarmManager; 23 import android.content.BroadcastReceiver; 24 import android.content.ContentResolver; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.content.IntentFilter; 28 import android.content.pm.ApplicationInfo; 29 import android.content.pm.PackageManager; 30 import android.content.pm.PackageManager.NameNotFoundException; 31 import android.database.ContentObserver; 32 import android.hardware.Sensor; 33 import android.hardware.SensorManager; 34 import android.hardware.SensorEvent; 35 import android.hardware.SensorEventListener; 36 import android.hardware.TriggerEvent; 37 import android.hardware.TriggerEventListener; 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.IDeviceIdleController; 53 import android.os.IMaintenanceActivityListener; 54 import android.os.Looper; 55 import android.os.Message; 56 import android.os.PowerManager; 57 import android.os.PowerManagerInternal; 58 import android.os.Process; 59 import android.os.RemoteCallbackList; 60 import android.os.RemoteException; 61 import android.os.ResultReceiver; 62 import android.os.ServiceManager; 63 import android.os.ShellCallback; 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 79 import com.android.internal.app.IBatteryStats; 80 import com.android.internal.os.AtomicFile; 81 import com.android.internal.os.BackgroundThread; 82 import com.android.internal.util.DumpUtils; 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 ActivityManagerInternal mLocalActivityManager; 118 private PowerManagerInternal mLocalPowerManager; 119 private PowerManager mPowerManager; 120 private ConnectivityService mConnectivityService; 121 private AlarmManagerService.LocalService mLocalAlarmManager; 122 private INetworkPolicyManager mNetworkPolicyManager; 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 AnyMotionDetector mAnyMotionDetector; 130 private boolean mLightEnabled; 131 private boolean mDeepEnabled; 132 private boolean mForceIdle; 133 private boolean mNetworkConnected; 134 private boolean mScreenOn; 135 private boolean mCharging; 136 private boolean mNotMoving; 137 private boolean mLocating; 138 private boolean mLocated; 139 private boolean mHasGps; 140 private boolean mHasNetworkLocation; 141 private Location mLastGenericLocation; 142 private Location mLastGpsLocation; 143 144 /** Device is currently active. */ 145 private static final int STATE_ACTIVE = 0; 146 /** Device is inactive (screen off, no motion) and we are waiting to for idle. */ 147 private static final int STATE_INACTIVE = 1; 148 /** Device is past the initial inactive period, and waiting for the next idle period. */ 149 private static final int STATE_IDLE_PENDING = 2; 150 /** Device is currently sensing motion. */ 151 private static final int STATE_SENSING = 3; 152 /** Device is currently finding location (and may still be sensing). */ 153 private static final int STATE_LOCATING = 4; 154 /** Device is in the idle state, trying to stay asleep as much as possible. */ 155 private static final int STATE_IDLE = 5; 156 /** Device is in the idle state, but temporarily out of idle to do regular maintenance. */ 157 private static final int STATE_IDLE_MAINTENANCE = 6; 158 private static String stateToString(int state) { 159 switch (state) { 160 case STATE_ACTIVE: return "ACTIVE"; 161 case STATE_INACTIVE: return "INACTIVE"; 162 case STATE_IDLE_PENDING: return "IDLE_PENDING"; 163 case STATE_SENSING: return "SENSING"; 164 case STATE_LOCATING: return "LOCATING"; 165 case STATE_IDLE: return "IDLE"; 166 case STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE"; 167 default: return Integer.toString(state); 168 } 169 } 170 171 /** Device is currently active. */ 172 private static final int LIGHT_STATE_ACTIVE = 0; 173 /** Device is inactive (screen off) and we are waiting to for the first light idle. */ 174 private static final int LIGHT_STATE_INACTIVE = 1; 175 /** Device is about to go idle for the first time, wait for current work to complete. */ 176 private static final int LIGHT_STATE_PRE_IDLE = 3; 177 /** Device is in the light idle state, trying to stay asleep as much as possible. */ 178 private static final int LIGHT_STATE_IDLE = 4; 179 /** Device is in the light idle state, we want to go in to idle maintenance but are 180 * waiting for network connectivity before doing so. */ 181 private static final int LIGHT_STATE_WAITING_FOR_NETWORK = 5; 182 /** Device is in the light idle state, but temporarily out of idle to do regular maintenance. */ 183 private static final int LIGHT_STATE_IDLE_MAINTENANCE = 6; 184 /** Device light idle state is overriden, now applying deep doze state. */ 185 private static final int LIGHT_STATE_OVERRIDE = 7; 186 private static String lightStateToString(int state) { 187 switch (state) { 188 case LIGHT_STATE_ACTIVE: return "ACTIVE"; 189 case LIGHT_STATE_INACTIVE: return "INACTIVE"; 190 case LIGHT_STATE_PRE_IDLE: return "PRE_IDLE"; 191 case LIGHT_STATE_IDLE: return "IDLE"; 192 case LIGHT_STATE_WAITING_FOR_NETWORK: return "WAITING_FOR_NETWORK"; 193 case LIGHT_STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE"; 194 case LIGHT_STATE_OVERRIDE: return "OVERRIDE"; 195 default: return Integer.toString(state); 196 } 197 } 198 199 private int mState; 200 private int mLightState; 201 202 private long mInactiveTimeout; 203 private long mNextAlarmTime; 204 private long mNextIdlePendingDelay; 205 private long mNextIdleDelay; 206 private long mNextLightIdleDelay; 207 private long mNextLightAlarmTime; 208 private long mNextSensingTimeoutAlarmTime; 209 private long mCurIdleBudget; 210 private long mMaintenanceStartTime; 211 212 private int mActiveIdleOpCount; 213 private PowerManager.WakeLock mActiveIdleWakeLock; // held when there are operations in progress 214 private PowerManager.WakeLock mGoingIdleWakeLock; // held when we are going idle so hardware 215 // (especially NetworkPolicyManager) can shut 216 // down. 217 private boolean mJobsActive; 218 private boolean mAlarmsActive; 219 private boolean mReportedMaintenanceActivity; 220 221 public final AtomicFile mConfigFile; 222 223 private final RemoteCallbackList<IMaintenanceActivityListener> mMaintenanceActivityListeners = 224 new RemoteCallbackList<IMaintenanceActivityListener>(); 225 226 /** 227 * Package names the system has white-listed to opt out of power save restrictions, 228 * except for device idle mode. 229 */ 230 private final ArrayMap<String, Integer> mPowerSaveWhitelistAppsExceptIdle = new ArrayMap<>(); 231 232 /** 233 * Package names the user has white-listed using commandline option to opt out of 234 * power save restrictions, except for device idle mode. 235 */ 236 private final ArraySet<String> mPowerSaveWhitelistUserAppsExceptIdle = new ArraySet<>(); 237 238 /** 239 * Package names the system has white-listed to opt out of power save restrictions for 240 * all modes. 241 */ 242 private final ArrayMap<String, Integer> mPowerSaveWhitelistApps = new ArrayMap<>(); 243 244 /** 245 * Package names the user has white-listed to opt out of power save restrictions. 246 */ 247 private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>(); 248 249 /** 250 * App IDs of built-in system apps that have been white-listed except for idle modes. 251 */ 252 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIdsExceptIdle 253 = new SparseBooleanArray(); 254 255 /** 256 * App IDs of built-in system apps that have been white-listed. 257 */ 258 private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray(); 259 260 /** 261 * App IDs that have been white-listed to opt out of power save restrictions, except 262 * for device idle modes. 263 */ 264 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray(); 265 266 /** 267 * Current app IDs that are in the complete power save white list, but shouldn't be 268 * excluded from idle modes. This array can be shared with others because it will not be 269 * modified once set. 270 */ 271 private int[] mPowerSaveWhitelistExceptIdleAppIdArray = new int[0]; 272 273 /** 274 * App IDs that have been white-listed to opt out of power save restrictions. 275 */ 276 private final SparseBooleanArray mPowerSaveWhitelistAllAppIds = new SparseBooleanArray(); 277 278 /** 279 * Current app IDs that are in the complete power save white list. This array can 280 * be shared with others because it will not be modified once set. 281 */ 282 private int[] mPowerSaveWhitelistAllAppIdArray = new int[0]; 283 284 /** 285 * App IDs that have been white-listed by the user to opt out of power save restrictions. 286 */ 287 private final SparseBooleanArray mPowerSaveWhitelistUserAppIds = new SparseBooleanArray(); 288 289 /** 290 * Current app IDs that are in the user power save white list. This array can 291 * be shared with others because it will not be modified once set. 292 */ 293 private int[] mPowerSaveWhitelistUserAppIdArray = new int[0]; 294 295 /** 296 * List of end times for UIDs that are temporarily marked as being allowed to access 297 * the network and acquire wakelocks. Times are in milliseconds. 298 */ 299 private final SparseArray<Pair<MutableLong, String>> mTempWhitelistAppIdEndTimes 300 = new SparseArray<>(); 301 302 /** 303 * Callback to the NetworkPolicyManagerService to tell it that the temp whitelist has changed. 304 */ 305 Runnable mNetworkPolicyTempWhitelistCallback; 306 307 /** 308 * Current app IDs of temporarily whitelist apps for high-priority messages. 309 */ 310 private int[] mTempWhitelistAppIdArray = new int[0]; 311 312 private static final int EVENT_NULL = 0; 313 private static final int EVENT_NORMAL = 1; 314 private static final int EVENT_LIGHT_IDLE = 2; 315 private static final int EVENT_LIGHT_MAINTENANCE = 3; 316 private static final int EVENT_DEEP_IDLE = 4; 317 private static final int EVENT_DEEP_MAINTENANCE = 5; 318 319 private final int[] mEventCmds = new int[EVENT_BUFFER_SIZE]; 320 private final long[] mEventTimes = new long[EVENT_BUFFER_SIZE]; 321 322 private void addEvent(int cmd) { 323 if (mEventCmds[0] != cmd) { 324 System.arraycopy(mEventCmds, 0, mEventCmds, 1, EVENT_BUFFER_SIZE - 1); 325 System.arraycopy(mEventTimes, 0, mEventTimes, 1, EVENT_BUFFER_SIZE - 1); 326 mEventCmds[0] = cmd; 327 mEventTimes[0] = SystemClock.elapsedRealtime(); 328 } 329 } 330 331 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 332 @Override public void onReceive(Context context, Intent intent) { 333 switch (intent.getAction()) { 334 case ConnectivityManager.CONNECTIVITY_ACTION: { 335 updateConnectivityState(intent); 336 } break; 337 case Intent.ACTION_BATTERY_CHANGED: { 338 synchronized (DeviceIdleController.this) { 339 int plugged = intent.getIntExtra("plugged", 0); 340 updateChargingLocked(plugged != 0); 341 } 342 } break; 343 case Intent.ACTION_PACKAGE_REMOVED: { 344 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 345 Uri data = intent.getData(); 346 String ssp; 347 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 348 removePowerSaveWhitelistAppInternal(ssp); 349 } 350 } 351 } break; 352 } 353 } 354 }; 355 356 private final AlarmManager.OnAlarmListener mLightAlarmListener 357 = new AlarmManager.OnAlarmListener() { 358 @Override 359 public void onAlarm() { 360 synchronized (DeviceIdleController.this) { 361 stepLightIdleStateLocked("s:alarm"); 362 } 363 } 364 }; 365 366 private final AlarmManager.OnAlarmListener mSensingTimeoutAlarmListener 367 = new AlarmManager.OnAlarmListener() { 368 @Override 369 public void onAlarm() { 370 if (mState == STATE_SENSING) { 371 synchronized (DeviceIdleController.this) { 372 becomeInactiveIfAppropriateLocked(); 373 } 374 } 375 } 376 }; 377 378 private final AlarmManager.OnAlarmListener mDeepAlarmListener 379 = new AlarmManager.OnAlarmListener() { 380 @Override 381 public void onAlarm() { 382 synchronized (DeviceIdleController.this) { 383 stepIdleStateLocked("s:alarm"); 384 } 385 } 386 }; 387 388 private final BroadcastReceiver mIdleStartedDoneReceiver = new BroadcastReceiver() { 389 @Override public void onReceive(Context context, Intent intent) { 390 // When coming out of a deep idle, we will add in some delay before we allow 391 // the system to settle down and finish the maintenance window. This is 392 // to give a chance for any pending work to be scheduled. 393 if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(intent.getAction())) { 394 mHandler.sendEmptyMessageDelayed(MSG_FINISH_IDLE_OP, 395 mConstants.MIN_DEEP_MAINTENANCE_TIME); 396 } else { 397 mHandler.sendEmptyMessageDelayed(MSG_FINISH_IDLE_OP, 398 mConstants.MIN_LIGHT_MAINTENANCE_TIME); 399 } 400 } 401 }; 402 403 private final BroadcastReceiver mInteractivityReceiver = new BroadcastReceiver() { 404 @Override 405 public void onReceive(Context context, Intent intent) { 406 synchronized (DeviceIdleController.this) { 407 updateInteractivityLocked(); 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 (result == AnyMotionDetector.RESULT_UNKNOWN)) { 978 synchronized (this) { 979 handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "non_stationary"); 980 } 981 } else if (result == AnyMotionDetector.RESULT_STATIONARY) { 982 if (mState == STATE_SENSING) { 983 // If we are currently sensing, it is time to move to locating. 984 synchronized (this) { 985 mNotMoving = true; 986 stepIdleStateLocked("s:stationary"); 987 } 988 } else if (mState == STATE_LOCATING) { 989 // If we are currently locating, note that we are not moving and step 990 // if we have located the position. 991 synchronized (this) { 992 mNotMoving = true; 993 if (mLocated) { 994 stepIdleStateLocked("s:stationary"); 995 } 996 } 997 } 998 } 999 } 1000 1001 private static final int MSG_WRITE_CONFIG = 1; 1002 private static final int MSG_REPORT_IDLE_ON = 2; 1003 private static final int MSG_REPORT_IDLE_ON_LIGHT = 3; 1004 private static final int MSG_REPORT_IDLE_OFF = 4; 1005 private static final int MSG_REPORT_ACTIVE = 5; 1006 private static final int MSG_TEMP_APP_WHITELIST_TIMEOUT = 6; 1007 private static final int MSG_REPORT_MAINTENANCE_ACTIVITY = 7; 1008 private static final int MSG_FINISH_IDLE_OP = 8; 1009 1010 final class MyHandler extends Handler { 1011 MyHandler(Looper looper) { 1012 super(looper); 1013 } 1014 1015 @Override public void handleMessage(Message msg) { 1016 if (DEBUG) Slog.d(TAG, "handleMessage(" + msg.what + ")"); 1017 switch (msg.what) { 1018 case MSG_WRITE_CONFIG: { 1019 // Does not hold a wakelock. Just let this happen whenever. 1020 handleWriteConfigFile(); 1021 } break; 1022 case MSG_REPORT_IDLE_ON: 1023 case MSG_REPORT_IDLE_ON_LIGHT: { 1024 // mGoingIdleWakeLock is held at this point 1025 EventLogTags.writeDeviceIdleOnStart(); 1026 final boolean deepChanged; 1027 final boolean lightChanged; 1028 if (msg.what == MSG_REPORT_IDLE_ON) { 1029 deepChanged = mLocalPowerManager.setDeviceIdleMode(true); 1030 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false); 1031 } else { 1032 deepChanged = mLocalPowerManager.setDeviceIdleMode(false); 1033 lightChanged = mLocalPowerManager.setLightDeviceIdleMode(true); 1034 } 1035 try { 1036 mNetworkPolicyManager.setDeviceIdleMode(true); 1037 mBatteryStats.noteDeviceIdleMode(msg.what == MSG_REPORT_IDLE_ON 1038 ? BatteryStats.DEVICE_IDLE_MODE_DEEP 1039 : BatteryStats.DEVICE_IDLE_MODE_LIGHT, null, Process.myUid()); 1040 } catch (RemoteException e) { 1041 } 1042 if (deepChanged) { 1043 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL); 1044 } 1045 if (lightChanged) { 1046 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL); 1047 } 1048 EventLogTags.writeDeviceIdleOnComplete(); 1049 mGoingIdleWakeLock.release(); 1050 } break; 1051 case MSG_REPORT_IDLE_OFF: { 1052 // mActiveIdleWakeLock is held at this point 1053 EventLogTags.writeDeviceIdleOffStart("unknown"); 1054 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false); 1055 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false); 1056 try { 1057 mNetworkPolicyManager.setDeviceIdleMode(false); 1058 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF, 1059 null, Process.myUid()); 1060 } catch (RemoteException e) { 1061 } 1062 if (deepChanged) { 1063 incActiveIdleOps(); 1064 getContext().sendOrderedBroadcastAsUser(mIdleIntent, UserHandle.ALL, 1065 null, mIdleStartedDoneReceiver, null, 0, null, null); 1066 } 1067 if (lightChanged) { 1068 incActiveIdleOps(); 1069 getContext().sendOrderedBroadcastAsUser(mLightIdleIntent, UserHandle.ALL, 1070 null, mIdleStartedDoneReceiver, null, 0, null, null); 1071 } 1072 // Always start with one active op for the message being sent here. 1073 // Now we are done! 1074 decActiveIdleOps(); 1075 EventLogTags.writeDeviceIdleOffComplete(); 1076 } break; 1077 case MSG_REPORT_ACTIVE: { 1078 // The device is awake at this point, so no wakelock necessary. 1079 String activeReason = (String)msg.obj; 1080 int activeUid = msg.arg1; 1081 EventLogTags.writeDeviceIdleOffStart( 1082 activeReason != null ? activeReason : "unknown"); 1083 final boolean deepChanged = mLocalPowerManager.setDeviceIdleMode(false); 1084 final boolean lightChanged = mLocalPowerManager.setLightDeviceIdleMode(false); 1085 try { 1086 mNetworkPolicyManager.setDeviceIdleMode(false); 1087 mBatteryStats.noteDeviceIdleMode(BatteryStats.DEVICE_IDLE_MODE_OFF, 1088 activeReason, activeUid); 1089 } catch (RemoteException e) { 1090 } 1091 if (deepChanged) { 1092 getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL); 1093 } 1094 if (lightChanged) { 1095 getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL); 1096 } 1097 EventLogTags.writeDeviceIdleOffComplete(); 1098 } break; 1099 case MSG_TEMP_APP_WHITELIST_TIMEOUT: { 1100 // TODO: What is keeping the device awake at this point? Does it need to be? 1101 int uid = msg.arg1; 1102 checkTempAppWhitelistTimeout(uid); 1103 } break; 1104 case MSG_REPORT_MAINTENANCE_ACTIVITY: { 1105 // TODO: What is keeping the device awake at this point? Does it need to be? 1106 boolean active = (msg.arg1 == 1); 1107 final int size = mMaintenanceActivityListeners.beginBroadcast(); 1108 try { 1109 for (int i = 0; i < size; i++) { 1110 try { 1111 mMaintenanceActivityListeners.getBroadcastItem(i) 1112 .onMaintenanceActivityChanged(active); 1113 } catch (RemoteException ignored) { 1114 } 1115 } 1116 } finally { 1117 mMaintenanceActivityListeners.finishBroadcast(); 1118 } 1119 } break; 1120 case MSG_FINISH_IDLE_OP: { 1121 // mActiveIdleWakeLock is held at this point 1122 decActiveIdleOps(); 1123 } break; 1124 } 1125 } 1126 } 1127 1128 final MyHandler mHandler; 1129 1130 BinderService mBinderService; 1131 1132 private final class BinderService extends IDeviceIdleController.Stub { 1133 @Override public void addPowerSaveWhitelistApp(String name) { 1134 if (DEBUG) { 1135 Slog.i(TAG, "addPowerSaveWhitelistApp(name = " + name + ")"); 1136 } 1137 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 1138 null); 1139 long ident = Binder.clearCallingIdentity(); 1140 try { 1141 addPowerSaveWhitelistAppInternal(name); 1142 } finally { 1143 Binder.restoreCallingIdentity(ident); 1144 } 1145 } 1146 1147 @Override public void removePowerSaveWhitelistApp(String name) { 1148 if (DEBUG) { 1149 Slog.i(TAG, "removePowerSaveWhitelistApp(name = " + name + ")"); 1150 } 1151 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 1152 null); 1153 long ident = Binder.clearCallingIdentity(); 1154 try { 1155 removePowerSaveWhitelistAppInternal(name); 1156 } finally { 1157 Binder.restoreCallingIdentity(ident); 1158 } 1159 } 1160 1161 @Override public String[] getSystemPowerWhitelistExceptIdle() { 1162 return getSystemPowerWhitelistExceptIdleInternal(); 1163 } 1164 1165 @Override public String[] getSystemPowerWhitelist() { 1166 return getSystemPowerWhitelistInternal(); 1167 } 1168 1169 @Override public String[] getUserPowerWhitelist() { 1170 return getUserPowerWhitelistInternal(); 1171 } 1172 1173 @Override public String[] getFullPowerWhitelistExceptIdle() { 1174 return getFullPowerWhitelistExceptIdleInternal(); 1175 } 1176 1177 @Override public String[] getFullPowerWhitelist() { 1178 return getFullPowerWhitelistInternal(); 1179 } 1180 1181 @Override public int[] getAppIdWhitelistExceptIdle() { 1182 return getAppIdWhitelistExceptIdleInternal(); 1183 } 1184 1185 @Override public int[] getAppIdWhitelist() { 1186 return getAppIdWhitelistInternal(); 1187 } 1188 1189 @Override public int[] getAppIdUserWhitelist() { 1190 return getAppIdUserWhitelistInternal(); 1191 } 1192 1193 @Override public int[] getAppIdTempWhitelist() { 1194 return getAppIdTempWhitelistInternal(); 1195 } 1196 1197 @Override public boolean isPowerSaveWhitelistExceptIdleApp(String name) { 1198 return isPowerSaveWhitelistExceptIdleAppInternal(name); 1199 } 1200 1201 @Override public boolean isPowerSaveWhitelistApp(String name) { 1202 return isPowerSaveWhitelistAppInternal(name); 1203 } 1204 1205 @Override public void addPowerSaveTempWhitelistApp(String packageName, long duration, 1206 int userId, String reason) throws RemoteException { 1207 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason); 1208 } 1209 1210 @Override public long addPowerSaveTempWhitelistAppForMms(String packageName, 1211 int userId, String reason) throws RemoteException { 1212 long duration = mConstants.MMS_TEMP_APP_WHITELIST_DURATION; 1213 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason); 1214 return duration; 1215 } 1216 1217 @Override public long addPowerSaveTempWhitelistAppForSms(String packageName, 1218 int userId, String reason) throws RemoteException { 1219 long duration = mConstants.SMS_TEMP_APP_WHITELIST_DURATION; 1220 addPowerSaveTempWhitelistAppChecked(packageName, duration, userId, reason); 1221 return duration; 1222 } 1223 1224 @Override public void exitIdle(String reason) { 1225 getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER, 1226 null); 1227 long ident = Binder.clearCallingIdentity(); 1228 try { 1229 exitIdleInternal(reason); 1230 } finally { 1231 Binder.restoreCallingIdentity(ident); 1232 } 1233 } 1234 1235 @Override public boolean registerMaintenanceActivityListener( 1236 IMaintenanceActivityListener listener) { 1237 return DeviceIdleController.this.registerMaintenanceActivityListener(listener); 1238 } 1239 1240 @Override public void unregisterMaintenanceActivityListener( 1241 IMaintenanceActivityListener listener) { 1242 DeviceIdleController.this.unregisterMaintenanceActivityListener(listener); 1243 } 1244 1245 @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1246 DeviceIdleController.this.dump(fd, pw, args); 1247 } 1248 1249 @Override public void onShellCommand(FileDescriptor in, FileDescriptor out, 1250 FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) { 1251 (new Shell()).exec(this, in, out, err, args, callback, resultReceiver); 1252 } 1253 } 1254 1255 public class LocalService { 1256 // duration in milliseconds 1257 public void addPowerSaveTempWhitelistApp(int callingUid, String packageName, 1258 long duration, int userId, boolean sync, String reason) { 1259 addPowerSaveTempWhitelistAppInternal(callingUid, packageName, duration, 1260 userId, sync, reason); 1261 } 1262 1263 // duration in milliseconds 1264 public void addPowerSaveTempWhitelistAppDirect(int appId, long duration, boolean sync, 1265 String reason) { 1266 addPowerSaveTempWhitelistAppDirectInternal(0, appId, duration, sync, reason); 1267 } 1268 1269 // duration in milliseconds 1270 public long getNotificationWhitelistDuration() { 1271 return mConstants.NOTIFICATION_WHITELIST_DURATION; 1272 } 1273 1274 public void setNetworkPolicyTempWhitelistCallback(Runnable callback) { 1275 setNetworkPolicyTempWhitelistCallbackInternal(callback); 1276 } 1277 1278 public void setJobsActive(boolean active) { 1279 DeviceIdleController.this.setJobsActive(active); 1280 } 1281 1282 // Up-call from alarm manager. 1283 public void setAlarmsActive(boolean active) { 1284 DeviceIdleController.this.setAlarmsActive(active); 1285 } 1286 1287 /** Is the app on any of the power save whitelists, whether system or user? */ 1288 public boolean isAppOnWhitelist(int appid) { 1289 return DeviceIdleController.this.isAppOnWhitelistInternal(appid); 1290 } 1291 1292 /** 1293 * Returns the array of app ids whitelisted by user. Take care not to 1294 * modify this, as it is a reference to the original copy. But the reference 1295 * can change when the list changes, so it needs to be re-acquired when 1296 * {@link PowerManager#ACTION_POWER_SAVE_WHITELIST_CHANGED} is sent. 1297 */ 1298 public int[] getPowerSaveWhitelistUserAppIds() { 1299 return DeviceIdleController.this.getPowerSaveWhitelistUserAppIds(); 1300 } 1301 } 1302 1303 public DeviceIdleController(Context context) { 1304 super(context); 1305 mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml")); 1306 mHandler = new MyHandler(BackgroundThread.getHandler().getLooper()); 1307 } 1308 1309 boolean isAppOnWhitelistInternal(int appid) { 1310 synchronized (this) { 1311 return Arrays.binarySearch(mPowerSaveWhitelistAllAppIdArray, appid) >= 0; 1312 } 1313 } 1314 1315 int[] getPowerSaveWhitelistUserAppIds() { 1316 synchronized (this) { 1317 return mPowerSaveWhitelistUserAppIdArray; 1318 } 1319 } 1320 1321 private static File getSystemDir() { 1322 return new File(Environment.getDataDirectory(), "system"); 1323 } 1324 1325 @Override 1326 public void onStart() { 1327 final PackageManager pm = getContext().getPackageManager(); 1328 1329 synchronized (this) { 1330 mLightEnabled = mDeepEnabled = getContext().getResources().getBoolean( 1331 com.android.internal.R.bool.config_enableAutoPowerModes); 1332 SystemConfig sysConfig = SystemConfig.getInstance(); 1333 ArraySet<String> allowPowerExceptIdle = sysConfig.getAllowInPowerSaveExceptIdle(); 1334 for (int i=0; i<allowPowerExceptIdle.size(); i++) { 1335 String pkg = allowPowerExceptIdle.valueAt(i); 1336 try { 1337 ApplicationInfo ai = pm.getApplicationInfo(pkg, 1338 PackageManager.MATCH_SYSTEM_ONLY); 1339 int appid = UserHandle.getAppId(ai.uid); 1340 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid); 1341 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true); 1342 } catch (PackageManager.NameNotFoundException e) { 1343 } 1344 } 1345 ArraySet<String> allowPower = sysConfig.getAllowInPowerSave(); 1346 for (int i=0; i<allowPower.size(); i++) { 1347 String pkg = allowPower.valueAt(i); 1348 try { 1349 ApplicationInfo ai = pm.getApplicationInfo(pkg, 1350 PackageManager.MATCH_SYSTEM_ONLY); 1351 int appid = UserHandle.getAppId(ai.uid); 1352 // These apps are on both the whitelist-except-idle as well 1353 // as the full whitelist, so they apply in all cases. 1354 mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid); 1355 mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true); 1356 mPowerSaveWhitelistApps.put(ai.packageName, appid); 1357 mPowerSaveWhitelistSystemAppIds.put(appid, true); 1358 } catch (PackageManager.NameNotFoundException e) { 1359 } 1360 } 1361 1362 mConstants = new Constants(mHandler, getContext().getContentResolver()); 1363 1364 readConfigFileLocked(); 1365 updateWhitelistAppIdsLocked(); 1366 1367 mNetworkConnected = true; 1368 mScreenOn = true; 1369 // Start out assuming we are charging. If we aren't, we will at least get 1370 // a battery update the next time the level drops. 1371 mCharging = true; 1372 mState = STATE_ACTIVE; 1373 mLightState = LIGHT_STATE_ACTIVE; 1374 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT; 1375 } 1376 1377 mBinderService = new BinderService(); 1378 publishBinderService(Context.DEVICE_IDLE_CONTROLLER, mBinderService); 1379 publishLocalService(LocalService.class, new LocalService()); 1380 } 1381 1382 @Override 1383 public void onBootPhase(int phase) { 1384 if (phase == PHASE_SYSTEM_SERVICES_READY) { 1385 synchronized (this) { 1386 mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); 1387 mBatteryStats = BatteryStatsService.getService(); 1388 mLocalActivityManager = getLocalService(ActivityManagerInternal.class); 1389 mLocalPowerManager = getLocalService(PowerManagerInternal.class); 1390 mPowerManager = getContext().getSystemService(PowerManager.class); 1391 mActiveIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 1392 "deviceidle_maint"); 1393 mActiveIdleWakeLock.setReferenceCounted(false); 1394 mGoingIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 1395 "deviceidle_going_idle"); 1396 mGoingIdleWakeLock.setReferenceCounted(true); 1397 mConnectivityService = (ConnectivityService)ServiceManager.getService( 1398 Context.CONNECTIVITY_SERVICE); 1399 mLocalAlarmManager = getLocalService(AlarmManagerService.LocalService.class); 1400 mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface( 1401 ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)); 1402 mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE); 1403 int sigMotionSensorId = getContext().getResources().getInteger( 1404 com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor); 1405 if (sigMotionSensorId > 0) { 1406 mMotionSensor = mSensorManager.getDefaultSensor(sigMotionSensorId, true); 1407 } 1408 if (mMotionSensor == null && getContext().getResources().getBoolean( 1409 com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) { 1410 mMotionSensor = mSensorManager.getDefaultSensor( 1411 Sensor.TYPE_WRIST_TILT_GESTURE, true); 1412 } 1413 if (mMotionSensor == null) { 1414 // As a last ditch, fall back to SMD. 1415 mMotionSensor = mSensorManager.getDefaultSensor( 1416 Sensor.TYPE_SIGNIFICANT_MOTION, true); 1417 } 1418 1419 if (getContext().getResources().getBoolean( 1420 com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) { 1421 mLocationManager = (LocationManager) getContext().getSystemService( 1422 Context.LOCATION_SERVICE); 1423 mLocationRequest = new LocationRequest() 1424 .setQuality(LocationRequest.ACCURACY_FINE) 1425 .setInterval(0) 1426 .setFastestInterval(0) 1427 .setNumUpdates(1); 1428 } 1429 1430 float angleThreshold = getContext().getResources().getInteger( 1431 com.android.internal.R.integer.config_autoPowerModeThresholdAngle) / 100f; 1432 mAnyMotionDetector = new AnyMotionDetector( 1433 (PowerManager) getContext().getSystemService(Context.POWER_SERVICE), 1434 mHandler, mSensorManager, this, angleThreshold); 1435 1436 mIdleIntent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); 1437 mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1438 | Intent.FLAG_RECEIVER_FOREGROUND); 1439 mLightIdleIntent = new Intent(PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED); 1440 mLightIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1441 | Intent.FLAG_RECEIVER_FOREGROUND); 1442 1443 IntentFilter filter = new IntentFilter(); 1444 filter.addAction(Intent.ACTION_BATTERY_CHANGED); 1445 getContext().registerReceiver(mReceiver, filter); 1446 1447 filter = new IntentFilter(); 1448 filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 1449 filter.addDataScheme("package"); 1450 getContext().registerReceiver(mReceiver, filter); 1451 1452 filter = new IntentFilter(); 1453 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 1454 getContext().registerReceiver(mReceiver, filter); 1455 1456 filter = new IntentFilter(); 1457 filter.addAction(Intent.ACTION_SCREEN_OFF); 1458 filter.addAction(Intent.ACTION_SCREEN_ON); 1459 getContext().registerReceiver(mInteractivityReceiver, filter); 1460 1461 mLocalActivityManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); 1462 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); 1463 mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray); 1464 1465 updateInteractivityLocked(); 1466 } 1467 updateConnectivityState(null); 1468 } 1469 } 1470 1471 public boolean addPowerSaveWhitelistAppInternal(String name) { 1472 synchronized (this) { 1473 try { 1474 ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name, 1475 PackageManager.MATCH_ANY_USER); 1476 if (mPowerSaveWhitelistUserApps.put(name, UserHandle.getAppId(ai.uid)) == null) { 1477 reportPowerSaveWhitelistChangedLocked(); 1478 updateWhitelistAppIdsLocked(); 1479 writeConfigFileLocked(); 1480 } 1481 return true; 1482 } catch (PackageManager.NameNotFoundException e) { 1483 return false; 1484 } 1485 } 1486 } 1487 1488 public boolean removePowerSaveWhitelistAppInternal(String name) { 1489 synchronized (this) { 1490 if (mPowerSaveWhitelistUserApps.remove(name) != null) { 1491 reportPowerSaveWhitelistChangedLocked(); 1492 updateWhitelistAppIdsLocked(); 1493 writeConfigFileLocked(); 1494 return true; 1495 } 1496 } 1497 return false; 1498 } 1499 1500 public boolean getPowerSaveWhitelistAppInternal(String name) { 1501 synchronized (this) { 1502 return mPowerSaveWhitelistUserApps.containsKey(name); 1503 } 1504 } 1505 1506 public boolean addPowerSaveWhitelistExceptIdleInternal(String name) { 1507 synchronized (this) { 1508 try { 1509 final ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name, 1510 PackageManager.MATCH_ANY_USER); 1511 if (mPowerSaveWhitelistAppsExceptIdle.put(name, UserHandle.getAppId(ai.uid)) 1512 == null) { 1513 mPowerSaveWhitelistUserAppsExceptIdle.add(name); 1514 reportPowerSaveWhitelistChangedLocked(); 1515 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray( 1516 mPowerSaveWhitelistAppsExceptIdle, mPowerSaveWhitelistUserApps, 1517 mPowerSaveWhitelistExceptIdleAppIds); 1518 } 1519 return true; 1520 } catch (PackageManager.NameNotFoundException e) { 1521 return false; 1522 } 1523 } 1524 } 1525 1526 public void resetPowerSaveWhitelistExceptIdleInternal() { 1527 synchronized (this) { 1528 if (mPowerSaveWhitelistAppsExceptIdle.removeAll( 1529 mPowerSaveWhitelistUserAppsExceptIdle)) { 1530 reportPowerSaveWhitelistChangedLocked(); 1531 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray( 1532 mPowerSaveWhitelistAppsExceptIdle, mPowerSaveWhitelistUserApps, 1533 mPowerSaveWhitelistExceptIdleAppIds); 1534 mPowerSaveWhitelistUserAppsExceptIdle.clear(); 1535 } 1536 } 1537 } 1538 1539 public boolean getPowerSaveWhitelistExceptIdleInternal(String name) { 1540 synchronized (this) { 1541 return mPowerSaveWhitelistAppsExceptIdle.containsKey(name); 1542 } 1543 } 1544 1545 public String[] getSystemPowerWhitelistExceptIdleInternal() { 1546 synchronized (this) { 1547 int size = mPowerSaveWhitelistAppsExceptIdle.size(); 1548 String[] apps = new String[size]; 1549 for (int i = 0; i < size; i++) { 1550 apps[i] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i); 1551 } 1552 return apps; 1553 } 1554 } 1555 1556 public String[] getSystemPowerWhitelistInternal() { 1557 synchronized (this) { 1558 int size = mPowerSaveWhitelistApps.size(); 1559 String[] apps = new String[size]; 1560 for (int i = 0; i < size; i++) { 1561 apps[i] = mPowerSaveWhitelistApps.keyAt(i); 1562 } 1563 return apps; 1564 } 1565 } 1566 1567 public String[] getUserPowerWhitelistInternal() { 1568 synchronized (this) { 1569 int size = mPowerSaveWhitelistUserApps.size(); 1570 String[] apps = new String[size]; 1571 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) { 1572 apps[i] = mPowerSaveWhitelistUserApps.keyAt(i); 1573 } 1574 return apps; 1575 } 1576 } 1577 1578 public String[] getFullPowerWhitelistExceptIdleInternal() { 1579 synchronized (this) { 1580 int size = mPowerSaveWhitelistAppsExceptIdle.size() + mPowerSaveWhitelistUserApps.size(); 1581 String[] apps = new String[size]; 1582 int cur = 0; 1583 for (int i = 0; i < mPowerSaveWhitelistAppsExceptIdle.size(); i++) { 1584 apps[cur] = mPowerSaveWhitelistAppsExceptIdle.keyAt(i); 1585 cur++; 1586 } 1587 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) { 1588 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i); 1589 cur++; 1590 } 1591 return apps; 1592 } 1593 } 1594 1595 public String[] getFullPowerWhitelistInternal() { 1596 synchronized (this) { 1597 int size = mPowerSaveWhitelistApps.size() + mPowerSaveWhitelistUserApps.size(); 1598 String[] apps = new String[size]; 1599 int cur = 0; 1600 for (int i = 0; i < mPowerSaveWhitelistApps.size(); i++) { 1601 apps[cur] = mPowerSaveWhitelistApps.keyAt(i); 1602 cur++; 1603 } 1604 for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) { 1605 apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i); 1606 cur++; 1607 } 1608 return apps; 1609 } 1610 } 1611 1612 public boolean isPowerSaveWhitelistExceptIdleAppInternal(String packageName) { 1613 synchronized (this) { 1614 return mPowerSaveWhitelistAppsExceptIdle.containsKey(packageName) 1615 || mPowerSaveWhitelistUserApps.containsKey(packageName); 1616 } 1617 } 1618 1619 public boolean isPowerSaveWhitelistAppInternal(String packageName) { 1620 synchronized (this) { 1621 return mPowerSaveWhitelistApps.containsKey(packageName) 1622 || mPowerSaveWhitelistUserApps.containsKey(packageName); 1623 } 1624 } 1625 1626 public int[] getAppIdWhitelistExceptIdleInternal() { 1627 synchronized (this) { 1628 return mPowerSaveWhitelistExceptIdleAppIdArray; 1629 } 1630 } 1631 1632 public int[] getAppIdWhitelistInternal() { 1633 synchronized (this) { 1634 return mPowerSaveWhitelistAllAppIdArray; 1635 } 1636 } 1637 1638 public int[] getAppIdUserWhitelistInternal() { 1639 synchronized (this) { 1640 return mPowerSaveWhitelistUserAppIdArray; 1641 } 1642 } 1643 1644 public int[] getAppIdTempWhitelistInternal() { 1645 synchronized (this) { 1646 return mTempWhitelistAppIdArray; 1647 } 1648 } 1649 1650 void addPowerSaveTempWhitelistAppChecked(String packageName, long duration, 1651 int userId, String reason) throws RemoteException { 1652 getContext().enforceCallingPermission( 1653 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, 1654 "No permission to change device idle whitelist"); 1655 final int callingUid = Binder.getCallingUid(); 1656 userId = ActivityManager.getService().handleIncomingUser( 1657 Binder.getCallingPid(), 1658 callingUid, 1659 userId, 1660 /*allowAll=*/ false, 1661 /*requireFull=*/ false, 1662 "addPowerSaveTempWhitelistApp", null); 1663 final long token = Binder.clearCallingIdentity(); 1664 try { 1665 addPowerSaveTempWhitelistAppInternal(callingUid, 1666 packageName, duration, userId, true, reason); 1667 } finally { 1668 Binder.restoreCallingIdentity(token); 1669 } 1670 } 1671 1672 /** 1673 * Adds an app to the temporary whitelist and resets the endTime for granting the 1674 * app an exemption to access network and acquire wakelocks. 1675 */ 1676 void addPowerSaveTempWhitelistAppInternal(int callingUid, String packageName, 1677 long duration, int userId, boolean sync, String reason) { 1678 try { 1679 int uid = getContext().getPackageManager().getPackageUidAsUser(packageName, userId); 1680 int appId = UserHandle.getAppId(uid); 1681 addPowerSaveTempWhitelistAppDirectInternal(callingUid, appId, duration, sync, reason); 1682 } catch (NameNotFoundException e) { 1683 } 1684 } 1685 1686 /** 1687 * Adds an app to the temporary whitelist and resets the endTime for granting the 1688 * app an exemption to access network and acquire wakelocks. 1689 */ 1690 void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int appId, 1691 long duration, boolean sync, String reason) { 1692 final long timeNow = SystemClock.elapsedRealtime(); 1693 Runnable networkPolicyTempWhitelistCallback = null; 1694 synchronized (this) { 1695 int callingAppId = UserHandle.getAppId(callingUid); 1696 if (callingAppId >= Process.FIRST_APPLICATION_UID) { 1697 if (!mPowerSaveWhitelistSystemAppIds.get(callingAppId)) { 1698 throw new SecurityException("Calling app " + UserHandle.formatUid(callingUid) 1699 + " is not on whitelist"); 1700 } 1701 } 1702 duration = Math.min(duration, mConstants.MAX_TEMP_APP_WHITELIST_DURATION); 1703 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId); 1704 final boolean newEntry = entry == null; 1705 // Set the new end time 1706 if (newEntry) { 1707 entry = new Pair<>(new MutableLong(0), reason); 1708 mTempWhitelistAppIdEndTimes.put(appId, entry); 1709 } 1710 entry.first.value = timeNow + duration; 1711 if (DEBUG) { 1712 Slog.d(TAG, "Adding AppId " + appId + " to temp whitelist. New entry: " + newEntry); 1713 } 1714 if (newEntry) { 1715 // No pending timeout for the app id, post a delayed message 1716 try { 1717 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_START, 1718 reason, appId); 1719 } catch (RemoteException e) { 1720 } 1721 postTempActiveTimeoutMessage(appId, duration); 1722 updateTempWhitelistAppIdsLocked(appId, true); 1723 if (mNetworkPolicyTempWhitelistCallback != null) { 1724 if (!sync) { 1725 mHandler.post(mNetworkPolicyTempWhitelistCallback); 1726 } else { 1727 networkPolicyTempWhitelistCallback = mNetworkPolicyTempWhitelistCallback; 1728 } 1729 } 1730 reportTempWhitelistChangedLocked(); 1731 } 1732 } 1733 if (networkPolicyTempWhitelistCallback != null) { 1734 networkPolicyTempWhitelistCallback.run(); 1735 } 1736 } 1737 1738 public void setNetworkPolicyTempWhitelistCallbackInternal(Runnable callback) { 1739 synchronized (this) { 1740 mNetworkPolicyTempWhitelistCallback = callback; 1741 } 1742 } 1743 1744 private void postTempActiveTimeoutMessage(int uid, long delay) { 1745 if (DEBUG) { 1746 Slog.d(TAG, "postTempActiveTimeoutMessage: uid=" + uid + ", delay=" + delay); 1747 } 1748 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, uid, 0), 1749 delay); 1750 } 1751 1752 void checkTempAppWhitelistTimeout(int uid) { 1753 final long timeNow = SystemClock.elapsedRealtime(); 1754 if (DEBUG) { 1755 Slog.d(TAG, "checkTempAppWhitelistTimeout: uid=" + uid + ", timeNow=" + timeNow); 1756 } 1757 synchronized (this) { 1758 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(uid); 1759 if (entry == null) { 1760 // Nothing to do 1761 return; 1762 } 1763 if (timeNow >= entry.first.value) { 1764 mTempWhitelistAppIdEndTimes.delete(uid); 1765 if (DEBUG) { 1766 Slog.d(TAG, "Removing UID " + uid + " from temp whitelist"); 1767 } 1768 updateTempWhitelistAppIdsLocked(uid, false); 1769 if (mNetworkPolicyTempWhitelistCallback != null) { 1770 mHandler.post(mNetworkPolicyTempWhitelistCallback); 1771 } 1772 reportTempWhitelistChangedLocked(); 1773 try { 1774 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH, 1775 entry.second, uid); 1776 } catch (RemoteException e) { 1777 } 1778 } else { 1779 // Need more time 1780 if (DEBUG) { 1781 Slog.d(TAG, "Time to remove UID " + uid + ": " + entry.first.value); 1782 } 1783 postTempActiveTimeoutMessage(uid, entry.first.value - timeNow); 1784 } 1785 } 1786 } 1787 1788 public void exitIdleInternal(String reason) { 1789 synchronized (this) { 1790 becomeActiveLocked(reason, Binder.getCallingUid()); 1791 } 1792 } 1793 1794 void updateConnectivityState(Intent connIntent) { 1795 ConnectivityService cm; 1796 synchronized (this) { 1797 cm = mConnectivityService; 1798 } 1799 if (cm == null) { 1800 return; 1801 } 1802 // Note: can't call out to ConnectivityService with our lock held. 1803 NetworkInfo ni = cm.getActiveNetworkInfo(); 1804 synchronized (this) { 1805 boolean conn; 1806 if (ni == null) { 1807 conn = false; 1808 } else { 1809 if (connIntent == null) { 1810 conn = ni.isConnected(); 1811 } else { 1812 final int networkType = 1813 connIntent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 1814 ConnectivityManager.TYPE_NONE); 1815 if (ni.getType() != networkType) { 1816 return; 1817 } 1818 conn = !connIntent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, 1819 false); 1820 } 1821 } 1822 if (conn != mNetworkConnected) { 1823 mNetworkConnected = conn; 1824 if (conn && mLightState == LIGHT_STATE_WAITING_FOR_NETWORK) { 1825 stepLightIdleStateLocked("network"); 1826 } 1827 } 1828 } 1829 } 1830 1831 void updateInteractivityLocked() { 1832 // The interactivity state from the power manager tells us whether the display is 1833 // in a state that we need to keep things running so they will update at a normal 1834 // frequency. 1835 boolean screenOn = mPowerManager.isInteractive(); 1836 if (DEBUG) Slog.d(TAG, "updateInteractivityLocked: screenOn=" + screenOn); 1837 if (!screenOn && mScreenOn) { 1838 mScreenOn = false; 1839 if (!mForceIdle) { 1840 becomeInactiveIfAppropriateLocked(); 1841 } 1842 } else if (screenOn) { 1843 mScreenOn = true; 1844 if (!mForceIdle) { 1845 becomeActiveLocked("screen", Process.myUid()); 1846 } 1847 } 1848 } 1849 1850 void updateChargingLocked(boolean charging) { 1851 if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging); 1852 if (!charging && mCharging) { 1853 mCharging = false; 1854 if (!mForceIdle) { 1855 becomeInactiveIfAppropriateLocked(); 1856 } 1857 } else if (charging) { 1858 mCharging = charging; 1859 if (!mForceIdle) { 1860 becomeActiveLocked("charging", Process.myUid()); 1861 } 1862 } 1863 } 1864 1865 void scheduleReportActiveLocked(String activeReason, int activeUid) { 1866 Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid, 0, activeReason); 1867 mHandler.sendMessage(msg); 1868 } 1869 1870 void becomeActiveLocked(String activeReason, int activeUid) { 1871 if (DEBUG) Slog.i(TAG, "becomeActiveLocked, reason = " + activeReason); 1872 if (mState != STATE_ACTIVE || mLightState != STATE_ACTIVE) { 1873 EventLogTags.writeDeviceIdle(STATE_ACTIVE, activeReason); 1874 EventLogTags.writeDeviceIdleLight(LIGHT_STATE_ACTIVE, activeReason); 1875 scheduleReportActiveLocked(activeReason, activeUid); 1876 mState = STATE_ACTIVE; 1877 mLightState = LIGHT_STATE_ACTIVE; 1878 mInactiveTimeout = mConstants.INACTIVE_TIMEOUT; 1879 mCurIdleBudget = 0; 1880 mMaintenanceStartTime = 0; 1881 resetIdleManagementLocked(); 1882 resetLightIdleManagementLocked(); 1883 addEvent(EVENT_NORMAL); 1884 } 1885 } 1886 1887 void becomeInactiveIfAppropriateLocked() { 1888 if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()"); 1889 if ((!mScreenOn && !mCharging) || mForceIdle) { 1890 // Screen has turned off; we are now going to become inactive and start 1891 // waiting to see if we will ultimately go idle. 1892 if (mState == STATE_ACTIVE && mDeepEnabled) { 1893 mState = STATE_INACTIVE; 1894 if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE"); 1895 resetIdleManagementLocked(); 1896 scheduleAlarmLocked(mInactiveTimeout, false); 1897 EventLogTags.writeDeviceIdle(mState, "no activity"); 1898 } 1899 if (mLightState == LIGHT_STATE_ACTIVE && mLightEnabled) { 1900 mLightState = LIGHT_STATE_INACTIVE; 1901 if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE"); 1902 resetLightIdleManagementLocked(); 1903 scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT); 1904 EventLogTags.writeDeviceIdleLight(mLightState, "no activity"); 1905 } 1906 } 1907 } 1908 1909 void resetIdleManagementLocked() { 1910 mNextIdlePendingDelay = 0; 1911 mNextIdleDelay = 0; 1912 mNextLightIdleDelay = 0; 1913 cancelAlarmLocked(); 1914 cancelSensingTimeoutAlarmLocked(); 1915 cancelLocatingLocked(); 1916 stopMonitoringMotionLocked(); 1917 mAnyMotionDetector.stop(); 1918 } 1919 1920 void resetLightIdleManagementLocked() { 1921 cancelLightAlarmLocked(); 1922 } 1923 1924 void exitForceIdleLocked() { 1925 if (mForceIdle) { 1926 mForceIdle = false; 1927 if (mScreenOn || mCharging) { 1928 becomeActiveLocked("exit-force", Process.myUid()); 1929 } 1930 } 1931 } 1932 1933 void stepLightIdleStateLocked(String reason) { 1934 if (mLightState == LIGHT_STATE_OVERRIDE) { 1935 // If we are already in deep device idle mode, then 1936 // there is nothing left to do for light mode. 1937 return; 1938 } 1939 1940 if (DEBUG) Slog.d(TAG, "stepLightIdleStateLocked: mLightState=" + mLightState); 1941 EventLogTags.writeDeviceIdleLightStep(); 1942 1943 switch (mLightState) { 1944 case LIGHT_STATE_INACTIVE: 1945 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET; 1946 // Reset the upcoming idle delays. 1947 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT; 1948 mMaintenanceStartTime = 0; 1949 if (!isOpsInactiveLocked()) { 1950 // We have some active ops going on... give them a chance to finish 1951 // before going in to our first idle. 1952 mLightState = LIGHT_STATE_PRE_IDLE; 1953 EventLogTags.writeDeviceIdleLight(mLightState, reason); 1954 scheduleLightAlarmLocked(mConstants.LIGHT_PRE_IDLE_TIMEOUT); 1955 break; 1956 } 1957 // Nothing active, fall through to immediately idle. 1958 case LIGHT_STATE_PRE_IDLE: 1959 case LIGHT_STATE_IDLE_MAINTENANCE: 1960 if (mMaintenanceStartTime != 0) { 1961 long duration = SystemClock.elapsedRealtime() - mMaintenanceStartTime; 1962 if (duration < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) { 1963 // We didn't use up all of our minimum budget; add this to the reserve. 1964 mCurIdleBudget += (mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET-duration); 1965 } else { 1966 // We used more than our minimum budget; this comes out of the reserve. 1967 mCurIdleBudget -= (duration-mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET); 1968 } 1969 } 1970 mMaintenanceStartTime = 0; 1971 scheduleLightAlarmLocked(mNextLightIdleDelay); 1972 mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT, 1973 (long)(mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR)); 1974 if (mNextLightIdleDelay < mConstants.LIGHT_IDLE_TIMEOUT) { 1975 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT; 1976 } 1977 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_STATE_IDLE."); 1978 mLightState = LIGHT_STATE_IDLE; 1979 EventLogTags.writeDeviceIdleLight(mLightState, reason); 1980 addEvent(EVENT_LIGHT_IDLE); 1981 mGoingIdleWakeLock.acquire(); 1982 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON_LIGHT); 1983 break; 1984 case LIGHT_STATE_IDLE: 1985 case LIGHT_STATE_WAITING_FOR_NETWORK: 1986 if (mNetworkConnected || mLightState == LIGHT_STATE_WAITING_FOR_NETWORK) { 1987 // We have been idling long enough, now it is time to do some work. 1988 mActiveIdleOpCount = 1; 1989 mActiveIdleWakeLock.acquire(); 1990 mMaintenanceStartTime = SystemClock.elapsedRealtime(); 1991 if (mCurIdleBudget < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) { 1992 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET; 1993 } else if (mCurIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) { 1994 mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET; 1995 } 1996 scheduleLightAlarmLocked(mCurIdleBudget); 1997 if (DEBUG) Slog.d(TAG, 1998 "Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE."); 1999 mLightState = LIGHT_STATE_IDLE_MAINTENANCE; 2000 EventLogTags.writeDeviceIdleLight(mLightState, reason); 2001 addEvent(EVENT_LIGHT_MAINTENANCE); 2002 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF); 2003 } else { 2004 // We'd like to do maintenance, but currently don't have network 2005 // connectivity... let's try to wait until the network comes back. 2006 // We'll only wait for another full idle period, however, and then give up. 2007 scheduleLightAlarmLocked(mNextLightIdleDelay); 2008 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_WAITING_FOR_NETWORK."); 2009 mLightState = LIGHT_STATE_WAITING_FOR_NETWORK; 2010 EventLogTags.writeDeviceIdleLight(mLightState, reason); 2011 } 2012 break; 2013 } 2014 } 2015 2016 void stepIdleStateLocked(String reason) { 2017 if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState); 2018 EventLogTags.writeDeviceIdleStep(); 2019 2020 final long now = SystemClock.elapsedRealtime(); 2021 if ((now+mConstants.MIN_TIME_TO_ALARM) > mAlarmManager.getNextWakeFromIdleTime()) { 2022 // Whoops, there is an upcoming alarm. We don't actually want to go idle. 2023 if (mState != STATE_ACTIVE) { 2024 becomeActiveLocked("alarm", Process.myUid()); 2025 becomeInactiveIfAppropriateLocked(); 2026 } 2027 return; 2028 } 2029 2030 switch (mState) { 2031 case STATE_INACTIVE: 2032 // We have now been inactive long enough, it is time to start looking 2033 // for motion and sleep some more while doing so. 2034 startMonitoringMotionLocked(); 2035 scheduleAlarmLocked(mConstants.IDLE_AFTER_INACTIVE_TIMEOUT, false); 2036 // Reset the upcoming idle delays. 2037 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT; 2038 mNextIdleDelay = mConstants.IDLE_TIMEOUT; 2039 mState = STATE_IDLE_PENDING; 2040 if (DEBUG) Slog.d(TAG, "Moved from STATE_INACTIVE to STATE_IDLE_PENDING."); 2041 EventLogTags.writeDeviceIdle(mState, reason); 2042 break; 2043 case STATE_IDLE_PENDING: 2044 mState = STATE_SENSING; 2045 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING."); 2046 EventLogTags.writeDeviceIdle(mState, reason); 2047 scheduleSensingTimeoutAlarmLocked(mConstants.SENSING_TIMEOUT); 2048 cancelLocatingLocked(); 2049 mNotMoving = false; 2050 mLocated = false; 2051 mLastGenericLocation = null; 2052 mLastGpsLocation = null; 2053 mAnyMotionDetector.checkForAnyMotion(); 2054 break; 2055 case STATE_SENSING: 2056 cancelSensingTimeoutAlarmLocked(); 2057 mState = STATE_LOCATING; 2058 if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING."); 2059 EventLogTags.writeDeviceIdle(mState, reason); 2060 scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT, false); 2061 if (mLocationManager != null 2062 && mLocationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) { 2063 mLocationManager.requestLocationUpdates(mLocationRequest, 2064 mGenericLocationListener, mHandler.getLooper()); 2065 mLocating = true; 2066 } else { 2067 mHasNetworkLocation = false; 2068 } 2069 if (mLocationManager != null 2070 && mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) { 2071 mHasGps = true; 2072 mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5, 2073 mGpsLocationListener, mHandler.getLooper()); 2074 mLocating = true; 2075 } else { 2076 mHasGps = false; 2077 } 2078 // If we have a location provider, we're all set, the listeners will move state 2079 // forward. 2080 if (mLocating) { 2081 break; 2082 } 2083 2084 // Otherwise, we have to move from locating into idle maintenance. 2085 case STATE_LOCATING: 2086 cancelAlarmLocked(); 2087 cancelLocatingLocked(); 2088 mAnyMotionDetector.stop(); 2089 2090 case STATE_IDLE_MAINTENANCE: 2091 scheduleAlarmLocked(mNextIdleDelay, true); 2092 if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay + 2093 " ms."); 2094 mNextIdleDelay = (long)(mNextIdleDelay * mConstants.IDLE_FACTOR); 2095 if (DEBUG) Slog.d(TAG, "Setting mNextIdleDelay = " + mNextIdleDelay); 2096 mNextIdleDelay = Math.min(mNextIdleDelay, mConstants.MAX_IDLE_TIMEOUT); 2097 if (mNextIdleDelay < mConstants.IDLE_TIMEOUT) { 2098 mNextIdleDelay = mConstants.IDLE_TIMEOUT; 2099 } 2100 mState = STATE_IDLE; 2101 if (mLightState != LIGHT_STATE_OVERRIDE) { 2102 mLightState = LIGHT_STATE_OVERRIDE; 2103 cancelLightAlarmLocked(); 2104 } 2105 EventLogTags.writeDeviceIdle(mState, reason); 2106 addEvent(EVENT_DEEP_IDLE); 2107 mGoingIdleWakeLock.acquire(); 2108 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON); 2109 break; 2110 case STATE_IDLE: 2111 // We have been idling long enough, now it is time to do some work. 2112 mActiveIdleOpCount = 1; 2113 mActiveIdleWakeLock.acquire(); 2114 scheduleAlarmLocked(mNextIdlePendingDelay, false); 2115 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE to STATE_IDLE_MAINTENANCE. " + 2116 "Next alarm in " + mNextIdlePendingDelay + " ms."); 2117 mMaintenanceStartTime = SystemClock.elapsedRealtime(); 2118 mNextIdlePendingDelay = Math.min(mConstants.MAX_IDLE_PENDING_TIMEOUT, 2119 (long)(mNextIdlePendingDelay * mConstants.IDLE_PENDING_FACTOR)); 2120 if (mNextIdlePendingDelay < mConstants.IDLE_PENDING_TIMEOUT) { 2121 mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT; 2122 } 2123 mState = STATE_IDLE_MAINTENANCE; 2124 EventLogTags.writeDeviceIdle(mState, reason); 2125 addEvent(EVENT_DEEP_MAINTENANCE); 2126 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF); 2127 break; 2128 } 2129 } 2130 2131 void incActiveIdleOps() { 2132 synchronized (this) { 2133 mActiveIdleOpCount++; 2134 } 2135 } 2136 2137 void decActiveIdleOps() { 2138 synchronized (this) { 2139 mActiveIdleOpCount--; 2140 if (mActiveIdleOpCount <= 0) { 2141 exitMaintenanceEarlyIfNeededLocked(); 2142 mActiveIdleWakeLock.release(); 2143 } 2144 } 2145 } 2146 2147 void setJobsActive(boolean active) { 2148 synchronized (this) { 2149 mJobsActive = active; 2150 reportMaintenanceActivityIfNeededLocked(); 2151 if (!active) { 2152 exitMaintenanceEarlyIfNeededLocked(); 2153 } 2154 } 2155 } 2156 2157 void setAlarmsActive(boolean active) { 2158 synchronized (this) { 2159 mAlarmsActive = active; 2160 if (!active) { 2161 exitMaintenanceEarlyIfNeededLocked(); 2162 } 2163 } 2164 } 2165 2166 boolean registerMaintenanceActivityListener(IMaintenanceActivityListener listener) { 2167 synchronized (this) { 2168 mMaintenanceActivityListeners.register(listener); 2169 return mReportedMaintenanceActivity; 2170 } 2171 } 2172 2173 void unregisterMaintenanceActivityListener(IMaintenanceActivityListener listener) { 2174 synchronized (this) { 2175 mMaintenanceActivityListeners.unregister(listener); 2176 } 2177 } 2178 2179 void reportMaintenanceActivityIfNeededLocked() { 2180 boolean active = mJobsActive; 2181 if (active == mReportedMaintenanceActivity) { 2182 return; 2183 } 2184 mReportedMaintenanceActivity = active; 2185 Message msg = mHandler.obtainMessage(MSG_REPORT_MAINTENANCE_ACTIVITY, 2186 mReportedMaintenanceActivity ? 1 : 0, 0); 2187 mHandler.sendMessage(msg); 2188 } 2189 2190 boolean isOpsInactiveLocked() { 2191 return mActiveIdleOpCount <= 0 && !mJobsActive && !mAlarmsActive; 2192 } 2193 2194 void exitMaintenanceEarlyIfNeededLocked() { 2195 if (mState == STATE_IDLE_MAINTENANCE || mLightState == LIGHT_STATE_IDLE_MAINTENANCE 2196 || mLightState == LIGHT_STATE_PRE_IDLE) { 2197 if (isOpsInactiveLocked()) { 2198 final long now = SystemClock.elapsedRealtime(); 2199 if (DEBUG) { 2200 StringBuilder sb = new StringBuilder(); 2201 sb.append("Exit: start="); 2202 TimeUtils.formatDuration(mMaintenanceStartTime, sb); 2203 sb.append(" now="); 2204 TimeUtils.formatDuration(now, sb); 2205 Slog.d(TAG, sb.toString()); 2206 } 2207 if (mState == STATE_IDLE_MAINTENANCE) { 2208 stepIdleStateLocked("s:early"); 2209 } else if (mLightState == LIGHT_STATE_PRE_IDLE) { 2210 stepLightIdleStateLocked("s:predone"); 2211 } else { 2212 stepLightIdleStateLocked("s:early"); 2213 } 2214 } 2215 } 2216 } 2217 2218 void motionLocked() { 2219 if (DEBUG) Slog.d(TAG, "motionLocked()"); 2220 // The motion sensor will have been disabled at this point 2221 handleMotionDetectedLocked(mConstants.MOTION_INACTIVE_TIMEOUT, "motion"); 2222 } 2223 2224 void handleMotionDetectedLocked(long timeout, String type) { 2225 // The device is not yet active, so we want to go back to the pending idle 2226 // state to wait again for no motion. Note that we only monitor for motion 2227 // after moving out of the inactive state, so no need to worry about that. 2228 boolean becomeInactive = false; 2229 if (mState != STATE_ACTIVE) { 2230 scheduleReportActiveLocked(type, Process.myUid()); 2231 mState = STATE_ACTIVE; 2232 mInactiveTimeout = timeout; 2233 mCurIdleBudget = 0; 2234 mMaintenanceStartTime = 0; 2235 EventLogTags.writeDeviceIdle(mState, type); 2236 addEvent(EVENT_NORMAL); 2237 becomeInactive = true; 2238 } 2239 if (mLightState == LIGHT_STATE_OVERRIDE) { 2240 // We went out of light idle mode because we had started deep idle mode... let's 2241 // now go back and reset things so we resume light idling if appropriate. 2242 mLightState = STATE_ACTIVE; 2243 EventLogTags.writeDeviceIdleLight(mLightState, type); 2244 becomeInactive = true; 2245 } 2246 if (becomeInactive) { 2247 becomeInactiveIfAppropriateLocked(); 2248 } 2249 } 2250 2251 void receivedGenericLocationLocked(Location location) { 2252 if (mState != STATE_LOCATING) { 2253 cancelLocatingLocked(); 2254 return; 2255 } 2256 if (DEBUG) Slog.d(TAG, "Generic location: " + location); 2257 mLastGenericLocation = new Location(location); 2258 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHasGps) { 2259 return; 2260 } 2261 mLocated = true; 2262 if (mNotMoving) { 2263 stepIdleStateLocked("s:location"); 2264 } 2265 } 2266 2267 void receivedGpsLocationLocked(Location location) { 2268 if (mState != STATE_LOCATING) { 2269 cancelLocatingLocked(); 2270 return; 2271 } 2272 if (DEBUG) Slog.d(TAG, "GPS location: " + location); 2273 mLastGpsLocation = new Location(location); 2274 if (location.getAccuracy() > mConstants.LOCATION_ACCURACY) { 2275 return; 2276 } 2277 mLocated = true; 2278 if (mNotMoving) { 2279 stepIdleStateLocked("s:gps"); 2280 } 2281 } 2282 2283 void startMonitoringMotionLocked() { 2284 if (DEBUG) Slog.d(TAG, "startMonitoringMotionLocked()"); 2285 if (mMotionSensor != null && !mMotionListener.active) { 2286 mMotionListener.registerLocked(); 2287 } 2288 } 2289 2290 void stopMonitoringMotionLocked() { 2291 if (DEBUG) Slog.d(TAG, "stopMonitoringMotionLocked()"); 2292 if (mMotionSensor != null && mMotionListener.active) { 2293 mMotionListener.unregisterLocked(); 2294 } 2295 } 2296 2297 void cancelAlarmLocked() { 2298 if (mNextAlarmTime != 0) { 2299 mNextAlarmTime = 0; 2300 mAlarmManager.cancel(mDeepAlarmListener); 2301 } 2302 } 2303 2304 void cancelLightAlarmLocked() { 2305 if (mNextLightAlarmTime != 0) { 2306 mNextLightAlarmTime = 0; 2307 mAlarmManager.cancel(mLightAlarmListener); 2308 } 2309 } 2310 2311 void cancelLocatingLocked() { 2312 if (mLocating) { 2313 mLocationManager.removeUpdates(mGenericLocationListener); 2314 mLocationManager.removeUpdates(mGpsLocationListener); 2315 mLocating = false; 2316 } 2317 } 2318 2319 void cancelSensingTimeoutAlarmLocked() { 2320 if (mNextSensingTimeoutAlarmTime != 0) { 2321 mNextSensingTimeoutAlarmTime = 0; 2322 mAlarmManager.cancel(mSensingTimeoutAlarmListener); 2323 } 2324 } 2325 2326 void scheduleAlarmLocked(long delay, boolean idleUntil) { 2327 if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")"); 2328 if (mMotionSensor == null) { 2329 // If there is no motion sensor on this device, then we won't schedule 2330 // alarms, because we can't determine if the device is not moving. This effectively 2331 // turns off normal execution of device idling, although it is still possible to 2332 // manually poke it by pretending like the alarm is going off. 2333 return; 2334 } 2335 mNextAlarmTime = SystemClock.elapsedRealtime() + delay; 2336 if (idleUntil) { 2337 mAlarmManager.setIdleUntil(AlarmManager.ELAPSED_REALTIME_WAKEUP, 2338 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler); 2339 } else { 2340 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 2341 mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler); 2342 } 2343 } 2344 2345 void scheduleLightAlarmLocked(long delay) { 2346 if (DEBUG) Slog.d(TAG, "scheduleLightAlarmLocked(" + delay + ")"); 2347 mNextLightAlarmTime = SystemClock.elapsedRealtime() + delay; 2348 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 2349 mNextLightAlarmTime, "DeviceIdleController.light", mLightAlarmListener, mHandler); 2350 } 2351 2352 void scheduleSensingTimeoutAlarmLocked(long delay) { 2353 if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")"); 2354 mNextSensingTimeoutAlarmTime = SystemClock.elapsedRealtime() + delay; 2355 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextSensingTimeoutAlarmTime, 2356 "DeviceIdleController.sensing", mSensingTimeoutAlarmListener, mHandler); 2357 } 2358 2359 private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps, 2360 ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds) { 2361 outAppIds.clear(); 2362 if (systemApps != null) { 2363 for (int i = 0; i < systemApps.size(); i++) { 2364 outAppIds.put(systemApps.valueAt(i), true); 2365 } 2366 } 2367 if (userApps != null) { 2368 for (int i = 0; i < userApps.size(); i++) { 2369 outAppIds.put(userApps.valueAt(i), true); 2370 } 2371 } 2372 int size = outAppIds.size(); 2373 int[] appids = new int[size]; 2374 for (int i = 0; i < size; i++) { 2375 appids[i] = outAppIds.keyAt(i); 2376 } 2377 return appids; 2378 } 2379 2380 private void updateWhitelistAppIdsLocked() { 2381 mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(mPowerSaveWhitelistAppsExceptIdle, 2382 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistExceptIdleAppIds); 2383 mPowerSaveWhitelistAllAppIdArray = buildAppIdArray(mPowerSaveWhitelistApps, 2384 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistAllAppIds); 2385 mPowerSaveWhitelistUserAppIdArray = buildAppIdArray(null, 2386 mPowerSaveWhitelistUserApps, mPowerSaveWhitelistUserAppIds); 2387 if (mLocalActivityManager != null) { 2388 if (DEBUG) { 2389 Slog.d(TAG, "Setting activity manager whitelist to " 2390 + Arrays.toString(mPowerSaveWhitelistAllAppIdArray)); 2391 } 2392 mLocalActivityManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); 2393 } 2394 if (mLocalPowerManager != null) { 2395 if (DEBUG) { 2396 Slog.d(TAG, "Setting wakelock whitelist to " 2397 + Arrays.toString(mPowerSaveWhitelistAllAppIdArray)); 2398 } 2399 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); 2400 } 2401 if (mLocalAlarmManager != null) { 2402 if (DEBUG) { 2403 Slog.d(TAG, "Setting alarm whitelist to " 2404 + Arrays.toString(mPowerSaveWhitelistUserAppIdArray)); 2405 } 2406 mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray); 2407 } 2408 } 2409 2410 private void updateTempWhitelistAppIdsLocked(int appId, boolean adding) { 2411 final int size = mTempWhitelistAppIdEndTimes.size(); 2412 if (mTempWhitelistAppIdArray.length != size) { 2413 mTempWhitelistAppIdArray = new int[size]; 2414 } 2415 for (int i = 0; i < size; i++) { 2416 mTempWhitelistAppIdArray[i] = mTempWhitelistAppIdEndTimes.keyAt(i); 2417 } 2418 if (mLocalActivityManager != null) { 2419 if (DEBUG) { 2420 Slog.d(TAG, "Setting activity manager temp whitelist to " 2421 + Arrays.toString(mTempWhitelistAppIdArray)); 2422 } 2423 mLocalActivityManager.updateDeviceIdleTempWhitelist(mTempWhitelistAppIdArray, appId, 2424 adding); 2425 } 2426 if (mLocalPowerManager != null) { 2427 if (DEBUG) { 2428 Slog.d(TAG, "Setting wakelock temp whitelist to " 2429 + Arrays.toString(mTempWhitelistAppIdArray)); 2430 } 2431 mLocalPowerManager.setDeviceIdleTempWhitelist(mTempWhitelistAppIdArray); 2432 } 2433 } 2434 2435 private void reportPowerSaveWhitelistChangedLocked() { 2436 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED); 2437 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 2438 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM); 2439 } 2440 2441 private void reportTempWhitelistChangedLocked() { 2442 Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED); 2443 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 2444 getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM); 2445 } 2446 2447 void readConfigFileLocked() { 2448 if (DEBUG) Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile()); 2449 mPowerSaveWhitelistUserApps.clear(); 2450 FileInputStream stream; 2451 try { 2452 stream = mConfigFile.openRead(); 2453 } catch (FileNotFoundException e) { 2454 return; 2455 } 2456 try { 2457 XmlPullParser parser = Xml.newPullParser(); 2458 parser.setInput(stream, StandardCharsets.UTF_8.name()); 2459 readConfigFileLocked(parser); 2460 } catch (XmlPullParserException e) { 2461 } finally { 2462 try { 2463 stream.close(); 2464 } catch (IOException e) { 2465 } 2466 } 2467 } 2468 2469 private void readConfigFileLocked(XmlPullParser parser) { 2470 final PackageManager pm = getContext().getPackageManager(); 2471 2472 try { 2473 int type; 2474 while ((type = parser.next()) != XmlPullParser.START_TAG 2475 && type != XmlPullParser.END_DOCUMENT) { 2476 ; 2477 } 2478 2479 if (type != XmlPullParser.START_TAG) { 2480 throw new IllegalStateException("no start tag found"); 2481 } 2482 2483 int outerDepth = parser.getDepth(); 2484 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 2485 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 2486 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 2487 continue; 2488 } 2489 2490 String tagName = parser.getName(); 2491 if (tagName.equals("wl")) { 2492 String name = parser.getAttributeValue(null, "n"); 2493 if (name != null) { 2494 try { 2495 ApplicationInfo ai = pm.getApplicationInfo(name, 2496 PackageManager.MATCH_ANY_USER); 2497 mPowerSaveWhitelistUserApps.put(ai.packageName, 2498 UserHandle.getAppId(ai.uid)); 2499 } catch (PackageManager.NameNotFoundException e) { 2500 } 2501 } 2502 } else { 2503 Slog.w(TAG, "Unknown element under <config>: " 2504 + parser.getName()); 2505 XmlUtils.skipCurrentTag(parser); 2506 } 2507 } 2508 2509 } catch (IllegalStateException e) { 2510 Slog.w(TAG, "Failed parsing config " + e); 2511 } catch (NullPointerException e) { 2512 Slog.w(TAG, "Failed parsing config " + e); 2513 } catch (NumberFormatException e) { 2514 Slog.w(TAG, "Failed parsing config " + e); 2515 } catch (XmlPullParserException e) { 2516 Slog.w(TAG, "Failed parsing config " + e); 2517 } catch (IOException e) { 2518 Slog.w(TAG, "Failed parsing config " + e); 2519 } catch (IndexOutOfBoundsException e) { 2520 Slog.w(TAG, "Failed parsing config " + e); 2521 } 2522 } 2523 2524 void writeConfigFileLocked() { 2525 mHandler.removeMessages(MSG_WRITE_CONFIG); 2526 mHandler.sendEmptyMessageDelayed(MSG_WRITE_CONFIG, 5000); 2527 } 2528 2529 void handleWriteConfigFile() { 2530 final ByteArrayOutputStream memStream = new ByteArrayOutputStream(); 2531 2532 try { 2533 synchronized (this) { 2534 XmlSerializer out = new FastXmlSerializer(); 2535 out.setOutput(memStream, StandardCharsets.UTF_8.name()); 2536 writeConfigFileLocked(out); 2537 } 2538 } catch (IOException e) { 2539 } 2540 2541 synchronized (mConfigFile) { 2542 FileOutputStream stream = null; 2543 try { 2544 stream = mConfigFile.startWrite(); 2545 memStream.writeTo(stream); 2546 stream.flush(); 2547 FileUtils.sync(stream); 2548 stream.close(); 2549 mConfigFile.finishWrite(stream); 2550 } catch (IOException e) { 2551 Slog.w(TAG, "Error writing config file", e); 2552 mConfigFile.failWrite(stream); 2553 } 2554 } 2555 } 2556 2557 void writeConfigFileLocked(XmlSerializer out) throws IOException { 2558 out.startDocument(null, true); 2559 out.startTag(null, "config"); 2560 for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) { 2561 String name = mPowerSaveWhitelistUserApps.keyAt(i); 2562 out.startTag(null, "wl"); 2563 out.attribute(null, "n", name); 2564 out.endTag(null, "wl"); 2565 } 2566 out.endTag(null, "config"); 2567 out.endDocument(); 2568 } 2569 2570 static void dumpHelp(PrintWriter pw) { 2571 pw.println("Device idle controller (deviceidle) commands:"); 2572 pw.println(" help"); 2573 pw.println(" Print this help text."); 2574 pw.println(" step [light|deep]"); 2575 pw.println(" Immediately step to next state, without waiting for alarm."); 2576 pw.println(" force-idle [light|deep]"); 2577 pw.println(" Force directly into idle mode, regardless of other device state."); 2578 pw.println(" force-inactive"); 2579 pw.println(" Force to be inactive, ready to freely step idle states."); 2580 pw.println(" unforce"); 2581 pw.println(" Resume normal functioning after force-idle or force-inactive."); 2582 pw.println(" get [light|deep|force|screen|charging|network]"); 2583 pw.println(" Retrieve the current given state."); 2584 pw.println(" disable [light|deep|all]"); 2585 pw.println(" Completely disable device idle mode."); 2586 pw.println(" enable [light|deep|all]"); 2587 pw.println(" Re-enable device idle mode after it had previously been disabled."); 2588 pw.println(" enabled [light|deep|all]"); 2589 pw.println(" Print 1 if device idle mode is currently enabled, else 0."); 2590 pw.println(" whitelist"); 2591 pw.println(" Print currently whitelisted apps."); 2592 pw.println(" whitelist [package ...]"); 2593 pw.println(" Add (prefix with +) or remove (prefix with -) packages."); 2594 pw.println(" except-idle-whitelist [package ...|reset]"); 2595 pw.println(" Prefix the package with '+' to add it to whitelist or " 2596 + "'=' to check if it is already whitelisted"); 2597 pw.println(" [reset] will reset the whitelist to it's original state"); 2598 pw.println(" Note that unlike <whitelist> cmd, " 2599 + "changes made using this won't be persisted across boots"); 2600 pw.println(" tempwhitelist"); 2601 pw.println(" Print packages that are temporarily whitelisted."); 2602 pw.println(" tempwhitelist [-u USER] [-d DURATION] [package ..]"); 2603 pw.println(" Temporarily place packages in whitelist for DURATION milliseconds."); 2604 pw.println(" If no DURATION is specified, 10 seconds is used"); 2605 } 2606 2607 class Shell extends ShellCommand { 2608 int userId = UserHandle.USER_SYSTEM; 2609 2610 @Override 2611 public int onCommand(String cmd) { 2612 return onShellCommand(this, cmd); 2613 } 2614 2615 @Override 2616 public void onHelp() { 2617 PrintWriter pw = getOutPrintWriter(); 2618 dumpHelp(pw); 2619 } 2620 } 2621 2622 int onShellCommand(Shell shell, String cmd) { 2623 PrintWriter pw = shell.getOutPrintWriter(); 2624 if ("step".equals(cmd)) { 2625 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 2626 null); 2627 synchronized (this) { 2628 long token = Binder.clearCallingIdentity(); 2629 String arg = shell.getNextArg(); 2630 try { 2631 if (arg == null || "deep".equals(arg)) { 2632 stepIdleStateLocked("s:shell"); 2633 pw.print("Stepped to deep: "); 2634 pw.println(stateToString(mState)); 2635 } else if ("light".equals(arg)) { 2636 stepLightIdleStateLocked("s:shell"); 2637 pw.print("Stepped to light: "); pw.println(lightStateToString(mLightState)); 2638 } else { 2639 pw.println("Unknown idle mode: " + arg); 2640 } 2641 } finally { 2642 Binder.restoreCallingIdentity(token); 2643 } 2644 } 2645 } else if ("force-idle".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 if (arg == null || "deep".equals(arg)) { 2653 if (!mDeepEnabled) { 2654 pw.println("Unable to go deep idle; not enabled"); 2655 return -1; 2656 } 2657 mForceIdle = true; 2658 becomeInactiveIfAppropriateLocked(); 2659 int curState = mState; 2660 while (curState != STATE_IDLE) { 2661 stepIdleStateLocked("s:shell"); 2662 if (curState == mState) { 2663 pw.print("Unable to go deep idle; stopped at "); 2664 pw.println(stateToString(mState)); 2665 exitForceIdleLocked(); 2666 return -1; 2667 } 2668 curState = mState; 2669 } 2670 pw.println("Now forced in to deep idle mode"); 2671 } else if ("light".equals(arg)) { 2672 mForceIdle = true; 2673 becomeInactiveIfAppropriateLocked(); 2674 int curLightState = mLightState; 2675 while (curLightState != LIGHT_STATE_IDLE) { 2676 stepIdleStateLocked("s:shell"); 2677 if (curLightState == mLightState) { 2678 pw.print("Unable to go light idle; stopped at "); 2679 pw.println(lightStateToString(mLightState)); 2680 exitForceIdleLocked(); 2681 return -1; 2682 } 2683 curLightState = mLightState; 2684 } 2685 pw.println("Now forced in to light idle mode"); 2686 } else { 2687 pw.println("Unknown idle mode: " + arg); 2688 } 2689 } finally { 2690 Binder.restoreCallingIdentity(token); 2691 } 2692 } 2693 } else if ("force-inactive".equals(cmd)) { 2694 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 2695 null); 2696 synchronized (this) { 2697 long token = Binder.clearCallingIdentity(); 2698 try { 2699 mForceIdle = true; 2700 becomeInactiveIfAppropriateLocked(); 2701 pw.print("Light state: "); 2702 pw.print(lightStateToString(mLightState)); 2703 pw.print(", deep state: "); 2704 pw.println(stateToString(mState)); 2705 } finally { 2706 Binder.restoreCallingIdentity(token); 2707 } 2708 } 2709 } else if ("unforce".equals(cmd)) { 2710 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 2711 null); 2712 synchronized (this) { 2713 long token = Binder.clearCallingIdentity(); 2714 try { 2715 exitForceIdleLocked(); 2716 pw.print("Light state: "); 2717 pw.print(lightStateToString(mLightState)); 2718 pw.print(", deep state: "); 2719 pw.println(stateToString(mState)); 2720 } finally { 2721 Binder.restoreCallingIdentity(token); 2722 } 2723 } 2724 } else if ("get".equals(cmd)) { 2725 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 2726 null); 2727 synchronized (this) { 2728 String arg = shell.getNextArg(); 2729 if (arg != null) { 2730 long token = Binder.clearCallingIdentity(); 2731 try { 2732 switch (arg) { 2733 case "light": pw.println(lightStateToString(mLightState)); break; 2734 case "deep": pw.println(stateToString(mState)); break; 2735 case "force": pw.println(mForceIdle); break; 2736 case "screen": pw.println(mScreenOn); break; 2737 case "charging": pw.println(mCharging); break; 2738 case "network": pw.println(mNetworkConnected); break; 2739 default: pw.println("Unknown get option: " + arg); break; 2740 } 2741 } finally { 2742 Binder.restoreCallingIdentity(token); 2743 } 2744 } else { 2745 pw.println("Argument required"); 2746 } 2747 } 2748 } else if ("disable".equals(cmd)) { 2749 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 2750 null); 2751 synchronized (this) { 2752 long token = Binder.clearCallingIdentity(); 2753 String arg = shell.getNextArg(); 2754 try { 2755 boolean becomeActive = false; 2756 boolean valid = false; 2757 if (arg == null || "deep".equals(arg) || "all".equals(arg)) { 2758 valid = true; 2759 if (mDeepEnabled) { 2760 mDeepEnabled = false; 2761 becomeActive = true; 2762 pw.println("Deep idle mode disabled"); 2763 } 2764 } 2765 if (arg == null || "light".equals(arg) || "all".equals(arg)) { 2766 valid = true; 2767 if (mLightEnabled) { 2768 mLightEnabled = false; 2769 becomeActive = true; 2770 pw.println("Light idle mode disabled"); 2771 } 2772 } 2773 if (becomeActive) { 2774 becomeActiveLocked((arg == null ? "all" : arg) + "-disabled", 2775 Process.myUid()); 2776 } 2777 if (!valid) { 2778 pw.println("Unknown idle mode: " + arg); 2779 } 2780 } finally { 2781 Binder.restoreCallingIdentity(token); 2782 } 2783 } 2784 } else if ("enable".equals(cmd)) { 2785 getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, 2786 null); 2787 synchronized (this) { 2788 long token = Binder.clearCallingIdentity(); 2789 String arg = shell.getNextArg(); 2790 try { 2791 boolean becomeInactive = false; 2792 boolean valid = false; 2793 if (arg == null || "deep".equals(arg) || "all".equals(arg)) { 2794 valid = true; 2795 if (!mDeepEnabled) { 2796 mDeepEnabled = true; 2797 becomeInactive = true; 2798 pw.println("Deep idle mode enabled"); 2799 } 2800 } 2801 if (arg == null || "light".equals(arg) || "all".equals(arg)) { 2802 valid = true; 2803 if (!mLightEnabled) { 2804 mLightEnabled = true; 2805 becomeInactive = true; 2806 pw.println("Light idle mode enable"); 2807 } 2808 } 2809 if (becomeInactive) { 2810 becomeInactiveIfAppropriateLocked(); 2811 } 2812 if (!valid) { 2813 pw.println("Unknown idle mode: " + arg); 2814 } 2815 } finally { 2816 Binder.restoreCallingIdentity(token); 2817 } 2818 } 2819 } else if ("enabled".equals(cmd)) { 2820 synchronized (this) { 2821 String arg = shell.getNextArg(); 2822 if (arg == null || "all".equals(arg)) { 2823 pw.println(mDeepEnabled && mLightEnabled ? "1" : 0); 2824 } else if ("deep".equals(arg)) { 2825 pw.println(mDeepEnabled ? "1" : 0); 2826 } else if ("light".equals(arg)) { 2827 pw.println(mLightEnabled ? "1" : 0); 2828 } else { 2829 pw.println("Unknown idle mode: " + arg); 2830 } 2831 } 2832 } else if ("whitelist".equals(cmd)) { 2833 String arg = shell.getNextArg(); 2834 if (arg != null) { 2835 getContext().enforceCallingOrSelfPermission( 2836 android.Manifest.permission.DEVICE_POWER, null); 2837 long token = Binder.clearCallingIdentity(); 2838 try { 2839 do { 2840 if (arg.length() < 1 || (arg.charAt(0) != '-' 2841 && arg.charAt(0) != '+' && arg.charAt(0) != '=')) { 2842 pw.println("Package must be prefixed with +, -, or =: " + arg); 2843 return -1; 2844 } 2845 char op = arg.charAt(0); 2846 String pkg = arg.substring(1); 2847 if (op == '+') { 2848 if (addPowerSaveWhitelistAppInternal(pkg)) { 2849 pw.println("Added: " + pkg); 2850 } else { 2851 pw.println("Unknown package: " + pkg); 2852 } 2853 } else if (op == '-') { 2854 if (removePowerSaveWhitelistAppInternal(pkg)) { 2855 pw.println("Removed: " + pkg); 2856 } 2857 } else { 2858 pw.println(getPowerSaveWhitelistAppInternal(pkg)); 2859 } 2860 } while ((arg=shell.getNextArg()) != null); 2861 } finally { 2862 Binder.restoreCallingIdentity(token); 2863 } 2864 } else { 2865 synchronized (this) { 2866 for (int j=0; j<mPowerSaveWhitelistAppsExceptIdle.size(); j++) { 2867 pw.print("system-excidle,"); 2868 pw.print(mPowerSaveWhitelistAppsExceptIdle.keyAt(j)); 2869 pw.print(","); 2870 pw.println(mPowerSaveWhitelistAppsExceptIdle.valueAt(j)); 2871 } 2872 for (int j=0; j<mPowerSaveWhitelistApps.size(); j++) { 2873 pw.print("system,"); 2874 pw.print(mPowerSaveWhitelistApps.keyAt(j)); 2875 pw.print(","); 2876 pw.println(mPowerSaveWhitelistApps.valueAt(j)); 2877 } 2878 for (int j=0; j<mPowerSaveWhitelistUserApps.size(); j++) { 2879 pw.print("user,"); 2880 pw.print(mPowerSaveWhitelistUserApps.keyAt(j)); 2881 pw.print(","); 2882 pw.println(mPowerSaveWhitelistUserApps.valueAt(j)); 2883 } 2884 } 2885 } 2886 } else if ("tempwhitelist".equals(cmd)) { 2887 long duration = 10000; 2888 String opt; 2889 while ((opt=shell.getNextOption()) != null) { 2890 if ("-u".equals(opt)) { 2891 opt = shell.getNextArg(); 2892 if (opt == null) { 2893 pw.println("-u requires a user number"); 2894 return -1; 2895 } 2896 shell.userId = Integer.parseInt(opt); 2897 } else if ("-d".equals(opt)) { 2898 opt = shell.getNextArg(); 2899 if (opt == null) { 2900 pw.println("-d requires a duration"); 2901 return -1; 2902 } 2903 duration = Long.parseLong(opt); 2904 } 2905 } 2906 String arg = shell.getNextArg(); 2907 if (arg != null) { 2908 try { 2909 addPowerSaveTempWhitelistAppChecked(arg, duration, shell.userId, "shell"); 2910 } catch (Exception e) { 2911 pw.println("Failed: " + e); 2912 return -1; 2913 } 2914 } else { 2915 dumpTempWhitelistSchedule(pw, false); 2916 } 2917 } else if ("except-idle-whitelist".equals(cmd)) { 2918 getContext().enforceCallingOrSelfPermission( 2919 android.Manifest.permission.DEVICE_POWER, null); 2920 final long token = Binder.clearCallingIdentity(); 2921 try { 2922 String arg = shell.getNextArg(); 2923 if (arg == null) { 2924 pw.println("No arguments given"); 2925 return -1; 2926 } else if ("reset".equals(arg)) { 2927 resetPowerSaveWhitelistExceptIdleInternal(); 2928 } else { 2929 do { 2930 if (arg.length() < 1 || (arg.charAt(0) != '-' 2931 && arg.charAt(0) != '+' && arg.charAt(0) != '=')) { 2932 pw.println("Package must be prefixed with +, -, or =: " + arg); 2933 return -1; 2934 } 2935 char op = arg.charAt(0); 2936 String pkg = arg.substring(1); 2937 if (op == '+') { 2938 if (addPowerSaveWhitelistExceptIdleInternal(pkg)) { 2939 pw.println("Added: " + pkg); 2940 } else { 2941 pw.println("Unknown package: " + pkg); 2942 } 2943 } else if (op == '=') { 2944 pw.println(getPowerSaveWhitelistExceptIdleInternal(pkg)); 2945 } else { 2946 pw.println("Unknown argument: " + arg); 2947 return -1; 2948 } 2949 } while ((arg = shell.getNextArg()) != null); 2950 } 2951 } finally { 2952 Binder.restoreCallingIdentity(token); 2953 } 2954 } else { 2955 return shell.handleDefaultCommands(cmd); 2956 } 2957 return 0; 2958 } 2959 2960 void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2961 if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return; 2962 2963 if (args != null) { 2964 int userId = UserHandle.USER_SYSTEM; 2965 for (int i=0; i<args.length; i++) { 2966 String arg = args[i]; 2967 if ("-h".equals(arg)) { 2968 dumpHelp(pw); 2969 return; 2970 } else if ("-u".equals(arg)) { 2971 i++; 2972 if (i < args.length) { 2973 arg = args[i]; 2974 userId = Integer.parseInt(arg); 2975 } 2976 } else if ("-a".equals(arg)) { 2977 // Ignore, we always dump all. 2978 } else if (arg.length() > 0 && arg.charAt(0) == '-'){ 2979 pw.println("Unknown option: " + arg); 2980 return; 2981 } else { 2982 Shell shell = new Shell(); 2983 shell.userId = userId; 2984 String[] newArgs = new String[args.length-i]; 2985 System.arraycopy(args, i, newArgs, 0, args.length-i); 2986 shell.exec(mBinderService, null, fd, null, newArgs, null, 2987 new ResultReceiver(null)); 2988 return; 2989 } 2990 } 2991 } 2992 2993 synchronized (this) { 2994 mConstants.dump(pw); 2995 2996 if (mEventCmds[0] != EVENT_NULL) { 2997 pw.println(" Idling history:"); 2998 long now = SystemClock.elapsedRealtime(); 2999 for (int i=EVENT_BUFFER_SIZE-1; i>=0; i--) { 3000 int cmd = mEventCmds[i]; 3001 if (cmd == EVENT_NULL) { 3002 continue; 3003 } 3004 String label; 3005 switch (mEventCmds[i]) { 3006 case EVENT_NORMAL: label = " normal"; break; 3007 case EVENT_LIGHT_IDLE: label = " light-idle"; break; 3008 case EVENT_LIGHT_MAINTENANCE: label = "light-maint"; break; 3009 case EVENT_DEEP_IDLE: label = " deep-idle"; break; 3010 case EVENT_DEEP_MAINTENANCE: label = " deep-maint"; break; 3011 default: label = " ??"; break; 3012 } 3013 pw.print(" "); 3014 pw.print(label); 3015 pw.print(": "); 3016 TimeUtils.formatDuration(mEventTimes[i], now, pw);; 3017 pw.println(); 3018 } 3019 } 3020 3021 int size = mPowerSaveWhitelistAppsExceptIdle.size(); 3022 if (size > 0) { 3023 pw.println(" Whitelist (except idle) system apps:"); 3024 for (int i = 0; i < size; i++) { 3025 pw.print(" "); 3026 pw.println(mPowerSaveWhitelistAppsExceptIdle.keyAt(i)); 3027 } 3028 } 3029 size = mPowerSaveWhitelistApps.size(); 3030 if (size > 0) { 3031 pw.println(" Whitelist system apps:"); 3032 for (int i = 0; i < size; i++) { 3033 pw.print(" "); 3034 pw.println(mPowerSaveWhitelistApps.keyAt(i)); 3035 } 3036 } 3037 size = mPowerSaveWhitelistUserApps.size(); 3038 if (size > 0) { 3039 pw.println(" Whitelist user apps:"); 3040 for (int i = 0; i < size; i++) { 3041 pw.print(" "); 3042 pw.println(mPowerSaveWhitelistUserApps.keyAt(i)); 3043 } 3044 } 3045 size = mPowerSaveWhitelistExceptIdleAppIds.size(); 3046 if (size > 0) { 3047 pw.println(" Whitelist (except idle) all app ids:"); 3048 for (int i = 0; i < size; i++) { 3049 pw.print(" "); 3050 pw.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i)); 3051 pw.println(); 3052 } 3053 } 3054 size = mPowerSaveWhitelistUserAppIds.size(); 3055 if (size > 0) { 3056 pw.println(" Whitelist user app ids:"); 3057 for (int i = 0; i < size; i++) { 3058 pw.print(" "); 3059 pw.print(mPowerSaveWhitelistUserAppIds.keyAt(i)); 3060 pw.println(); 3061 } 3062 } 3063 size = mPowerSaveWhitelistAllAppIds.size(); 3064 if (size > 0) { 3065 pw.println(" Whitelist all app ids:"); 3066 for (int i = 0; i < size; i++) { 3067 pw.print(" "); 3068 pw.print(mPowerSaveWhitelistAllAppIds.keyAt(i)); 3069 pw.println(); 3070 } 3071 } 3072 dumpTempWhitelistSchedule(pw, true); 3073 3074 size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0; 3075 if (size > 0) { 3076 pw.println(" Temp whitelist app ids:"); 3077 for (int i = 0; i < size; i++) { 3078 pw.print(" "); 3079 pw.print(mTempWhitelistAppIdArray[i]); 3080 pw.println(); 3081 } 3082 } 3083 3084 pw.print(" mLightEnabled="); pw.print(mLightEnabled); 3085 pw.print(" mDeepEnabled="); pw.println(mDeepEnabled); 3086 pw.print(" mForceIdle="); pw.println(mForceIdle); 3087 pw.print(" mMotionSensor="); pw.println(mMotionSensor); 3088 pw.print(" mScreenOn="); pw.println(mScreenOn); 3089 pw.print(" mNetworkConnected="); pw.println(mNetworkConnected); 3090 pw.print(" mCharging="); pw.println(mCharging); 3091 pw.print(" mMotionActive="); pw.println(mMotionListener.active); 3092 pw.print(" mNotMoving="); pw.println(mNotMoving); 3093 pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHasGps="); 3094 pw.print(mHasGps); pw.print(" mHasNetwork="); 3095 pw.print(mHasNetworkLocation); pw.print(" mLocated="); pw.println(mLocated); 3096 if (mLastGenericLocation != null) { 3097 pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation); 3098 } 3099 if (mLastGpsLocation != null) { 3100 pw.print(" mLastGpsLocation="); pw.println(mLastGpsLocation); 3101 } 3102 pw.print(" mState="); pw.print(stateToString(mState)); 3103 pw.print(" mLightState="); 3104 pw.println(lightStateToString(mLightState)); 3105 pw.print(" mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw); 3106 pw.println(); 3107 if (mActiveIdleOpCount != 0) { 3108 pw.print(" mActiveIdleOpCount="); pw.println(mActiveIdleOpCount); 3109 } 3110 if (mNextAlarmTime != 0) { 3111 pw.print(" mNextAlarmTime="); 3112 TimeUtils.formatDuration(mNextAlarmTime, SystemClock.elapsedRealtime(), pw); 3113 pw.println(); 3114 } 3115 if (mNextIdlePendingDelay != 0) { 3116 pw.print(" mNextIdlePendingDelay="); 3117 TimeUtils.formatDuration(mNextIdlePendingDelay, pw); 3118 pw.println(); 3119 } 3120 if (mNextIdleDelay != 0) { 3121 pw.print(" mNextIdleDelay="); 3122 TimeUtils.formatDuration(mNextIdleDelay, pw); 3123 pw.println(); 3124 } 3125 if (mNextLightIdleDelay != 0) { 3126 pw.print(" mNextIdleDelay="); 3127 TimeUtils.formatDuration(mNextLightIdleDelay, pw); 3128 pw.println(); 3129 } 3130 if (mNextLightAlarmTime != 0) { 3131 pw.print(" mNextLightAlarmTime="); 3132 TimeUtils.formatDuration(mNextLightAlarmTime, SystemClock.elapsedRealtime(), pw); 3133 pw.println(); 3134 } 3135 if (mCurIdleBudget != 0) { 3136 pw.print(" mCurIdleBudget="); 3137 TimeUtils.formatDuration(mCurIdleBudget, pw); 3138 pw.println(); 3139 } 3140 if (mMaintenanceStartTime != 0) { 3141 pw.print(" mMaintenanceStartTime="); 3142 TimeUtils.formatDuration(mMaintenanceStartTime, SystemClock.elapsedRealtime(), pw); 3143 pw.println(); 3144 } 3145 if (mJobsActive) { 3146 pw.print(" mJobsActive="); pw.println(mJobsActive); 3147 } 3148 if (mAlarmsActive) { 3149 pw.print(" mAlarmsActive="); pw.println(mAlarmsActive); 3150 } 3151 } 3152 } 3153 3154 void dumpTempWhitelistSchedule(PrintWriter pw, boolean printTitle) { 3155 final int size = mTempWhitelistAppIdEndTimes.size(); 3156 if (size > 0) { 3157 String prefix = ""; 3158 if (printTitle) { 3159 pw.println(" Temp whitelist schedule:"); 3160 prefix = " "; 3161 } 3162 final long timeNow = SystemClock.elapsedRealtime(); 3163 for (int i = 0; i < size; i++) { 3164 pw.print(prefix); 3165 pw.print("UID="); 3166 pw.print(mTempWhitelistAppIdEndTimes.keyAt(i)); 3167 pw.print(": "); 3168 Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.valueAt(i); 3169 TimeUtils.formatDuration(entry.first.value, timeNow, pw); 3170 pw.print(" - "); 3171 pw.println(entry.second); 3172 } 3173 } 3174 } 3175 } 3176