PowerManagerService.java revision 88c997a5abb3b2b2df1fb17fa3af40b34fbdd590
1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.power; 18 19import com.android.internal.app.IBatteryStats; 20import com.android.server.BatteryService; 21import com.android.server.EventLogTags; 22import com.android.server.LightsService; 23import com.android.server.Watchdog; 24import com.android.server.am.BatteryStatsService; 25 26import android.app.ActivityManagerNative; 27import android.app.IActivityManager; 28import android.content.BroadcastReceiver; 29import android.content.ContentQueryMap; 30import android.content.ContentResolver; 31import android.content.ContentValues; 32import android.content.Context; 33import android.content.Intent; 34import android.content.IntentFilter; 35import android.content.pm.PackageManager; 36import android.content.res.Resources; 37import android.database.ContentObserver; 38import android.database.Cursor; 39import android.hardware.Sensor; 40import android.hardware.SensorEvent; 41import android.hardware.SensorEventListener; 42import android.hardware.SensorManager; 43import android.hardware.SystemSensorManager; 44import android.os.BatteryManager; 45import android.os.BatteryStats; 46import android.os.Binder; 47import android.os.Handler; 48import android.os.HandlerThread; 49import android.os.IBinder; 50import android.os.IPowerManager; 51import android.os.LocalPowerManager; 52import android.os.Message; 53import android.os.PowerManager; 54import android.os.Process; 55import android.os.RemoteException; 56import android.os.SystemClock; 57import android.os.SystemProperties; 58import android.os.WorkSource; 59import android.provider.Settings; 60import android.util.EventLog; 61import android.util.Log; 62import android.util.Slog; 63import android.view.WindowManagerPolicy; 64import static android.view.WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR; 65import static android.provider.Settings.System.DIM_SCREEN; 66import static android.provider.Settings.System.SCREEN_BRIGHTNESS; 67import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE; 68import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC; 69import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; 70import static android.provider.Settings.System.STAY_ON_WHILE_PLUGGED_IN; 71import static android.provider.Settings.System.WINDOW_ANIMATION_SCALE; 72import static android.provider.Settings.System.TRANSITION_ANIMATION_SCALE; 73 74import java.io.FileDescriptor; 75import java.io.IOException; 76import java.io.PrintWriter; 77import java.util.ArrayList; 78import java.util.HashMap; 79import java.util.Observable; 80import java.util.Observer; 81 82public class PowerManagerService extends IPowerManager.Stub 83 implements LocalPowerManager, Watchdog.Monitor { 84 private static final int NOMINAL_FRAME_TIME_MS = 1000/60; 85 86 private static final String TAG = "PowerManagerService"; 87 static final String PARTIAL_NAME = "PowerManagerService"; 88 89 // could be either static or controllable at runtime 90 private static final boolean DEBUG = false; 91 private static final boolean DEBUG_PROXIMITY_SENSOR = (false || DEBUG); 92 private static final boolean DEBUG_LIGHT_SENSOR = (false || DEBUG); 93 private static final boolean DEBUG_LIGHT_ANIMATION = (false || DEBUG); 94 private static final boolean DEBUG_SCREEN_ON = false; 95 96 // Wake lock that ensures that the CPU is running. The screen might not be on. 97 private static final int PARTIAL_WAKE_LOCK_ID = 1; 98 99 // Wake lock that ensures that the screen is on. 100 private static final int FULL_WAKE_LOCK_ID = 2; 101 102 private static final boolean LOG_PARTIAL_WL = false; 103 104 private static final int LOCK_MASK = PowerManager.PARTIAL_WAKE_LOCK 105 | PowerManager.SCREEN_DIM_WAKE_LOCK 106 | PowerManager.SCREEN_BRIGHT_WAKE_LOCK 107 | PowerManager.FULL_WAKE_LOCK 108 | PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK; 109 110 // time since last state: time since last event: 111 // The short keylight delay comes from secure settings; this is the default. 112 private static final int SHORT_KEYLIGHT_DELAY_DEFAULT = 6000; // t+6 sec 113 private static final int MEDIUM_KEYLIGHT_DELAY = 15000; // t+15 sec 114 private static final int LONG_KEYLIGHT_DELAY = 6000; // t+6 sec 115 private static final int LONG_DIM_TIME = 7000; // t+N-5 sec 116 117 // How long to wait to debounce light sensor changes in milliseconds 118 private static final int LIGHT_SENSOR_DELAY = 2000; 119 120 // light sensor events rate in microseconds 121 private static final int LIGHT_SENSOR_RATE = 1000000; 122 123 // Expansion of range of light values when applying scale from light 124 // sensor brightness setting, in the [0..255] brightness range. 125 private static final int LIGHT_SENSOR_RANGE_EXPANSION = 20; 126 127 // Scaling factor of the light sensor brightness setting when applying 128 // it to the final brightness. 129 private static final int LIGHT_SENSOR_OFFSET_SCALE = 8; 130 131 // For debouncing the proximity sensor in milliseconds 132 private static final int PROXIMITY_SENSOR_DELAY = 1000; 133 134 // trigger proximity if distance is less than 5 cm 135 private static final float PROXIMITY_THRESHOLD = 5.0f; 136 137 // Cached secure settings; see updateSettingsValues() 138 private int mShortKeylightDelay = SHORT_KEYLIGHT_DELAY_DEFAULT; 139 140 // Default timeout for screen off, if not found in settings database = 15 seconds. 141 private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15000; 142 143 // Screen brightness should always have a value, but just in case... 144 private static final int DEFAULT_SCREEN_BRIGHTNESS = 192; 145 146 // Threshold for BRIGHTNESS_LOW_BATTERY (percentage) 147 // Screen will stay dim if battery level is <= LOW_BATTERY_THRESHOLD 148 private static final int LOW_BATTERY_THRESHOLD = 10; 149 150 // flags for setPowerState 151 private static final int ALL_LIGHTS_OFF = 0x00000000; 152 private static final int SCREEN_ON_BIT = 0x00000001; 153 private static final int SCREEN_BRIGHT_BIT = 0x00000002; 154 private static final int BUTTON_BRIGHT_BIT = 0x00000004; 155 private static final int KEYBOARD_BRIGHT_BIT = 0x00000008; 156 private static final int BATTERY_LOW_BIT = 0x00000010; 157 158 // values for setPowerState 159 160 // SCREEN_OFF == everything off 161 private static final int SCREEN_OFF = 0x00000000; 162 163 // SCREEN_DIM == screen on, screen backlight dim 164 private static final int SCREEN_DIM = SCREEN_ON_BIT; 165 166 // SCREEN_BRIGHT == screen on, screen backlight bright 167 private static final int SCREEN_BRIGHT = SCREEN_ON_BIT | SCREEN_BRIGHT_BIT; 168 169 // SCREEN_BUTTON_BRIGHT == screen on, screen and button backlights bright 170 private static final int SCREEN_BUTTON_BRIGHT = SCREEN_BRIGHT | BUTTON_BRIGHT_BIT; 171 172 // SCREEN_BUTTON_BRIGHT == screen on, screen, button and keyboard backlights bright 173 private static final int ALL_BRIGHT = SCREEN_BUTTON_BRIGHT | KEYBOARD_BRIGHT_BIT; 174 175 // used for noChangeLights in setPowerState() 176 private static final int LIGHTS_MASK = SCREEN_BRIGHT_BIT | BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT; 177 178 // animate screen lights in PowerManager (as opposed to SurfaceFlinger) 179 boolean mAnimateScreenLights = true; 180 181 static final int ANIM_STEPS = 60; // nominal # of frames at 60Hz 182 // Slower animation for autobrightness changes 183 static final int AUTOBRIGHTNESS_ANIM_STEPS = 2 * ANIM_STEPS; 184 // Even slower animation for autodimness changes. Set to max to effectively disable dimming. 185 // Note 100 is used to keep the mWindowScaleAnimation scaling below from overflowing an int. 186 static final int AUTODIMNESS_ANIM_STEPS = Integer.MAX_VALUE / (NOMINAL_FRAME_TIME_MS * 100); 187 // Number of steps when performing a more immediate brightness change. 188 static final int IMMEDIATE_ANIM_STEPS = 4; 189 190 // These magic numbers are the initial state of the LEDs at boot. Ideally 191 // we should read them from the driver, but our current hardware returns 0 192 // for the initial value. Oops! 193 static final int INITIAL_SCREEN_BRIGHTNESS = 255; 194 static final int INITIAL_BUTTON_BRIGHTNESS = PowerManager.BRIGHTNESS_OFF; 195 static final int INITIAL_KEYBOARD_BRIGHTNESS = PowerManager.BRIGHTNESS_OFF; 196 197 private final int MY_UID; 198 private final int MY_PID; 199 200 private boolean mDoneBooting = false; 201 private boolean mBootCompleted = false; 202 private boolean mHeadless = false; 203 private int mStayOnConditions = 0; 204 private final int[] mBroadcastQueue = new int[] { -1, -1, -1 }; 205 private final int[] mBroadcastWhy = new int[3]; 206 private boolean mPreparingForScreenOn = false; 207 private boolean mSkippedScreenOn = false; 208 private boolean mInitialized = false; 209 private int mPartialCount = 0; 210 private int mPowerState; 211 // mScreenOffReason can be WindowManagerPolicy.OFF_BECAUSE_OF_USER, 212 // WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT or WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR 213 private int mScreenOffReason; 214 private int mUserState; 215 private boolean mKeyboardVisible = false; 216 private boolean mUserActivityAllowed = true; 217 private int mProximityWakeLockCount = 0; 218 private boolean mProximitySensorEnabled = false; 219 private boolean mProximitySensorActive = false; 220 private int mProximityPendingValue = -1; // -1 == nothing, 0 == inactive, 1 == active 221 private long mLastProximityEventTime; 222 private int mScreenOffTimeoutSetting; 223 private int mMaximumScreenOffTimeout = Integer.MAX_VALUE; 224 private int mKeylightDelay; 225 private int mDimDelay; 226 private int mScreenOffDelay; 227 private int mWakeLockState; 228 private long mLastEventTime = 0; 229 private long mScreenOffTime; 230 private volatile WindowManagerPolicy mPolicy; 231 private final LockList mLocks = new LockList(); 232 private Intent mScreenOffIntent; 233 private Intent mScreenOnIntent; 234 private LightsService mLightsService; 235 private Context mContext; 236 private LightsService.Light mLcdLight; 237 private LightsService.Light mButtonLight; 238 private LightsService.Light mKeyboardLight; 239 private LightsService.Light mAttentionLight; 240 private UnsynchronizedWakeLock mBroadcastWakeLock; 241 private UnsynchronizedWakeLock mStayOnWhilePluggedInScreenDimLock; 242 private UnsynchronizedWakeLock mStayOnWhilePluggedInPartialLock; 243 private UnsynchronizedWakeLock mPreventScreenOnPartialLock; 244 private UnsynchronizedWakeLock mProximityPartialLock; 245 private HandlerThread mHandlerThread; 246 private Handler mScreenOffHandler; 247 private Handler mScreenBrightnessHandler; 248 private Handler mHandler; 249 private final TimeoutTask mTimeoutTask = new TimeoutTask(); 250 private ScreenBrightnessAnimator mScreenBrightnessAnimator; 251 private boolean mWaitingForFirstLightSensor = false; 252 private boolean mStillNeedSleepNotification; 253 private boolean mIsPowered = false; 254 private IActivityManager mActivityService; 255 private IBatteryStats mBatteryStats; 256 private BatteryService mBatteryService; 257 private SensorManager mSensorManager; 258 private Sensor mProximitySensor; 259 private Sensor mLightSensor; 260 private boolean mLightSensorEnabled; 261 private float mLightSensorValue = -1; 262 private boolean mProxIgnoredBecauseScreenTurnedOff = false; 263 private int mHighestLightSensorValue = -1; 264 private boolean mLightSensorPendingDecrease = false; 265 private boolean mLightSensorPendingIncrease = false; 266 private float mLightSensorPendingValue = -1; 267 private float mLightSensorAdjustSetting = 0; 268 private int mLightSensorScreenBrightness = -1; 269 private int mLightSensorButtonBrightness = -1; 270 private int mLightSensorKeyboardBrightness = -1; 271 private boolean mDimScreen = true; 272 private boolean mIsDocked = false; 273 private long mNextTimeout; 274 private volatile int mPokey = 0; 275 private volatile boolean mPokeAwakeOnSet = false; 276 private volatile boolean mInitComplete = false; 277 private final HashMap<IBinder,PokeLock> mPokeLocks = new HashMap<IBinder,PokeLock>(); 278 // mLastScreenOnTime is the time the screen was last turned on 279 private long mLastScreenOnTime; 280 private boolean mPreventScreenOn; 281 private int mScreenBrightnessSetting = DEFAULT_SCREEN_BRIGHTNESS; 282 private int mScreenBrightnessOverride = -1; 283 private int mButtonBrightnessOverride = -1; 284 private int mScreenBrightnessDim; 285 private boolean mUseSoftwareAutoBrightness; 286 private boolean mAutoBrightessEnabled; 287 private int[] mAutoBrightnessLevels; 288 private int[] mLcdBacklightValues; 289 private int[] mButtonBacklightValues; 290 private int[] mKeyboardBacklightValues; 291 private int mLightSensorWarmupTime; 292 boolean mUnplugTurnsOnScreen; 293 private int mWarningSpewThrottleCount; 294 private long mWarningSpewThrottleTime; 295 private int mAnimationSetting = ANIM_SETTING_OFF; 296 private float mWindowScaleAnimation; 297 298 // Must match with the ISurfaceComposer constants in C++. 299 private static final int ANIM_SETTING_ON = 0x01; 300 private static final int ANIM_SETTING_OFF = 0x10; 301 302 private native void nativeInit(); 303 private native void nativeSetPowerState(boolean screenOn, boolean screenBright); 304 private native void nativeStartSurfaceFlingerAnimation(int mode); 305 private static native void nativeAcquireWakeLock(int lock, String id); 306 private static native void nativeReleaseWakeLock(String id); 307 private static native int nativeSetScreenState(boolean on); 308 private static native void nativeShutdown(); 309 private static native void nativeReboot(String reason) throws IOException; 310 311 /* 312 static PrintStream mLog; 313 static { 314 try { 315 mLog = new PrintStream("/data/power.log"); 316 } 317 catch (FileNotFoundException e) { 318 android.util.Slog.e(TAG, "Life is hard", e); 319 } 320 } 321 static class Log { 322 static void d(String tag, String s) { 323 mLog.println(s); 324 android.util.Slog.d(tag, s); 325 } 326 static void i(String tag, String s) { 327 mLog.println(s); 328 android.util.Slog.i(tag, s); 329 } 330 static void w(String tag, String s) { 331 mLog.println(s); 332 android.util.Slog.w(tag, s); 333 } 334 static void e(String tag, String s) { 335 mLog.println(s); 336 android.util.Slog.e(tag, s); 337 } 338 } 339 */ 340 341 /** 342 * This class works around a deadlock between the lock in PowerManager.WakeLock 343 * and our synchronizing on mLocks. PowerManager.WakeLock synchronizes on its 344 * mToken object so it can be accessed from any thread, but it calls into here 345 * with its lock held. This class is essentially a reimplementation of 346 * PowerManager.WakeLock, but without that extra synchronized block, because we'll 347 * only call it with our own locks held. 348 */ 349 private class UnsynchronizedWakeLock { 350 int mFlags; 351 String mTag; 352 IBinder mToken; 353 int mCount = 0; 354 boolean mRefCounted; 355 boolean mHeld; 356 357 UnsynchronizedWakeLock(int flags, String tag, boolean refCounted) { 358 mFlags = flags; 359 mTag = tag; 360 mToken = new Binder(); 361 mRefCounted = refCounted; 362 } 363 364 public void acquire() { 365 if (!mRefCounted || mCount++ == 0) { 366 long ident = Binder.clearCallingIdentity(); 367 try { 368 PowerManagerService.this.acquireWakeLockLocked(mFlags, mToken, 369 MY_UID, MY_PID, mTag, null); 370 mHeld = true; 371 } finally { 372 Binder.restoreCallingIdentity(ident); 373 } 374 } 375 } 376 377 public void release() { 378 if (!mRefCounted || --mCount == 0) { 379 PowerManagerService.this.releaseWakeLockLocked(mToken, 0, false); 380 mHeld = false; 381 } 382 if (mCount < 0) { 383 throw new RuntimeException("WakeLock under-locked " + mTag); 384 } 385 } 386 387 public boolean isHeld() 388 { 389 return mHeld; 390 } 391 392 public String toString() { 393 return "UnsynchronizedWakeLock(mFlags=0x" + Integer.toHexString(mFlags) 394 + " mCount=" + mCount + " mHeld=" + mHeld + ")"; 395 } 396 } 397 398 private final class BatteryReceiver extends BroadcastReceiver { 399 @Override 400 public void onReceive(Context context, Intent intent) { 401 synchronized (mLocks) { 402 boolean wasPowered = mIsPowered; 403 mIsPowered = mBatteryService.isPowered(); 404 405 if (mIsPowered != wasPowered) { 406 // update mStayOnWhilePluggedIn wake lock 407 updateWakeLockLocked(); 408 409 // treat plugging and unplugging the devices as a user activity. 410 // users find it disconcerting when they unplug the device 411 // and it shuts off right away. 412 // to avoid turning on the screen when unplugging, we only trigger 413 // user activity when screen was already on. 414 // temporarily set mUserActivityAllowed to true so this will work 415 // even when the keyguard is on. 416 // However, you can also set config_unplugTurnsOnScreen to have it 417 // turn on. Some devices want this because they don't have a 418 // charging LED. 419 synchronized (mLocks) { 420 if (!wasPowered || (mPowerState & SCREEN_ON_BIT) != 0 || 421 mUnplugTurnsOnScreen) { 422 forceUserActivityLocked(); 423 } 424 } 425 } 426 } 427 } 428 } 429 430 private final class BootCompletedReceiver extends BroadcastReceiver { 431 @Override 432 public void onReceive(Context context, Intent intent) { 433 bootCompleted(); 434 } 435 } 436 437 private final class DockReceiver extends BroadcastReceiver { 438 @Override 439 public void onReceive(Context context, Intent intent) { 440 int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, 441 Intent.EXTRA_DOCK_STATE_UNDOCKED); 442 dockStateChanged(state); 443 } 444 } 445 446 /** 447 * Set the setting that determines whether the device stays on when plugged in. 448 * The argument is a bit string, with each bit specifying a power source that, 449 * when the device is connected to that source, causes the device to stay on. 450 * See {@link android.os.BatteryManager} for the list of power sources that 451 * can be specified. Current values include {@link android.os.BatteryManager#BATTERY_PLUGGED_AC} 452 * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB} 453 * @param val an {@code int} containing the bits that specify which power sources 454 * should cause the device to stay on. 455 */ 456 public void setStayOnSetting(int val) { 457 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS, null); 458 Settings.System.putInt(mContext.getContentResolver(), 459 Settings.System.STAY_ON_WHILE_PLUGGED_IN, val); 460 } 461 462 public void setMaximumScreenOffTimeount(int timeMs) { 463 mContext.enforceCallingOrSelfPermission( 464 android.Manifest.permission.WRITE_SECURE_SETTINGS, null); 465 synchronized (mLocks) { 466 mMaximumScreenOffTimeout = timeMs; 467 // recalculate everything 468 setScreenOffTimeoutsLocked(); 469 } 470 } 471 472 int getStayOnConditionsLocked() { 473 return mMaximumScreenOffTimeout <= 0 || mMaximumScreenOffTimeout == Integer.MAX_VALUE 474 ? mStayOnConditions : 0; 475 } 476 477 private class SettingsObserver implements Observer { 478 private int getInt(String name, int defValue) { 479 ContentValues values = mSettings.getValues(name); 480 Integer iVal = values != null ? values.getAsInteger(Settings.System.VALUE) : null; 481 return iVal != null ? iVal : defValue; 482 } 483 484 private float getFloat(String name, float defValue) { 485 ContentValues values = mSettings.getValues(name); 486 Float fVal = values != null ? values.getAsFloat(Settings.System.VALUE) : null; 487 return fVal != null ? fVal : defValue; 488 } 489 490 public void update(Observable o, Object arg) { 491 synchronized (mLocks) { 492 // STAY_ON_WHILE_PLUGGED_IN, default to when plugged into AC 493 mStayOnConditions = getInt(STAY_ON_WHILE_PLUGGED_IN, 494 BatteryManager.BATTERY_PLUGGED_AC); 495 updateWakeLockLocked(); 496 497 // SCREEN_OFF_TIMEOUT, default to 15 seconds 498 mScreenOffTimeoutSetting = getInt(SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT); 499 500 // DIM_SCREEN 501 //mDimScreen = getInt(DIM_SCREEN) != 0; 502 503 mScreenBrightnessSetting = getInt(SCREEN_BRIGHTNESS, DEFAULT_SCREEN_BRIGHTNESS); 504 mLightSensorAdjustSetting = 0; //getFloat(SCREEN_AUTO_BRIGHTNESS_ADJ, 0); 505 506 // SCREEN_BRIGHTNESS_MODE, default to manual 507 setScreenBrightnessMode(getInt(SCREEN_BRIGHTNESS_MODE, 508 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL)); 509 510 // recalculate everything 511 setScreenOffTimeoutsLocked(); 512 513 mWindowScaleAnimation = getFloat(WINDOW_ANIMATION_SCALE, 1.0f); 514 final float transitionScale = getFloat(TRANSITION_ANIMATION_SCALE, 1.0f); 515 mAnimationSetting = 0; 516 if (mWindowScaleAnimation > 0.5f) { 517 mAnimationSetting |= ANIM_SETTING_OFF; 518 } 519 if (transitionScale > 0.5f) { 520 // Uncomment this if you want the screen-on animation. 521 // mAnimationSetting |= ANIM_SETTING_ON; 522 } 523 } 524 } 525 } 526 527 public PowerManagerService() { 528 // Hack to get our uid... should have a func for this. 529 long token = Binder.clearCallingIdentity(); 530 MY_UID = Process.myUid(); 531 MY_PID = Process.myPid(); 532 Binder.restoreCallingIdentity(token); 533 534 // assume nothing is on yet 535 mUserState = mPowerState = 0; 536 537 // Add ourself to the Watchdog monitors. 538 Watchdog.getInstance().addMonitor(this); 539 540 nativeInit(); 541 } 542 543 private ContentQueryMap mSettings; 544 545 public void init(Context context, LightsService lights, IActivityManager activity, 546 BatteryService battery) { 547 mLightsService = lights; 548 mContext = context; 549 mActivityService = activity; 550 mBatteryStats = BatteryStatsService.getService(); 551 mBatteryService = battery; 552 553 mLcdLight = lights.getLight(LightsService.LIGHT_ID_BACKLIGHT); 554 mButtonLight = lights.getLight(LightsService.LIGHT_ID_BUTTONS); 555 mKeyboardLight = lights.getLight(LightsService.LIGHT_ID_KEYBOARD); 556 mAttentionLight = lights.getLight(LightsService.LIGHT_ID_ATTENTION); 557 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 558 559 mInitComplete = false; 560 mScreenBrightnessAnimator = new ScreenBrightnessAnimator("mScreenBrightnessUpdaterThread", 561 Process.THREAD_PRIORITY_DISPLAY); 562 mScreenBrightnessAnimator.start(); 563 564 synchronized (mScreenBrightnessAnimator) { 565 while (!mInitComplete) { 566 try { 567 mScreenBrightnessAnimator.wait(); 568 } catch (InterruptedException e) { 569 // Ignore 570 } 571 } 572 } 573 574 mInitComplete = false; 575 mHandlerThread = new HandlerThread("PowerManagerService") { 576 @Override 577 protected void onLooperPrepared() { 578 super.onLooperPrepared(); 579 initInThread(); 580 } 581 }; 582 mHandlerThread.start(); 583 584 synchronized (mHandlerThread) { 585 while (!mInitComplete) { 586 try { 587 mHandlerThread.wait(); 588 } catch (InterruptedException e) { 589 // Ignore 590 } 591 } 592 } 593 594 synchronized (mLocks) { 595 updateNativePowerStateLocked(); 596 // We make sure to start out with the screen on due to user activity. 597 // (They did just boot their device, after all.) 598 forceUserActivityLocked(); 599 mInitialized = true; 600 } 601 } 602 603 void initInThread() { 604 mHandler = new Handler(); 605 606 mBroadcastWakeLock = new UnsynchronizedWakeLock( 607 PowerManager.PARTIAL_WAKE_LOCK, "sleep_broadcast", true); 608 mStayOnWhilePluggedInScreenDimLock = new UnsynchronizedWakeLock( 609 PowerManager.SCREEN_DIM_WAKE_LOCK, "StayOnWhilePluggedIn Screen Dim", false); 610 mStayOnWhilePluggedInPartialLock = new UnsynchronizedWakeLock( 611 PowerManager.PARTIAL_WAKE_LOCK, "StayOnWhilePluggedIn Partial", false); 612 mPreventScreenOnPartialLock = new UnsynchronizedWakeLock( 613 PowerManager.PARTIAL_WAKE_LOCK, "PreventScreenOn Partial", false); 614 mProximityPartialLock = new UnsynchronizedWakeLock( 615 PowerManager.PARTIAL_WAKE_LOCK, "Proximity Partial", false); 616 617 mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON); 618 mScreenOnIntent.addFlags( 619 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); 620 mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF); 621 mScreenOffIntent.addFlags( 622 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); 623 624 Resources resources = mContext.getResources(); 625 626 mAnimateScreenLights = resources.getBoolean( 627 com.android.internal.R.bool.config_animateScreenLights); 628 629 mUnplugTurnsOnScreen = resources.getBoolean( 630 com.android.internal.R.bool.config_unplugTurnsOnScreen); 631 632 mScreenBrightnessDim = resources.getInteger( 633 com.android.internal.R.integer.config_screenBrightnessDim); 634 635 // read settings for auto-brightness 636 mUseSoftwareAutoBrightness = resources.getBoolean( 637 com.android.internal.R.bool.config_automatic_brightness_available); 638 if (mUseSoftwareAutoBrightness) { 639 mAutoBrightnessLevels = resources.getIntArray( 640 com.android.internal.R.array.config_autoBrightnessLevels); 641 mLcdBacklightValues = resources.getIntArray( 642 com.android.internal.R.array.config_autoBrightnessLcdBacklightValues); 643 mButtonBacklightValues = resources.getIntArray( 644 com.android.internal.R.array.config_autoBrightnessButtonBacklightValues); 645 mKeyboardBacklightValues = resources.getIntArray( 646 com.android.internal.R.array.config_autoBrightnessKeyboardBacklightValues); 647 mLightSensorWarmupTime = resources.getInteger( 648 com.android.internal.R.integer.config_lightSensorWarmupTime); 649 } 650 651 ContentResolver resolver = mContext.getContentResolver(); 652 Cursor settingsCursor = resolver.query(Settings.System.CONTENT_URI, null, 653 "(" + Settings.System.NAME + "=?) or (" 654 + Settings.System.NAME + "=?) or (" 655 + Settings.System.NAME + "=?) or (" 656 + Settings.System.NAME + "=?) or (" 657 + Settings.System.NAME + "=?) or (" 658 + Settings.System.NAME + "=?) or (" 659 + Settings.System.NAME + "=?) or (" 660 + Settings.System.NAME + "=?)", 661 new String[]{STAY_ON_WHILE_PLUGGED_IN, SCREEN_OFF_TIMEOUT, DIM_SCREEN, SCREEN_BRIGHTNESS, 662 SCREEN_BRIGHTNESS_MODE, /*SCREEN_AUTO_BRIGHTNESS_ADJ,*/ 663 WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE}, 664 null); 665 mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mHandler); 666 SettingsObserver settingsObserver = new SettingsObserver(); 667 mSettings.addObserver(settingsObserver); 668 669 // pretend that the settings changed so we will get their initial state 670 settingsObserver.update(mSettings, null); 671 672 // register for the battery changed notifications 673 IntentFilter filter = new IntentFilter(); 674 filter.addAction(Intent.ACTION_BATTERY_CHANGED); 675 mContext.registerReceiver(new BatteryReceiver(), filter); 676 filter = new IntentFilter(); 677 filter.addAction(Intent.ACTION_BOOT_COMPLETED); 678 mContext.registerReceiver(new BootCompletedReceiver(), filter); 679 filter = new IntentFilter(); 680 filter.addAction(Intent.ACTION_DOCK_EVENT); 681 mContext.registerReceiver(new DockReceiver(), filter); 682 683 // Listen for secure settings changes 684 mContext.getContentResolver().registerContentObserver( 685 Settings.Secure.CONTENT_URI, true, 686 new ContentObserver(new Handler()) { 687 public void onChange(boolean selfChange) { 688 updateSettingsValues(); 689 } 690 }); 691 updateSettingsValues(); 692 693 synchronized (mHandlerThread) { 694 mInitComplete = true; 695 mHandlerThread.notifyAll(); 696 } 697 } 698 699 /** 700 * Low-level function turn the device off immediately, without trying 701 * to be clean. Most people should use 702 * {@link com.android.server.power.internal.app.ShutdownThread} for a clean shutdown. 703 */ 704 public static void lowLevelShutdown() { 705 nativeShutdown(); 706 } 707 708 /** 709 * Low-level function to reboot the device. 710 * 711 * @param reason code to pass to the kernel (e.g. "recovery"), or null. 712 * @throws IOException if reboot fails for some reason (eg, lack of 713 * permission) 714 */ 715 public static void lowLevelReboot(String reason) throws IOException { 716 nativeReboot(reason); 717 } 718 719 private class WakeLock implements IBinder.DeathRecipient 720 { 721 WakeLock(int f, IBinder b, String t, int u, int p) { 722 super(); 723 flags = f; 724 binder = b; 725 tag = t; 726 uid = u == MY_UID ? Process.SYSTEM_UID : u; 727 pid = p; 728 if (u != MY_UID || ( 729 !"KEEP_SCREEN_ON_FLAG".equals(tag) 730 && !"KeyInputQueue".equals(tag))) { 731 monitorType = (f & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK 732 ? BatteryStats.WAKE_TYPE_PARTIAL 733 : BatteryStats.WAKE_TYPE_FULL; 734 } else { 735 monitorType = -1; 736 } 737 try { 738 b.linkToDeath(this, 0); 739 } catch (RemoteException e) { 740 binderDied(); 741 } 742 } 743 public void binderDied() { 744 synchronized (mLocks) { 745 releaseWakeLockLocked(this.binder, 0, true); 746 } 747 } 748 final int flags; 749 final IBinder binder; 750 final String tag; 751 final int uid; 752 final int pid; 753 final int monitorType; 754 WorkSource ws; 755 boolean activated = true; 756 int minState; 757 } 758 759 private void updateWakeLockLocked() { 760 final int stayOnConditions = getStayOnConditionsLocked(); 761 if (stayOnConditions != 0 && mBatteryService.isPowered(stayOnConditions)) { 762 // keep the device on if we're plugged in and mStayOnWhilePluggedIn is set. 763 mStayOnWhilePluggedInScreenDimLock.acquire(); 764 mStayOnWhilePluggedInPartialLock.acquire(); 765 } else { 766 mStayOnWhilePluggedInScreenDimLock.release(); 767 mStayOnWhilePluggedInPartialLock.release(); 768 } 769 } 770 771 private boolean isScreenLock(int flags) 772 { 773 int n = flags & LOCK_MASK; 774 return n == PowerManager.FULL_WAKE_LOCK 775 || n == PowerManager.SCREEN_BRIGHT_WAKE_LOCK 776 || n == PowerManager.SCREEN_DIM_WAKE_LOCK 777 || n == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK; 778 } 779 780 void enforceWakeSourcePermission(int uid, int pid) { 781 if (uid == Process.myUid()) { 782 return; 783 } 784 mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS, 785 pid, uid, null); 786 } 787 788 public void acquireWakeLock(int flags, IBinder lock, String tag, WorkSource ws) { 789 int uid = Binder.getCallingUid(); 790 int pid = Binder.getCallingPid(); 791 if (uid != Process.myUid()) { 792 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null); 793 } 794 if (ws != null) { 795 enforceWakeSourcePermission(uid, pid); 796 } 797 long ident = Binder.clearCallingIdentity(); 798 try { 799 synchronized (mLocks) { 800 acquireWakeLockLocked(flags, lock, uid, pid, tag, ws); 801 } 802 } finally { 803 Binder.restoreCallingIdentity(ident); 804 } 805 } 806 807 void noteStartWakeLocked(WakeLock wl, WorkSource ws) { 808 if (wl.monitorType >= 0) { 809 long origId = Binder.clearCallingIdentity(); 810 try { 811 if (ws != null) { 812 mBatteryStats.noteStartWakelockFromSource(ws, wl.pid, wl.tag, 813 wl.monitorType); 814 } else { 815 mBatteryStats.noteStartWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType); 816 } 817 } catch (RemoteException e) { 818 // Ignore 819 } finally { 820 Binder.restoreCallingIdentity(origId); 821 } 822 } 823 } 824 825 void noteStopWakeLocked(WakeLock wl, WorkSource ws) { 826 if (wl.monitorType >= 0) { 827 long origId = Binder.clearCallingIdentity(); 828 try { 829 if (ws != null) { 830 mBatteryStats.noteStopWakelockFromSource(ws, wl.pid, wl.tag, 831 wl.monitorType); 832 } else { 833 mBatteryStats.noteStopWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType); 834 } 835 } catch (RemoteException e) { 836 // Ignore 837 } finally { 838 Binder.restoreCallingIdentity(origId); 839 } 840 } 841 } 842 843 public void acquireWakeLockLocked(int flags, IBinder lock, int uid, int pid, String tag, 844 WorkSource ws) { 845 if (DEBUG) { 846 Slog.d(TAG, "acquireWakeLock flags=0x" + Integer.toHexString(flags) + " tag=" + tag); 847 } 848 849 if (ws != null && ws.size() == 0) { 850 ws = null; 851 } 852 853 int index = mLocks.getIndex(lock); 854 WakeLock wl; 855 boolean newlock; 856 boolean diffsource; 857 WorkSource oldsource; 858 if (index < 0) { 859 wl = new WakeLock(flags, lock, tag, uid, pid); 860 switch (wl.flags & LOCK_MASK) 861 { 862 case PowerManager.FULL_WAKE_LOCK: 863 if (mUseSoftwareAutoBrightness) { 864 wl.minState = SCREEN_BRIGHT; 865 } else { 866 wl.minState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT); 867 } 868 break; 869 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK: 870 wl.minState = SCREEN_BRIGHT; 871 break; 872 case PowerManager.SCREEN_DIM_WAKE_LOCK: 873 wl.minState = SCREEN_DIM; 874 break; 875 case PowerManager.PARTIAL_WAKE_LOCK: 876 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK: 877 break; 878 default: 879 // just log and bail. we're in the server, so don't 880 // throw an exception. 881 Slog.e(TAG, "bad wakelock type for lock '" + tag + "' " 882 + " flags=" + flags); 883 return; 884 } 885 mLocks.addLock(wl); 886 if (ws != null) { 887 wl.ws = new WorkSource(ws); 888 } 889 newlock = true; 890 diffsource = false; 891 oldsource = null; 892 } else { 893 wl = mLocks.get(index); 894 newlock = false; 895 oldsource = wl.ws; 896 if (oldsource != null) { 897 if (ws == null) { 898 wl.ws = null; 899 diffsource = true; 900 } else { 901 diffsource = oldsource.diff(ws); 902 } 903 } else if (ws != null) { 904 diffsource = true; 905 } else { 906 diffsource = false; 907 } 908 if (diffsource) { 909 wl.ws = new WorkSource(ws); 910 } 911 } 912 if (isScreenLock(flags)) { 913 // if this causes a wakeup, we reactivate all of the locks and 914 // set it to whatever they want. otherwise, we modulate that 915 // by the current state so we never turn it more on than 916 // it already is. 917 if ((flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) { 918 mProximityWakeLockCount++; 919 if (mProximityWakeLockCount == 1) { 920 enableProximityLockLocked(); 921 } 922 } else { 923 if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) { 924 int oldWakeLockState = mWakeLockState; 925 mWakeLockState = mLocks.reactivateScreenLocksLocked(); 926 927 // Disable proximity sensor if if user presses power key while we are in the 928 // "waiting for proximity sensor to go negative" state. 929 if ((mWakeLockState & SCREEN_ON_BIT) != 0 930 && mProximitySensorActive && mProximityWakeLockCount == 0) { 931 mProximitySensorActive = false; 932 } 933 934 if (DEBUG) { 935 Slog.d(TAG, "wakeup here mUserState=0x" + Integer.toHexString(mUserState) 936 + " mWakeLockState=0x" 937 + Integer.toHexString(mWakeLockState) 938 + " previous wakeLockState=0x" 939 + Integer.toHexString(oldWakeLockState)); 940 } 941 } else { 942 if (DEBUG) { 943 Slog.d(TAG, "here mUserState=0x" + Integer.toHexString(mUserState) 944 + " mLocks.gatherState()=0x" 945 + Integer.toHexString(mLocks.gatherState()) 946 + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState)); 947 } 948 mWakeLockState = (mUserState | mWakeLockState) & mLocks.gatherState(); 949 } 950 setPowerState(mWakeLockState | mUserState); 951 } 952 } 953 else if ((flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) { 954 if (newlock) { 955 mPartialCount++; 956 if (mPartialCount == 1) { 957 if (LOG_PARTIAL_WL) { 958 EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 1, tag); 959 } 960 } 961 } 962 nativeAcquireWakeLock(PARTIAL_WAKE_LOCK_ID, PARTIAL_NAME); 963 } 964 965 if (diffsource) { 966 // If the lock sources have changed, need to first release the 967 // old ones. 968 noteStopWakeLocked(wl, oldsource); 969 } 970 if (newlock || diffsource) { 971 noteStartWakeLocked(wl, ws); 972 } 973 } 974 975 public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) { 976 int uid = Binder.getCallingUid(); 977 int pid = Binder.getCallingPid(); 978 if (ws != null && ws.size() == 0) { 979 ws = null; 980 } 981 if (ws != null) { 982 enforceWakeSourcePermission(uid, pid); 983 } 984 synchronized (mLocks) { 985 int index = mLocks.getIndex(lock); 986 if (index < 0) { 987 throw new IllegalArgumentException("Wake lock not active"); 988 } 989 WakeLock wl = mLocks.get(index); 990 WorkSource oldsource = wl.ws; 991 wl.ws = ws != null ? new WorkSource(ws) : null; 992 noteStopWakeLocked(wl, oldsource); 993 noteStartWakeLocked(wl, ws); 994 } 995 } 996 997 public void releaseWakeLock(IBinder lock, int flags) { 998 int uid = Binder.getCallingUid(); 999 if (uid != Process.myUid()) { 1000 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null); 1001 } 1002 1003 synchronized (mLocks) { 1004 releaseWakeLockLocked(lock, flags, false); 1005 } 1006 } 1007 1008 private void releaseWakeLockLocked(IBinder lock, int flags, boolean death) { 1009 WakeLock wl = mLocks.removeLock(lock); 1010 if (wl == null) { 1011 return; 1012 } 1013 1014 if (DEBUG) { 1015 Slog.d(TAG, "releaseWakeLock flags=0x" 1016 + Integer.toHexString(wl.flags) + " tag=" + wl.tag); 1017 } 1018 1019 if (isScreenLock(wl.flags)) { 1020 if ((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) { 1021 mProximityWakeLockCount--; 1022 if (mProximityWakeLockCount == 0) { 1023 if (mProximitySensorActive && 1024 ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0)) { 1025 // wait for proximity sensor to go negative before disabling sensor 1026 if (DEBUG_PROXIMITY_SENSOR) { 1027 Slog.d(TAG, "waiting for proximity sensor to go negative"); 1028 } 1029 } else { 1030 disableProximityLockLocked(); 1031 } 1032 } 1033 } else { 1034 mWakeLockState = mLocks.gatherState(); 1035 // goes in the middle to reduce flicker 1036 if ((wl.flags & PowerManager.ON_AFTER_RELEASE) != 0) { 1037 userActivity(SystemClock.uptimeMillis(), -1, false, OTHER_EVENT, false); 1038 } 1039 setPowerState(mWakeLockState | mUserState); 1040 } 1041 } 1042 else if ((wl.flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) { 1043 mPartialCount--; 1044 if (mPartialCount == 0) { 1045 if (LOG_PARTIAL_WL) { 1046 EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 0, wl.tag); 1047 } 1048 nativeReleaseWakeLock(PARTIAL_NAME); 1049 } 1050 } 1051 // Unlink the lock from the binder. 1052 wl.binder.unlinkToDeath(wl, 0); 1053 1054 noteStopWakeLocked(wl, wl.ws); 1055 } 1056 1057 private class PokeLock implements IBinder.DeathRecipient 1058 { 1059 PokeLock(int p, IBinder b, String t) { 1060 super(); 1061 this.pokey = p; 1062 this.binder = b; 1063 this.tag = t; 1064 try { 1065 b.linkToDeath(this, 0); 1066 } catch (RemoteException e) { 1067 binderDied(); 1068 } 1069 } 1070 public void binderDied() { 1071 setPokeLock(0, this.binder, this.tag); 1072 } 1073 int pokey; 1074 IBinder binder; 1075 String tag; 1076 boolean awakeOnSet; 1077 } 1078 1079 public void setPokeLock(int pokey, IBinder token, String tag) { 1080 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 1081 if (token == null) { 1082 Slog.e(TAG, "setPokeLock got null token for tag='" + tag + "'"); 1083 return; 1084 } 1085 1086 if ((pokey & POKE_LOCK_TIMEOUT_MASK) == POKE_LOCK_TIMEOUT_MASK) { 1087 throw new IllegalArgumentException("setPokeLock can't have both POKE_LOCK_SHORT_TIMEOUT" 1088 + " and POKE_LOCK_MEDIUM_TIMEOUT"); 1089 } 1090 1091 synchronized (mLocks) { 1092 if (pokey != 0) { 1093 PokeLock p = mPokeLocks.get(token); 1094 int oldPokey = 0; 1095 if (p != null) { 1096 oldPokey = p.pokey; 1097 p.pokey = pokey; 1098 } else { 1099 p = new PokeLock(pokey, token, tag); 1100 mPokeLocks.put(token, p); 1101 } 1102 int oldTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK; 1103 int newTimeout = pokey & POKE_LOCK_TIMEOUT_MASK; 1104 if (((mPowerState & SCREEN_ON_BIT) == 0) && (oldTimeout != newTimeout)) { 1105 p.awakeOnSet = true; 1106 } 1107 } else { 1108 PokeLock rLock = mPokeLocks.remove(token); 1109 if (rLock != null) { 1110 token.unlinkToDeath(rLock, 0); 1111 } 1112 } 1113 1114 int oldPokey = mPokey; 1115 int cumulative = 0; 1116 boolean awakeOnSet = false; 1117 for (PokeLock p: mPokeLocks.values()) { 1118 cumulative |= p.pokey; 1119 if (p.awakeOnSet) { 1120 awakeOnSet = true; 1121 } 1122 } 1123 mPokey = cumulative; 1124 mPokeAwakeOnSet = awakeOnSet; 1125 1126 int oldCumulativeTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK; 1127 int newCumulativeTimeout = pokey & POKE_LOCK_TIMEOUT_MASK; 1128 1129 if (oldCumulativeTimeout != newCumulativeTimeout) { 1130 setScreenOffTimeoutsLocked(); 1131 // reset the countdown timer, but use the existing nextState so it doesn't 1132 // change anything 1133 setTimeoutLocked(SystemClock.uptimeMillis(), mTimeoutTask.nextState); 1134 } 1135 } 1136 } 1137 1138 private static String lockType(int type) 1139 { 1140 switch (type) 1141 { 1142 case PowerManager.FULL_WAKE_LOCK: 1143 return "FULL_WAKE_LOCK "; 1144 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK: 1145 return "SCREEN_BRIGHT_WAKE_LOCK "; 1146 case PowerManager.SCREEN_DIM_WAKE_LOCK: 1147 return "SCREEN_DIM_WAKE_LOCK "; 1148 case PowerManager.PARTIAL_WAKE_LOCK: 1149 return "PARTIAL_WAKE_LOCK "; 1150 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK: 1151 return "PROXIMITY_SCREEN_OFF_WAKE_LOCK"; 1152 default: 1153 return "??? "; 1154 } 1155 } 1156 1157 private static String dumpPowerState(int state) { 1158 return (((state & KEYBOARD_BRIGHT_BIT) != 0) 1159 ? "KEYBOARD_BRIGHT_BIT " : "") 1160 + (((state & SCREEN_BRIGHT_BIT) != 0) 1161 ? "SCREEN_BRIGHT_BIT " : "") 1162 + (((state & SCREEN_ON_BIT) != 0) 1163 ? "SCREEN_ON_BIT " : "") 1164 + (((state & BUTTON_BRIGHT_BIT) != 0) 1165 ? "BUTTON_BRIGHT_BIT " : "") 1166 + (((state & BATTERY_LOW_BIT) != 0) 1167 ? "BATTERY_LOW_BIT " : ""); 1168 } 1169 1170 @Override 1171 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1172 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 1173 != PackageManager.PERMISSION_GRANTED) { 1174 pw.println("Permission Denial: can't dump PowerManager from from pid=" 1175 + Binder.getCallingPid() 1176 + ", uid=" + Binder.getCallingUid()); 1177 return; 1178 } 1179 1180 long now = SystemClock.uptimeMillis(); 1181 1182 synchronized (mLocks) { 1183 pw.println("Power Manager State:"); 1184 pw.println(" mIsPowered=" + mIsPowered 1185 + " mPowerState=" + mPowerState 1186 + " mScreenOffTime=" + (SystemClock.elapsedRealtime()-mScreenOffTime) 1187 + " ms"); 1188 pw.println(" mPartialCount=" + mPartialCount); 1189 pw.println(" mWakeLockState=" + dumpPowerState(mWakeLockState)); 1190 pw.println(" mUserState=" + dumpPowerState(mUserState)); 1191 pw.println(" mPowerState=" + dumpPowerState(mPowerState)); 1192 pw.println(" mLocks.gather=" + dumpPowerState(mLocks.gatherState())); 1193 pw.println(" mNextTimeout=" + mNextTimeout + " now=" + now 1194 + " " + ((mNextTimeout-now)/1000) + "s from now"); 1195 pw.println(" mDimScreen=" + mDimScreen 1196 + " mStayOnConditions=" + mStayOnConditions 1197 + " mPreparingForScreenOn=" + mPreparingForScreenOn 1198 + " mSkippedScreenOn=" + mSkippedScreenOn); 1199 pw.println(" mScreenOffReason=" + mScreenOffReason 1200 + " mUserState=" + mUserState); 1201 pw.println(" mBroadcastQueue={" + mBroadcastQueue[0] + ',' + mBroadcastQueue[1] 1202 + ',' + mBroadcastQueue[2] + "}"); 1203 pw.println(" mBroadcastWhy={" + mBroadcastWhy[0] + ',' + mBroadcastWhy[1] 1204 + ',' + mBroadcastWhy[2] + "}"); 1205 pw.println(" mPokey=" + mPokey + " mPokeAwakeonSet=" + mPokeAwakeOnSet); 1206 pw.println(" mKeyboardVisible=" + mKeyboardVisible 1207 + " mUserActivityAllowed=" + mUserActivityAllowed); 1208 pw.println(" mKeylightDelay=" + mKeylightDelay + " mDimDelay=" + mDimDelay 1209 + " mScreenOffDelay=" + mScreenOffDelay); 1210 pw.println(" mPreventScreenOn=" + mPreventScreenOn 1211 + " mScreenBrightnessOverride=" + mScreenBrightnessOverride 1212 + " mButtonBrightnessOverride=" + mButtonBrightnessOverride); 1213 pw.println(" mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting 1214 + " mMaximumScreenOffTimeout=" + mMaximumScreenOffTimeout); 1215 pw.println(" mLastScreenOnTime=" + mLastScreenOnTime); 1216 pw.println(" mBroadcastWakeLock=" + mBroadcastWakeLock); 1217 pw.println(" mStayOnWhilePluggedInScreenDimLock=" + mStayOnWhilePluggedInScreenDimLock); 1218 pw.println(" mStayOnWhilePluggedInPartialLock=" + mStayOnWhilePluggedInPartialLock); 1219 pw.println(" mPreventScreenOnPartialLock=" + mPreventScreenOnPartialLock); 1220 pw.println(" mProximityPartialLock=" + mProximityPartialLock); 1221 pw.println(" mProximityWakeLockCount=" + mProximityWakeLockCount); 1222 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled); 1223 pw.println(" mProximitySensorActive=" + mProximitySensorActive); 1224 pw.println(" mProximityPendingValue=" + mProximityPendingValue); 1225 pw.println(" mLastProximityEventTime=" + mLastProximityEventTime); 1226 pw.println(" mLightSensorEnabled=" + mLightSensorEnabled 1227 + " mLightSensorAdjustSetting=" + mLightSensorAdjustSetting); 1228 pw.println(" mLightSensorValue=" + mLightSensorValue 1229 + " mLightSensorPendingValue=" + mLightSensorPendingValue); 1230 pw.println(" mHighestLightSensorValue=" + mHighestLightSensorValue 1231 + " mWaitingForFirstLightSensor=" + mWaitingForFirstLightSensor); 1232 pw.println(" mLightSensorPendingDecrease=" + mLightSensorPendingDecrease 1233 + " mLightSensorPendingIncrease=" + mLightSensorPendingIncrease); 1234 pw.println(" mLightSensorScreenBrightness=" + mLightSensorScreenBrightness 1235 + " mLightSensorButtonBrightness=" + mLightSensorButtonBrightness 1236 + " mLightSensorKeyboardBrightness=" + mLightSensorKeyboardBrightness); 1237 pw.println(" mUseSoftwareAutoBrightness=" + mUseSoftwareAutoBrightness); 1238 pw.println(" mAutoBrightessEnabled=" + mAutoBrightessEnabled); 1239 mScreenBrightnessAnimator.dump(pw, " mScreenBrightnessAnimator: "); 1240 1241 int N = mLocks.size(); 1242 pw.println(); 1243 pw.println("mLocks.size=" + N + ":"); 1244 for (int i=0; i<N; i++) { 1245 WakeLock wl = mLocks.get(i); 1246 String type = lockType(wl.flags & LOCK_MASK); 1247 String acquireCausesWakeup = ""; 1248 if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) { 1249 acquireCausesWakeup = "ACQUIRE_CAUSES_WAKEUP "; 1250 } 1251 String activated = ""; 1252 if (wl.activated) { 1253 activated = " activated"; 1254 } 1255 pw.println(" " + type + " '" + wl.tag + "'" + acquireCausesWakeup 1256 + activated + " (minState=" + wl.minState + ", uid=" + wl.uid 1257 + ", pid=" + wl.pid + ")"); 1258 } 1259 1260 pw.println(); 1261 pw.println("mPokeLocks.size=" + mPokeLocks.size() + ":"); 1262 for (PokeLock p: mPokeLocks.values()) { 1263 pw.println(" poke lock '" + p.tag + "':" 1264 + ((p.pokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0 1265 ? " POKE_LOCK_IGNORE_TOUCH_EVENTS" : "") 1266 + ((p.pokey & POKE_LOCK_SHORT_TIMEOUT) != 0 1267 ? " POKE_LOCK_SHORT_TIMEOUT" : "") 1268 + ((p.pokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0 1269 ? " POKE_LOCK_MEDIUM_TIMEOUT" : "")); 1270 } 1271 1272 pw.println(); 1273 } 1274 } 1275 1276 private void setTimeoutLocked(long now, int nextState) { 1277 setTimeoutLocked(now, -1, nextState); 1278 } 1279 1280 // If they gave a timeoutOverride it is the number of seconds 1281 // to screen-off. Figure out where in the countdown cycle we 1282 // should jump to. 1283 private void setTimeoutLocked(long now, final long originalTimeoutOverride, int nextState) { 1284 long timeoutOverride = originalTimeoutOverride; 1285 if (mBootCompleted) { 1286 synchronized (mLocks) { 1287 long when = 0; 1288 if (timeoutOverride <= 0) { 1289 switch (nextState) 1290 { 1291 case SCREEN_BRIGHT: 1292 when = now + mKeylightDelay; 1293 break; 1294 case SCREEN_DIM: 1295 if (mDimDelay >= 0) { 1296 when = now + mDimDelay; 1297 break; 1298 } else { 1299 Slog.w(TAG, "mDimDelay=" + mDimDelay + " while trying to dim"); 1300 } 1301 case SCREEN_OFF: 1302 synchronized (mLocks) { 1303 when = now + mScreenOffDelay; 1304 } 1305 break; 1306 default: 1307 when = now; 1308 break; 1309 } 1310 } else { 1311 override: { 1312 if (timeoutOverride <= mScreenOffDelay) { 1313 when = now + timeoutOverride; 1314 nextState = SCREEN_OFF; 1315 break override; 1316 } 1317 timeoutOverride -= mScreenOffDelay; 1318 1319 if (mDimDelay >= 0) { 1320 if (timeoutOverride <= mDimDelay) { 1321 when = now + timeoutOverride; 1322 nextState = SCREEN_DIM; 1323 break override; 1324 } 1325 timeoutOverride -= mDimDelay; 1326 } 1327 1328 when = now + timeoutOverride; 1329 nextState = SCREEN_BRIGHT; 1330 } 1331 } 1332 if (DEBUG) { 1333 Slog.d(TAG, "setTimeoutLocked now=" + now 1334 + " timeoutOverride=" + timeoutOverride 1335 + " nextState=" + nextState + " when=" + when); 1336 } 1337 1338 mHandler.removeCallbacks(mTimeoutTask); 1339 mTimeoutTask.nextState = nextState; 1340 mTimeoutTask.remainingTimeoutOverride = timeoutOverride > 0 1341 ? (originalTimeoutOverride - timeoutOverride) 1342 : -1; 1343 mHandler.postAtTime(mTimeoutTask, when); 1344 mNextTimeout = when; // for debugging 1345 } 1346 } 1347 } 1348 1349 private void cancelTimerLocked() 1350 { 1351 mHandler.removeCallbacks(mTimeoutTask); 1352 mTimeoutTask.nextState = -1; 1353 } 1354 1355 private class TimeoutTask implements Runnable 1356 { 1357 int nextState; // access should be synchronized on mLocks 1358 long remainingTimeoutOverride; 1359 public void run() 1360 { 1361 synchronized (mLocks) { 1362 if (DEBUG) { 1363 Slog.d(TAG, "user activity timeout timed out nextState=" + this.nextState); 1364 } 1365 1366 if (nextState == -1) { 1367 return; 1368 } 1369 1370 mUserState = this.nextState; 1371 setPowerState(this.nextState | mWakeLockState); 1372 1373 long now = SystemClock.uptimeMillis(); 1374 1375 switch (this.nextState) 1376 { 1377 case SCREEN_BRIGHT: 1378 if (mDimDelay >= 0) { 1379 setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_DIM); 1380 break; 1381 } 1382 case SCREEN_DIM: 1383 setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_OFF); 1384 break; 1385 } 1386 } 1387 } 1388 } 1389 1390 private void sendNotificationLocked(boolean on, int why) { 1391 if (!mInitialized) { 1392 // No notifications sent until first initialization is done. 1393 // This is so that when we are moving from our initial state 1394 // which looks like the screen was off to it being on, we do not 1395 // go through the process of waiting for the higher-level user 1396 // space to be ready before turning up the display brightness. 1397 // (And also do not send needless broadcasts about the screen.) 1398 return; 1399 } 1400 1401 if (DEBUG_SCREEN_ON) { 1402 RuntimeException here = new RuntimeException("here"); 1403 here.fillInStackTrace(); 1404 Slog.i(TAG, "sendNotificationLocked: " + on, here); 1405 } 1406 1407 if (!on) { 1408 mStillNeedSleepNotification = false; 1409 } 1410 1411 // Add to the queue. 1412 int index = 0; 1413 while (mBroadcastQueue[index] != -1) { 1414 index++; 1415 } 1416 mBroadcastQueue[index] = on ? 1 : 0; 1417 mBroadcastWhy[index] = why; 1418 1419 // If we added it position 2, then there is a pair that can be stripped. 1420 // If we added it position 1 and we're turning the screen off, we can strip 1421 // the pair and do nothing, because the screen is already off, and therefore 1422 // keyguard has already been enabled. 1423 // However, if we added it at position 1 and we're turning it on, then position 1424 // 0 was to turn it off, and we can't strip that, because keyguard needs to come 1425 // on, so have to run the queue then. 1426 if (index == 2) { 1427 // While we're collapsing them, if it's going off, and the new reason 1428 // is more significant than the first, then use the new one. 1429 if (!on && mBroadcastWhy[0] > why) { 1430 mBroadcastWhy[0] = why; 1431 } 1432 mBroadcastQueue[0] = on ? 1 : 0; 1433 mBroadcastQueue[1] = -1; 1434 mBroadcastQueue[2] = -1; 1435 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount); 1436 mBroadcastWakeLock.release(); 1437 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount); 1438 mBroadcastWakeLock.release(); 1439 index = 0; 1440 } 1441 if (index == 1 && !on) { 1442 mBroadcastQueue[0] = -1; 1443 mBroadcastQueue[1] = -1; 1444 index = -1; 1445 // The wake lock was being held, but we're not actually going to do any 1446 // broadcasts, so release the wake lock. 1447 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount); 1448 mBroadcastWakeLock.release(); 1449 } 1450 1451 // The broadcast queue has changed; make sure the screen is on if it 1452 // is now possible for it to be. 1453 if (mSkippedScreenOn) { 1454 updateLightsLocked(mPowerState, SCREEN_ON_BIT); 1455 } 1456 1457 // Now send the message. 1458 if (index >= 0) { 1459 // Acquire the broadcast wake lock before changing the power 1460 // state. It will be release after the broadcast is sent. 1461 // We always increment the ref count for each notification in the queue 1462 // and always decrement when that notification is handled. 1463 mBroadcastWakeLock.acquire(); 1464 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, mBroadcastWakeLock.mCount); 1465 mHandler.post(mNotificationTask); 1466 } 1467 } 1468 1469 private WindowManagerPolicy.ScreenOnListener mScreenOnListener = 1470 new WindowManagerPolicy.ScreenOnListener() { 1471 public void onScreenOn() { 1472 synchronized (mLocks) { 1473 if (mPreparingForScreenOn) { 1474 mPreparingForScreenOn = false; 1475 updateLightsLocked(mPowerState, SCREEN_ON_BIT); 1476 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1477 4, mBroadcastWakeLock.mCount); 1478 mBroadcastWakeLock.release(); 1479 } 1480 } 1481 } 1482 }; 1483 1484 private Runnable mNotificationTask = new Runnable() 1485 { 1486 public void run() 1487 { 1488 while (true) { 1489 int value; 1490 int why; 1491 WindowManagerPolicy policy; 1492 synchronized (mLocks) { 1493 value = mBroadcastQueue[0]; 1494 why = mBroadcastWhy[0]; 1495 for (int i=0; i<2; i++) { 1496 mBroadcastQueue[i] = mBroadcastQueue[i+1]; 1497 mBroadcastWhy[i] = mBroadcastWhy[i+1]; 1498 } 1499 policy = getPolicyLocked(); 1500 if (value == 1 && !mPreparingForScreenOn) { 1501 mPreparingForScreenOn = true; 1502 mBroadcastWakeLock.acquire(); 1503 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1504 mBroadcastWakeLock.mCount); 1505 } 1506 } 1507 if (value == 1) { 1508 mScreenOnStart = SystemClock.uptimeMillis(); 1509 1510 policy.screenTurningOn(mScreenOnListener); 1511 try { 1512 ActivityManagerNative.getDefault().wakingUp(); 1513 } catch (RemoteException e) { 1514 // ignore it 1515 } 1516 1517 if (DEBUG) { 1518 Slog.d(TAG, "mBroadcastWakeLock=" + mBroadcastWakeLock); 1519 } 1520 if (mContext != null && ActivityManagerNative.isSystemReady()) { 1521 mContext.sendOrderedBroadcast(mScreenOnIntent, null, 1522 mScreenOnBroadcastDone, mHandler, 0, null, null); 1523 } else { 1524 synchronized (mLocks) { 1525 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1526 mBroadcastWakeLock.mCount); 1527 mBroadcastWakeLock.release(); 1528 } 1529 } 1530 } 1531 else if (value == 0) { 1532 mScreenOffStart = SystemClock.uptimeMillis(); 1533 1534 policy.screenTurnedOff(why); 1535 try { 1536 ActivityManagerNative.getDefault().goingToSleep(); 1537 } catch (RemoteException e) { 1538 // ignore it. 1539 } 1540 1541 if (mContext != null && ActivityManagerNative.isSystemReady()) { 1542 mContext.sendOrderedBroadcast(mScreenOffIntent, null, 1543 mScreenOffBroadcastDone, mHandler, 0, null, null); 1544 } else { 1545 synchronized (mLocks) { 1546 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3, 1547 mBroadcastWakeLock.mCount); 1548 updateLightsLocked(mPowerState, SCREEN_ON_BIT); 1549 mBroadcastWakeLock.release(); 1550 } 1551 } 1552 } 1553 else { 1554 // If we're in this case, then this handler is running for a previous 1555 // paired transaction. mBroadcastWakeLock will already have been released. 1556 break; 1557 } 1558 } 1559 } 1560 }; 1561 1562 long mScreenOnStart; 1563 private BroadcastReceiver mScreenOnBroadcastDone = new BroadcastReceiver() { 1564 public void onReceive(Context context, Intent intent) { 1565 synchronized (mLocks) { 1566 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1, 1567 SystemClock.uptimeMillis() - mScreenOnStart, mBroadcastWakeLock.mCount); 1568 mBroadcastWakeLock.release(); 1569 } 1570 } 1571 }; 1572 1573 long mScreenOffStart; 1574 private BroadcastReceiver mScreenOffBroadcastDone = new BroadcastReceiver() { 1575 public void onReceive(Context context, Intent intent) { 1576 synchronized (mLocks) { 1577 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0, 1578 SystemClock.uptimeMillis() - mScreenOffStart, mBroadcastWakeLock.mCount); 1579 mBroadcastWakeLock.release(); 1580 } 1581 } 1582 }; 1583 1584 /** 1585 * Prevents the screen from turning on even if it *should* turn on due 1586 * to a subsequent full wake lock being acquired. 1587 * <p> 1588 * This is a temporary hack that allows an activity to "cover up" any 1589 * display glitches that happen during the activity's startup 1590 * sequence. (Specifically, this API was added to work around a 1591 * cosmetic bug in the "incoming call" sequence, where the lock screen 1592 * would flicker briefly before the incoming call UI became visible.) 1593 * TODO: There ought to be a more elegant way of doing this, 1594 * probably by having the PowerManager and ActivityManager 1595 * work together to let apps specify that the screen on/off 1596 * state should be synchronized with the Activity lifecycle. 1597 * <p> 1598 * Note that calling preventScreenOn(true) will NOT turn the screen 1599 * off if it's currently on. (This API only affects *future* 1600 * acquisitions of full wake locks.) 1601 * But calling preventScreenOn(false) WILL turn the screen on if 1602 * it's currently off because of a prior preventScreenOn(true) call. 1603 * <p> 1604 * Any call to preventScreenOn(true) MUST be followed promptly by a call 1605 * to preventScreenOn(false). In fact, if the preventScreenOn(false) 1606 * call doesn't occur within 5 seconds, we'll turn the screen back on 1607 * ourselves (and log a warning about it); this prevents a buggy app 1608 * from disabling the screen forever.) 1609 * <p> 1610 * TODO: this feature should really be controlled by a new type of poke 1611 * lock (rather than an IPowerManager call). 1612 */ 1613 public void preventScreenOn(boolean prevent) { 1614 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 1615 1616 synchronized (mLocks) { 1617 if (prevent) { 1618 // First of all, grab a partial wake lock to 1619 // make sure the CPU stays on during the entire 1620 // preventScreenOn(true) -> preventScreenOn(false) sequence. 1621 mPreventScreenOnPartialLock.acquire(); 1622 1623 // Post a forceReenableScreen() call (for 5 seconds in the 1624 // future) to make sure the matching preventScreenOn(false) call 1625 // has happened by then. 1626 mHandler.removeCallbacks(mForceReenableScreenTask); 1627 mHandler.postDelayed(mForceReenableScreenTask, 5000); 1628 1629 // Finally, set the flag that prevents the screen from turning on. 1630 // (Below, in setPowerState(), we'll check mPreventScreenOn and 1631 // we *won't* call setScreenStateLocked(true) if it's set.) 1632 mPreventScreenOn = true; 1633 } else { 1634 // (Re)enable the screen. 1635 mPreventScreenOn = false; 1636 1637 // We're "undoing" a the prior preventScreenOn(true) call, so we 1638 // no longer need the 5-second safeguard. 1639 mHandler.removeCallbacks(mForceReenableScreenTask); 1640 1641 // Forcibly turn on the screen if it's supposed to be on. (This 1642 // handles the case where the screen is currently off because of 1643 // a prior preventScreenOn(true) call.) 1644 if (!mProximitySensorActive && (mPowerState & SCREEN_ON_BIT) != 0) { 1645 if (DEBUG) { 1646 Slog.d(TAG, 1647 "preventScreenOn: turning on after a prior preventScreenOn(true)!"); 1648 } 1649 int err = setScreenStateLocked(true); 1650 if (err != 0) { 1651 Slog.w(TAG, "preventScreenOn: error from setScreenStateLocked(): " + err); 1652 } 1653 } 1654 1655 // Release the partial wake lock that we held during the 1656 // preventScreenOn(true) -> preventScreenOn(false) sequence. 1657 mPreventScreenOnPartialLock.release(); 1658 } 1659 } 1660 } 1661 1662 public void setScreenBrightnessOverride(int brightness) { 1663 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 1664 1665 if (DEBUG) Slog.d(TAG, "setScreenBrightnessOverride " + brightness); 1666 synchronized (mLocks) { 1667 if (mScreenBrightnessOverride != brightness) { 1668 mScreenBrightnessOverride = brightness; 1669 if (isScreenOn()) { 1670 updateLightsLocked(mPowerState, SCREEN_ON_BIT); 1671 } 1672 } 1673 } 1674 } 1675 1676 public void setButtonBrightnessOverride(int brightness) { 1677 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 1678 1679 if (DEBUG) Slog.d(TAG, "setButtonBrightnessOverride " + brightness); 1680 synchronized (mLocks) { 1681 if (mButtonBrightnessOverride != brightness) { 1682 mButtonBrightnessOverride = brightness; 1683 if (isScreenOn()) { 1684 updateLightsLocked(mPowerState, BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT); 1685 } 1686 } 1687 } 1688 } 1689 1690 /** 1691 * Sanity-check that gets called 5 seconds after any call to 1692 * preventScreenOn(true). This ensures that the original call 1693 * is followed promptly by a call to preventScreenOn(false). 1694 */ 1695 private void forceReenableScreen() { 1696 // We shouldn't get here at all if mPreventScreenOn is false, since 1697 // we should have already removed any existing 1698 // mForceReenableScreenTask messages... 1699 if (!mPreventScreenOn) { 1700 Slog.w(TAG, "forceReenableScreen: mPreventScreenOn is false, nothing to do"); 1701 return; 1702 } 1703 1704 // Uh oh. It's been 5 seconds since a call to 1705 // preventScreenOn(true) and we haven't re-enabled the screen yet. 1706 // This means the app that called preventScreenOn(true) is either 1707 // slow (i.e. it took more than 5 seconds to call preventScreenOn(false)), 1708 // or buggy (i.e. it forgot to call preventScreenOn(false), or 1709 // crashed before doing so.) 1710 1711 // Log a warning, and forcibly turn the screen back on. 1712 Slog.w(TAG, "App called preventScreenOn(true) but didn't promptly reenable the screen! " 1713 + "Forcing the screen back on..."); 1714 preventScreenOn(false); 1715 } 1716 1717 private Runnable mForceReenableScreenTask = new Runnable() { 1718 public void run() { 1719 forceReenableScreen(); 1720 } 1721 }; 1722 1723 private int setScreenStateLocked(boolean on) { 1724 if (DEBUG_SCREEN_ON) { 1725 RuntimeException e = new RuntimeException("here"); 1726 e.fillInStackTrace(); 1727 Slog.i(TAG, "Set screen state: " + on, e); 1728 } 1729 if (on) { 1730 if ((mPowerState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) { 1731 // If we are turning the screen state on, but the screen 1732 // light is currently off, then make sure that we set the 1733 // light at this point to 0. This is the case where we are 1734 // turning on the screen and waiting for the UI to be drawn 1735 // before showing it to the user. We want the light off 1736 // until it is ready to be shown to the user, not it using 1737 // whatever the last value it had. 1738 if (DEBUG_SCREEN_ON) { 1739 Slog.i(TAG, "Forcing brightness 0: mPowerState=0x" 1740 + Integer.toHexString(mPowerState) 1741 + " mSkippedScreenOn=" + mSkippedScreenOn); 1742 } 1743 mScreenBrightnessAnimator.animateTo(PowerManager.BRIGHTNESS_OFF, SCREEN_BRIGHT_BIT, 0); 1744 } 1745 } 1746 int err = nativeSetScreenState(on); 1747 if (err == 0) { 1748 mLastScreenOnTime = (on ? SystemClock.elapsedRealtime() : 0); 1749 if (mUseSoftwareAutoBrightness) { 1750 enableLightSensorLocked(on); 1751 if (on) { 1752 // If AutoBrightness is enabled, set the brightness immediately after the 1753 // next sensor value is received. 1754 mWaitingForFirstLightSensor = mAutoBrightessEnabled; 1755 } else { 1756 // make sure button and key backlights are off too 1757 mButtonLight.turnOff(); 1758 mKeyboardLight.turnOff(); 1759 } 1760 } 1761 } 1762 return err; 1763 } 1764 1765 private void setPowerState(int state) 1766 { 1767 setPowerState(state, false, WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT); 1768 } 1769 1770 private void setPowerState(int newState, boolean noChangeLights, int reason) 1771 { 1772 synchronized (mLocks) { 1773 int err; 1774 1775 if (DEBUG) { 1776 Slog.d(TAG, "setPowerState: mPowerState=0x" + Integer.toHexString(mPowerState) 1777 + " newState=0x" + Integer.toHexString(newState) 1778 + " noChangeLights=" + noChangeLights 1779 + " reason=" + reason); 1780 } 1781 1782 if (noChangeLights) { 1783 newState = (newState & ~LIGHTS_MASK) | (mPowerState & LIGHTS_MASK); 1784 } 1785 if (mProximitySensorActive) { 1786 // don't turn on the screen when the proximity sensor lock is held 1787 newState = (newState & ~SCREEN_BRIGHT); 1788 } 1789 1790 if (batteryIsLow()) { 1791 newState |= BATTERY_LOW_BIT; 1792 } else { 1793 newState &= ~BATTERY_LOW_BIT; 1794 } 1795 if (newState == mPowerState && mInitialized) { 1796 return; 1797 } 1798 1799 if (!mBootCompleted && !mUseSoftwareAutoBrightness) { 1800 newState |= ALL_BRIGHT; 1801 } 1802 1803 boolean oldScreenOn = (mPowerState & SCREEN_ON_BIT) != 0; 1804 boolean newScreenOn = (newState & SCREEN_ON_BIT) != 0; 1805 1806 if (DEBUG) { 1807 Slog.d(TAG, "setPowerState: mPowerState=" + mPowerState 1808 + " newState=" + newState + " noChangeLights=" + noChangeLights); 1809 Slog.d(TAG, " oldKeyboardBright=" + ((mPowerState & KEYBOARD_BRIGHT_BIT) != 0) 1810 + " newKeyboardBright=" + ((newState & KEYBOARD_BRIGHT_BIT) != 0)); 1811 Slog.d(TAG, " oldScreenBright=" + ((mPowerState & SCREEN_BRIGHT_BIT) != 0) 1812 + " newScreenBright=" + ((newState & SCREEN_BRIGHT_BIT) != 0)); 1813 Slog.d(TAG, " oldButtonBright=" + ((mPowerState & BUTTON_BRIGHT_BIT) != 0) 1814 + " newButtonBright=" + ((newState & BUTTON_BRIGHT_BIT) != 0)); 1815 Slog.d(TAG, " oldScreenOn=" + oldScreenOn 1816 + " newScreenOn=" + newScreenOn); 1817 Slog.d(TAG, " oldBatteryLow=" + ((mPowerState & BATTERY_LOW_BIT) != 0) 1818 + " newBatteryLow=" + ((newState & BATTERY_LOW_BIT) != 0)); 1819 } 1820 1821 final boolean stateChanged = mPowerState != newState; 1822 1823 if (stateChanged && reason == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT) { 1824 if (mPolicy != null && mPolicy.isScreenSaverEnabled()) { 1825 if (DEBUG) { 1826 Slog.d(TAG, "setPowerState: running screen saver instead of turning off screen"); 1827 } 1828 if (mPolicy.startScreenSaver()) { 1829 // was successful 1830 return; 1831 } 1832 } 1833 } 1834 1835 1836 if (oldScreenOn != newScreenOn) { 1837 if (newScreenOn) { 1838 // When the user presses the power button, we need to always send out the 1839 // notification that it's going to sleep so the keyguard goes on. But 1840 // we can't do that until the screen fades out, so we don't show the keyguard 1841 // too early. 1842 if (mStillNeedSleepNotification) { 1843 sendNotificationLocked(false, WindowManagerPolicy.OFF_BECAUSE_OF_USER); 1844 } 1845 1846 // Turn on the screen UNLESS there was a prior 1847 // preventScreenOn(true) request. (Note that the lifetime 1848 // of a single preventScreenOn() request is limited to 5 1849 // seconds to prevent a buggy app from disabling the 1850 // screen forever; see forceReenableScreen().) 1851 boolean reallyTurnScreenOn = true; 1852 if (DEBUG) { 1853 Slog.d(TAG, "- turning screen on... mPreventScreenOn = " 1854 + mPreventScreenOn); 1855 } 1856 1857 if (mPreventScreenOn) { 1858 if (DEBUG) { 1859 Slog.d(TAG, "- PREVENTING screen from really turning on!"); 1860 } 1861 reallyTurnScreenOn = false; 1862 } 1863 if (reallyTurnScreenOn) { 1864 err = setScreenStateLocked(true); 1865 long identity = Binder.clearCallingIdentity(); 1866 try { 1867 mBatteryStats.noteScreenBrightness(getPreferredBrightness()); 1868 mBatteryStats.noteScreenOn(); 1869 } catch (RemoteException e) { 1870 Slog.w(TAG, "RemoteException calling noteScreenOn on BatteryStatsService", e); 1871 } finally { 1872 Binder.restoreCallingIdentity(identity); 1873 } 1874 } else { 1875 setScreenStateLocked(false); 1876 // But continue as if we really did turn the screen on... 1877 err = 0; 1878 } 1879 1880 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, reason, 0, 0); 1881 if (err == 0) { 1882 sendNotificationLocked(true, -1); 1883 // Update the lights *after* taking care of turning the 1884 // screen on, so we do this after our notifications are 1885 // enqueued and thus will delay turning on the screen light 1886 // until the windows are correctly displayed. 1887 if (stateChanged) { 1888 updateLightsLocked(newState, 0); 1889 } 1890 mPowerState |= SCREEN_ON_BIT; 1891 } 1892 1893 } else { 1894 // Update the lights *before* taking care of turning the 1895 // screen off, so we can initiate any animations that are desired. 1896 mScreenOffReason = reason; 1897 if (stateChanged) { 1898 updateLightsLocked(newState, 0); 1899 } 1900 1901 // cancel light sensor task 1902 mHandler.removeCallbacks(mAutoBrightnessTask); 1903 mLightSensorPendingDecrease = false; 1904 mLightSensorPendingIncrease = false; 1905 mScreenOffTime = SystemClock.elapsedRealtime(); 1906 long identity = Binder.clearCallingIdentity(); 1907 try { 1908 mBatteryStats.noteScreenOff(); 1909 } catch (RemoteException e) { 1910 Slog.w(TAG, "RemoteException calling noteScreenOff on BatteryStatsService", e); 1911 } finally { 1912 Binder.restoreCallingIdentity(identity); 1913 } 1914 mPowerState &= ~SCREEN_ON_BIT; 1915 if (!mScreenBrightnessAnimator.isAnimating()) { 1916 err = screenOffFinishedAnimatingLocked(reason); 1917 } else { 1918 err = 0; 1919 } 1920 } 1921 } else if (stateChanged) { 1922 // Screen on/off didn't change, but lights may have. 1923 updateLightsLocked(newState, 0); 1924 } 1925 1926 mPowerState = (mPowerState & ~LIGHTS_MASK) | (newState & LIGHTS_MASK); 1927 1928 updateNativePowerStateLocked(); 1929 } 1930 } 1931 1932 private void updateNativePowerStateLocked() { 1933 if (!mHeadless) { 1934 nativeSetPowerState( 1935 (mPowerState & SCREEN_ON_BIT) != 0, 1936 (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT); 1937 } 1938 } 1939 1940 private int screenOffFinishedAnimatingLocked(int reason) { 1941 // I don't think we need to check the current state here because all of these 1942 // Power.setScreenState and sendNotificationLocked can both handle being 1943 // called multiple times in the same state. -joeo 1944 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, reason, 0, 0); 1945 int err = setScreenStateLocked(false); 1946 if (err == 0) { 1947 mScreenOffReason = reason; 1948 sendNotificationLocked(false, reason); 1949 } 1950 return err; 1951 } 1952 1953 private boolean batteryIsLow() { 1954 return (!mIsPowered && 1955 mBatteryService.getBatteryLevel() <= LOW_BATTERY_THRESHOLD); 1956 } 1957 1958 private boolean shouldDeferScreenOnLocked() { 1959 if (mPreparingForScreenOn) { 1960 // Currently waiting for confirmation from the policy that it 1961 // is okay to turn on the screen. Don't allow the screen to go 1962 // on until that is done. 1963 if (DEBUG_SCREEN_ON) Slog.i(TAG, 1964 "updateLights: delaying screen on due to mPreparingForScreenOn"); 1965 return true; 1966 } else { 1967 // If there is a screen-on command in the notification queue, we 1968 // can't turn the screen on until it has been processed (and we 1969 // have set mPreparingForScreenOn) or it has been dropped. 1970 for (int i=0; i<mBroadcastQueue.length; i++) { 1971 if (mBroadcastQueue[i] == 1) { 1972 if (DEBUG_SCREEN_ON) Slog.i(TAG, 1973 "updateLights: delaying screen on due to notification queue"); 1974 return true; 1975 } 1976 } 1977 } 1978 return false; 1979 } 1980 1981 private void updateLightsLocked(int newState, int forceState) { 1982 final int oldState = mPowerState; 1983 1984 // If the screen is not currently on, we will want to delay actually 1985 // turning the lights on if we are still getting the UI put up. 1986 if ((oldState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) { 1987 // Don't turn screen on until we know we are really ready to. 1988 // This is to avoid letting the screen go on before things like the 1989 // lock screen have been displayed. 1990 if ((mSkippedScreenOn = shouldDeferScreenOnLocked())) { 1991 newState &= ~(SCREEN_ON_BIT|SCREEN_BRIGHT_BIT); 1992 } 1993 } 1994 1995 if ((newState & SCREEN_ON_BIT) != 0) { 1996 // Only turn on the buttons or keyboard if the screen is also on. 1997 // We should never see the buttons on but not the screen. 1998 newState = applyButtonState(newState); 1999 newState = applyKeyboardState(newState); 2000 } 2001 final int realDifference = (newState ^ oldState); 2002 final int difference = realDifference | forceState; 2003 if (difference == 0) { 2004 return; 2005 } 2006 2007 int offMask = 0; 2008 int dimMask = 0; 2009 int onMask = 0; 2010 2011 int preferredBrightness = getPreferredBrightness(); 2012 2013 if ((difference & KEYBOARD_BRIGHT_BIT) != 0) { 2014 if ((newState & KEYBOARD_BRIGHT_BIT) == 0) { 2015 offMask |= KEYBOARD_BRIGHT_BIT; 2016 } else { 2017 onMask |= KEYBOARD_BRIGHT_BIT; 2018 } 2019 } 2020 2021 if ((difference & BUTTON_BRIGHT_BIT) != 0) { 2022 if ((newState & BUTTON_BRIGHT_BIT) == 0) { 2023 offMask |= BUTTON_BRIGHT_BIT; 2024 } else { 2025 onMask |= BUTTON_BRIGHT_BIT; 2026 } 2027 } 2028 2029 if ((difference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) { 2030 int nominalCurrentValue = -1; 2031 // If there was an actual difference in the light state, then 2032 // figure out the "ideal" current value based on the previous 2033 // state. Otherwise, this is a change due to the brightness 2034 // override, so we want to animate from whatever the current 2035 // value is. 2036 if ((realDifference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) { 2037 switch (oldState & (SCREEN_BRIGHT_BIT|SCREEN_ON_BIT)) { 2038 case SCREEN_BRIGHT_BIT | SCREEN_ON_BIT: 2039 nominalCurrentValue = preferredBrightness; 2040 break; 2041 case SCREEN_ON_BIT: 2042 nominalCurrentValue = mScreenBrightnessDim; 2043 break; 2044 case 0: 2045 nominalCurrentValue = PowerManager.BRIGHTNESS_OFF; 2046 break; 2047 case SCREEN_BRIGHT_BIT: 2048 default: 2049 // not possible 2050 nominalCurrentValue = (int)mScreenBrightnessAnimator.getCurrentBrightness(); 2051 break; 2052 } 2053 } 2054 int brightness = preferredBrightness; 2055 int steps = ANIM_STEPS; 2056 if ((newState & SCREEN_BRIGHT_BIT) == 0) { 2057 // dim or turn off backlight, depending on if the screen is on 2058 // the scale is because the brightness ramp isn't linear and this biases 2059 // it so the later parts take longer. 2060 final float scale = 1.5f; 2061 float ratio = (((float)mScreenBrightnessDim)/preferredBrightness); 2062 if (ratio > 1.0f) ratio = 1.0f; 2063 if ((newState & SCREEN_ON_BIT) == 0) { 2064 if ((oldState & SCREEN_BRIGHT_BIT) != 0) { 2065 // was bright 2066 steps = ANIM_STEPS; 2067 } else { 2068 // was dim 2069 steps = (int)(ANIM_STEPS*ratio*scale); 2070 } 2071 brightness = PowerManager.BRIGHTNESS_OFF; 2072 } else { 2073 if ((oldState & SCREEN_ON_BIT) != 0) { 2074 // was bright 2075 steps = (int)(ANIM_STEPS*(1.0f-ratio)*scale); 2076 } else { 2077 // was dim 2078 steps = (int)(ANIM_STEPS*ratio); 2079 } 2080 final int stayOnConditions = getStayOnConditionsLocked(); 2081 if (stayOnConditions != 0 && mBatteryService.isPowered(stayOnConditions)) { 2082 // If the "stay on while plugged in" option is 2083 // turned on, then the screen will often not 2084 // automatically turn off while plugged in. To 2085 // still have a sense of when it is inactive, we 2086 // will then count going dim as turning off. 2087 mScreenOffTime = SystemClock.elapsedRealtime(); 2088 } 2089 brightness = mScreenBrightnessDim; 2090 } 2091 } 2092 if (mWaitingForFirstLightSensor && (newState & SCREEN_ON_BIT) != 0) { 2093 steps = IMMEDIATE_ANIM_STEPS; 2094 } 2095 2096 long identity = Binder.clearCallingIdentity(); 2097 try { 2098 mBatteryStats.noteScreenBrightness(brightness); 2099 } catch (RemoteException e) { 2100 // Nothing interesting to do. 2101 } finally { 2102 Binder.restoreCallingIdentity(identity); 2103 } 2104 if (!mSkippedScreenOn) { 2105 int dt = steps * NOMINAL_FRAME_TIME_MS; 2106 mScreenBrightnessAnimator.animateTo(brightness, SCREEN_BRIGHT_BIT, dt); 2107 if (DEBUG_SCREEN_ON) { 2108 RuntimeException e = new RuntimeException("here"); 2109 e.fillInStackTrace(); 2110 Slog.i(TAG, "Setting screen brightness: " + brightness, e); 2111 } 2112 } 2113 } 2114 2115 if (DEBUG) { 2116 Slog.d(TAG, "offMask=0x" + Integer.toHexString(offMask) 2117 + " dimMask=0x" + Integer.toHexString(dimMask) 2118 + " onMask=0x" + Integer.toHexString(onMask) 2119 + " difference=0x" + Integer.toHexString(difference) 2120 + " realDifference=0x" + Integer.toHexString(realDifference) 2121 + " forceState=0x" + Integer.toHexString(forceState) 2122 ); 2123 } 2124 2125 if (offMask != 0) { 2126 if (DEBUG) Slog.i(TAG, "Setting brightess off: " + offMask); 2127 setLightBrightness(offMask, PowerManager.BRIGHTNESS_OFF); 2128 } 2129 if (dimMask != 0) { 2130 int brightness = mScreenBrightnessDim; 2131 if ((newState & BATTERY_LOW_BIT) != 0 && 2132 brightness > PowerManager.BRIGHTNESS_LOW_BATTERY) { 2133 brightness = PowerManager.BRIGHTNESS_LOW_BATTERY; 2134 } 2135 if (DEBUG) Slog.i(TAG, "Setting brightess dim " + brightness + ": " + dimMask); 2136 setLightBrightness(dimMask, brightness); 2137 } 2138 if (onMask != 0) { 2139 int brightness = getPreferredBrightness(); 2140 if ((newState & BATTERY_LOW_BIT) != 0 && 2141 brightness > PowerManager.BRIGHTNESS_LOW_BATTERY) { 2142 brightness = PowerManager.BRIGHTNESS_LOW_BATTERY; 2143 } 2144 if (DEBUG) Slog.i(TAG, "Setting brightess on " + brightness + ": " + onMask); 2145 setLightBrightness(onMask, brightness); 2146 } 2147 } 2148 2149 /** 2150 * Note: by design this class does not hold mLocks while calling native methods. 2151 * Nor should it. Ever. 2152 */ 2153 class ScreenBrightnessAnimator extends HandlerThread { 2154 static final int ANIMATE_LIGHTS = 10; 2155 static final int ANIMATE_POWER_OFF = 11; 2156 volatile int startValue; 2157 volatile int endValue; 2158 volatile int startSensorValue; 2159 volatile int endSensorValue; 2160 volatile int currentValue; 2161 private int currentMask; 2162 private int duration; 2163 private long startTimeMillis; 2164 private final String prefix; 2165 2166 public ScreenBrightnessAnimator(String name, int priority) { 2167 super(name, priority); 2168 prefix = name; 2169 } 2170 2171 @Override 2172 protected void onLooperPrepared() { 2173 mScreenBrightnessHandler = new Handler() { 2174 public void handleMessage(Message msg) { 2175 int brightnessMode = (mAutoBrightessEnabled && !mInitialAnimation 2176 ? LightsService.BRIGHTNESS_MODE_SENSOR 2177 : LightsService.BRIGHTNESS_MODE_USER); 2178 if (msg.what == ANIMATE_LIGHTS) { 2179 final int mask = msg.arg1; 2180 int value = msg.arg2; 2181 long tStart = SystemClock.uptimeMillis(); 2182 if ((mask & SCREEN_BRIGHT_BIT) != 0) { 2183 if (DEBUG_LIGHT_ANIMATION) Slog.v(TAG, "Set brightness: " + value); 2184 mLcdLight.setBrightness(value, brightnessMode); 2185 } 2186 long elapsed = SystemClock.uptimeMillis() - tStart; 2187 if ((mask & BUTTON_BRIGHT_BIT) != 0) { 2188 mButtonLight.setBrightness(value); 2189 } 2190 if ((mask & KEYBOARD_BRIGHT_BIT) != 0) { 2191 mKeyboardLight.setBrightness(value); 2192 } 2193 2194 if (elapsed > 100) { 2195 Slog.e(TAG, "Excessive delay setting brightness: " + elapsed 2196 + "ms, mask=" + mask); 2197 } 2198 2199 // Throttle brightness updates to frame refresh rate 2200 int delay = elapsed < NOMINAL_FRAME_TIME_MS ? NOMINAL_FRAME_TIME_MS : 1; 2201 synchronized(this) { 2202 currentValue = value; 2203 } 2204 animateInternal(mask, false, delay); 2205 } else if (msg.what == ANIMATE_POWER_OFF) { 2206 int mode = msg.arg1; 2207 nativeStartSurfaceFlingerAnimation(mode); 2208 } 2209 } 2210 }; 2211 synchronized (this) { 2212 mInitComplete = true; 2213 notifyAll(); 2214 } 2215 } 2216 2217 private void animateInternal(int mask, boolean turningOff, int delay) { 2218 synchronized (this) { 2219 if (currentValue != endValue) { 2220 final long now = SystemClock.elapsedRealtime(); 2221 final int elapsed = (int) (now - startTimeMillis); 2222 int newValue; 2223 if (elapsed < duration) { 2224 int delta = endValue - startValue; 2225 newValue = startValue + delta * elapsed / duration; 2226 newValue = Math.max(PowerManager.BRIGHTNESS_OFF, newValue); 2227 newValue = Math.min(PowerManager.BRIGHTNESS_ON, newValue); 2228 // Optimization to delay next step until a change will occur. 2229 if (delay > 0 && newValue == currentValue) { 2230 final int timePerStep = duration / Math.abs(delta); 2231 delay = Math.min(duration - elapsed, timePerStep); 2232 newValue += delta < 0 ? -1 : 1; 2233 } 2234 // adjust the peak sensor value until we get to the target sensor value 2235 delta = endSensorValue - startSensorValue; 2236 mHighestLightSensorValue = startSensorValue + delta * elapsed / duration; 2237 } else { 2238 newValue = endValue; 2239 mHighestLightSensorValue = endSensorValue; 2240 if (endValue > 0) { 2241 mInitialAnimation = false; 2242 } 2243 } 2244 2245 if (DEBUG_LIGHT_ANIMATION) { 2246 Slog.v(TAG, "Animating light: " + "start:" + startValue 2247 + ", end:" + endValue + ", elapsed:" + elapsed 2248 + ", duration:" + duration + ", current:" + currentValue 2249 + ", newValue:" + newValue 2250 + ", delay:" + delay 2251 + ", highestSensor:" + mHighestLightSensorValue); 2252 } 2253 2254 if (turningOff && !mHeadless && !mAnimateScreenLights) { 2255 int mode = mScreenOffReason == OFF_BECAUSE_OF_PROX_SENSOR 2256 ? 0 : mAnimationSetting; 2257 if (DEBUG_LIGHT_ANIMATION) { 2258 Slog.v(TAG, "Doing power-off anim, mode=" + mode); 2259 } 2260 mScreenBrightnessHandler.obtainMessage(ANIMATE_POWER_OFF, mode, 0) 2261 .sendToTarget(); 2262 } 2263 mScreenBrightnessHandler.removeMessages( 2264 ScreenBrightnessAnimator.ANIMATE_LIGHTS); 2265 Message msg = mScreenBrightnessHandler 2266 .obtainMessage(ANIMATE_LIGHTS, mask, newValue); 2267 mScreenBrightnessHandler.sendMessageDelayed(msg, delay); 2268 } 2269 } 2270 } 2271 2272 public void dump(PrintWriter pw, String string) { 2273 pw.println(string); 2274 pw.println(" animating: " + "start:" + startValue + ", end:" + endValue 2275 + ", duration:" + duration + ", current:" + currentValue); 2276 pw.println(" startSensorValue:" + startSensorValue 2277 + " endSensorValue:" + endSensorValue); 2278 pw.println(" startSensorValue:" + startSensorValue 2279 + " endSensorValue:" + endSensorValue); 2280 } 2281 2282 public void animateTo(int target, int mask, int animationDuration) { 2283 animateTo(target, mHighestLightSensorValue, mask, animationDuration); 2284 } 2285 2286 public void animateTo(int target, int sensorTarget, int mask, int animationDuration) { 2287 synchronized(this) { 2288 if ((mask & SCREEN_BRIGHT_BIT) == 0) { 2289 // We only animate keyboard and button when passed in with SCREEN_BRIGHT_BIT. 2290 if ((mask & BUTTON_BRIGHT_BIT) != 0) { 2291 mButtonLight.setBrightness(target); 2292 } 2293 if ((mask & KEYBOARD_BRIGHT_BIT) != 0) { 2294 mKeyboardLight.setBrightness(target); 2295 } 2296 return; 2297 } 2298 if (isAnimating() && (mask ^ currentMask) != 0) { 2299 // current animation is unrelated to new animation, jump to final values 2300 cancelAnimation(); 2301 } 2302 startValue = currentValue; 2303 endValue = target; 2304 startSensorValue = mHighestLightSensorValue; 2305 endSensorValue = sensorTarget; 2306 currentMask = mask; 2307 duration = (int) (mWindowScaleAnimation * animationDuration); 2308 startTimeMillis = SystemClock.elapsedRealtime(); 2309 mInitialAnimation = mInitialAnimation && target > 0; 2310 2311 if (DEBUG_LIGHT_ANIMATION) { 2312 Slog.v(TAG, "animateTo(target=" + target 2313 + ", sensor=" + sensorTarget 2314 + ", mask=" + mask 2315 + ", duration=" + animationDuration +")" 2316 + ", currentValue=" + currentValue 2317 + ", startTime=" + startTimeMillis); 2318 } 2319 2320 if (target != currentValue) { 2321 final boolean doScreenAnim = (mask & (SCREEN_BRIGHT_BIT | SCREEN_ON_BIT)) != 0; 2322 final boolean turningOff = endValue == PowerManager.BRIGHTNESS_OFF; 2323 if (turningOff && doScreenAnim) { 2324 // Cancel all pending animations since we're turning off 2325 mScreenBrightnessHandler.removeCallbacksAndMessages(null); 2326 screenOffFinishedAnimatingLocked(mScreenOffReason); 2327 duration = 200; // TODO: how long should this be? 2328 } 2329 if (doScreenAnim) { 2330 animateInternal(mask, turningOff, 0); 2331 } 2332 // TODO: Handle keyboard light animation when we have devices that support it 2333 } 2334 } 2335 } 2336 2337 public int getCurrentBrightness() { 2338 synchronized (this) { 2339 return currentValue; 2340 } 2341 } 2342 2343 public boolean isAnimating() { 2344 synchronized (this) { 2345 return currentValue != endValue; 2346 } 2347 } 2348 2349 public void cancelAnimation() { 2350 animateTo(endValue, currentMask, 0); 2351 } 2352 } 2353 2354 private void setLightBrightness(int mask, int value) { 2355 mScreenBrightnessAnimator.animateTo(value, mask, 0); 2356 } 2357 2358 private int getPreferredBrightness() { 2359 int brightness = mScreenBrightnessSetting; 2360 if (mScreenBrightnessOverride >= 0) { 2361 brightness = mScreenBrightnessOverride; 2362 } else if (mLightSensorScreenBrightness >= 0 && mUseSoftwareAutoBrightness 2363 && mAutoBrightessEnabled) { 2364 brightness = mLightSensorScreenBrightness; 2365 } 2366 // Don't let applications turn the screen all the way off 2367 return Math.max(brightness, mScreenBrightnessDim); 2368 } 2369 2370 private int applyButtonState(int state) { 2371 int brightness = -1; 2372 if ((state & BATTERY_LOW_BIT) != 0) { 2373 // do not override brightness if the battery is low 2374 return state; 2375 } 2376 if (mButtonBrightnessOverride >= 0) { 2377 brightness = mButtonBrightnessOverride; 2378 } else if (mLightSensorButtonBrightness >= 0 && mUseSoftwareAutoBrightness) { 2379 brightness = mLightSensorButtonBrightness; 2380 } 2381 if (brightness > 0) { 2382 return state | BUTTON_BRIGHT_BIT; 2383 } else if (brightness == 0) { 2384 return state & ~BUTTON_BRIGHT_BIT; 2385 } else { 2386 return state; 2387 } 2388 } 2389 2390 private int applyKeyboardState(int state) { 2391 int brightness = -1; 2392 if ((state & BATTERY_LOW_BIT) != 0) { 2393 // do not override brightness if the battery is low 2394 return state; 2395 } 2396 if (!mKeyboardVisible) { 2397 brightness = 0; 2398 } else if (mButtonBrightnessOverride >= 0) { 2399 brightness = mButtonBrightnessOverride; 2400 } else if (mLightSensorKeyboardBrightness >= 0 && mUseSoftwareAutoBrightness) { 2401 brightness = mLightSensorKeyboardBrightness; 2402 } 2403 if (brightness > 0) { 2404 return state | KEYBOARD_BRIGHT_BIT; 2405 } else if (brightness == 0) { 2406 return state & ~KEYBOARD_BRIGHT_BIT; 2407 } else { 2408 return state; 2409 } 2410 } 2411 2412 public boolean isScreenOn() { 2413 synchronized (mLocks) { 2414 return (mPowerState & SCREEN_ON_BIT) != 0; 2415 } 2416 } 2417 2418 boolean isScreenBright() { 2419 synchronized (mLocks) { 2420 return (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT; 2421 } 2422 } 2423 2424 private boolean isScreenTurningOffLocked() { 2425 return (mScreenBrightnessAnimator.isAnimating() 2426 && mScreenBrightnessAnimator.endValue == PowerManager.BRIGHTNESS_OFF 2427 && (mScreenBrightnessAnimator.currentMask & SCREEN_BRIGHT_BIT) != 0); 2428 } 2429 2430 private boolean shouldLog(long time) { 2431 synchronized (mLocks) { 2432 if (time > (mWarningSpewThrottleTime + (60*60*1000))) { 2433 mWarningSpewThrottleTime = time; 2434 mWarningSpewThrottleCount = 0; 2435 return true; 2436 } else if (mWarningSpewThrottleCount < 30) { 2437 mWarningSpewThrottleCount++; 2438 return true; 2439 } else { 2440 return false; 2441 } 2442 } 2443 } 2444 2445 private void forceUserActivityLocked() { 2446 if (isScreenTurningOffLocked()) { 2447 // cancel animation so userActivity will succeed 2448 mScreenBrightnessAnimator.cancelAnimation(); 2449 } 2450 boolean savedActivityAllowed = mUserActivityAllowed; 2451 mUserActivityAllowed = true; 2452 userActivity(SystemClock.uptimeMillis(), false); 2453 mUserActivityAllowed = savedActivityAllowed; 2454 } 2455 2456 public void userActivityWithForce(long time, boolean noChangeLights, boolean force) { 2457 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 2458 userActivity(time, -1, noChangeLights, OTHER_EVENT, force); 2459 } 2460 2461 public void userActivity(long time, boolean noChangeLights) { 2462 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER) 2463 != PackageManager.PERMISSION_GRANTED) { 2464 if (shouldLog(time)) { 2465 Slog.w(TAG, "Caller does not have DEVICE_POWER permission. pid=" 2466 + Binder.getCallingPid() + " uid=" + Binder.getCallingUid()); 2467 } 2468 return; 2469 } 2470 2471 userActivity(time, -1, noChangeLights, OTHER_EVENT, false); 2472 } 2473 2474 public void userActivity(long time, boolean noChangeLights, int eventType) { 2475 userActivity(time, -1, noChangeLights, eventType, false); 2476 } 2477 2478 public void userActivity(long time, boolean noChangeLights, int eventType, boolean force) { 2479 userActivity(time, -1, noChangeLights, eventType, force); 2480 } 2481 2482 /* 2483 * Reset the user activity timeout to now + timeout. This overrides whatever else is going 2484 * on with user activity. Don't use this function. 2485 */ 2486 public void clearUserActivityTimeout(long now, long timeout) { 2487 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 2488 Slog.i(TAG, "clearUserActivity for " + timeout + "ms from now"); 2489 userActivity(now, timeout, false, OTHER_EVENT, false); 2490 } 2491 2492 private void userActivity(long time, long timeoutOverride, boolean noChangeLights, 2493 int eventType, boolean force) { 2494 2495 if (((mPokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0) && (eventType == TOUCH_EVENT)) { 2496 if (false) { 2497 Slog.d(TAG, "dropping touch mPokey=0x" + Integer.toHexString(mPokey)); 2498 } 2499 return; 2500 } 2501 2502 synchronized (mLocks) { 2503 if (DEBUG) { 2504 Slog.d(TAG, "userActivity mLastEventTime=" + mLastEventTime + " time=" + time 2505 + " mUserActivityAllowed=" + mUserActivityAllowed 2506 + " mUserState=0x" + Integer.toHexString(mUserState) 2507 + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState) 2508 + " mProximitySensorActive=" + mProximitySensorActive 2509 + " timeoutOverride=" + timeoutOverride 2510 + " force=" + force); 2511 } 2512 // ignore user activity if we are in the process of turning off the screen 2513 if (isScreenTurningOffLocked()) { 2514 Slog.d(TAG, "ignoring user activity while turning off screen"); 2515 return; 2516 } 2517 // Disable proximity sensor if if user presses power key while we are in the 2518 // "waiting for proximity sensor to go negative" state. 2519 if (mProximitySensorActive && mProximityWakeLockCount == 0) { 2520 mProximitySensorActive = false; 2521 } 2522 if (mLastEventTime <= time || force) { 2523 mLastEventTime = time; 2524 if ((mUserActivityAllowed && !mProximitySensorActive) || force) { 2525 // Only turn on button backlights if a button was pressed 2526 // and auto brightness is disabled 2527 if (eventType == BUTTON_EVENT && !mUseSoftwareAutoBrightness) { 2528 mUserState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT); 2529 } else { 2530 // don't clear button/keyboard backlights when the screen is touched. 2531 mUserState |= SCREEN_BRIGHT; 2532 } 2533 2534 int uid = Binder.getCallingUid(); 2535 long ident = Binder.clearCallingIdentity(); 2536 try { 2537 mBatteryStats.noteUserActivity(uid, eventType); 2538 } catch (RemoteException e) { 2539 // Ignore 2540 } finally { 2541 Binder.restoreCallingIdentity(ident); 2542 } 2543 2544 mWakeLockState = mLocks.reactivateScreenLocksLocked(); 2545 setPowerState(mUserState | mWakeLockState, noChangeLights, 2546 WindowManagerPolicy.OFF_BECAUSE_OF_USER); 2547 setTimeoutLocked(time, timeoutOverride, SCREEN_BRIGHT); 2548 } 2549 } 2550 } 2551 2552 if (mPolicy != null) { 2553 mPolicy.userActivity(); 2554 } 2555 } 2556 2557 private int getAutoBrightnessValue(int sensorValue, int[] values) { 2558 try { 2559 int i; 2560 for (i = 0; i < mAutoBrightnessLevels.length; i++) { 2561 if (sensorValue < mAutoBrightnessLevels[i]) { 2562 break; 2563 } 2564 } 2565 // This is the range of brightness values that we can use. 2566 final int minval = values[0]; 2567 final int maxval = values[mAutoBrightnessLevels.length]; 2568 // This is the range we will be scaling. We put some padding 2569 // at the low and high end to give the adjustment a little better 2570 // impact on the actual observed value. 2571 final int range = (maxval-minval) + LIGHT_SENSOR_RANGE_EXPANSION; 2572 // This is the desired brightness value from 0.0 to 1.0. 2573 float valf = ((values[i]-minval+(LIGHT_SENSOR_RANGE_EXPANSION/2))/(float)range); 2574 // Apply a scaling to the value based on the adjustment. 2575 if (mLightSensorAdjustSetting > 0 && mLightSensorAdjustSetting <= 1) { 2576 float adj = (float)Math.sqrt(1.0f-mLightSensorAdjustSetting); 2577 if (adj <= .00001) { 2578 valf = 1; 2579 } else { 2580 valf /= adj; 2581 } 2582 } else if (mLightSensorAdjustSetting < 0 && mLightSensorAdjustSetting >= -1) { 2583 float adj = (float)Math.sqrt(1.0f+mLightSensorAdjustSetting); 2584 valf *= adj; 2585 } 2586 // Apply an additional offset to the value based on the adjustment. 2587 valf += mLightSensorAdjustSetting/LIGHT_SENSOR_OFFSET_SCALE; 2588 // Convert the 0.0-1.0 value back to a brightness integer. 2589 int val = (int)((valf*range)+minval) - (LIGHT_SENSOR_RANGE_EXPANSION/2); 2590 if (val < minval) val = minval; 2591 else if (val > maxval) val = maxval; 2592 return val; 2593 } catch (Exception e) { 2594 // guard against null pointer or index out of bounds errors 2595 Slog.e(TAG, "Values array must be non-empty and must be one element longer than " 2596 + "the auto-brightness levels array. Check config.xml.", e); 2597 return 255; 2598 } 2599 } 2600 2601 private Runnable mProximityTask = new Runnable() { 2602 public void run() { 2603 synchronized (mLocks) { 2604 if (mProximityPendingValue != -1) { 2605 proximityChangedLocked(mProximityPendingValue == 1); 2606 mProximityPendingValue = -1; 2607 } 2608 if (mProximityPartialLock.isHeld()) { 2609 mProximityPartialLock.release(); 2610 } 2611 } 2612 } 2613 }; 2614 2615 private Runnable mAutoBrightnessTask = new Runnable() { 2616 public void run() { 2617 synchronized (mLocks) { 2618 if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) { 2619 int value = (int)mLightSensorPendingValue; 2620 mLightSensorPendingDecrease = false; 2621 mLightSensorPendingIncrease = false; 2622 lightSensorChangedLocked(value, false); 2623 } 2624 } 2625 } 2626 }; 2627 2628 /** used to prevent lightsensor changes while turning on. */ 2629 private boolean mInitialAnimation = true; 2630 2631 private void dockStateChanged(int state) { 2632 synchronized (mLocks) { 2633 mIsDocked = (state != Intent.EXTRA_DOCK_STATE_UNDOCKED); 2634 if (mIsDocked) { 2635 // allow brightness to decrease when docked 2636 mHighestLightSensorValue = -1; 2637 } 2638 if ((mPowerState & SCREEN_ON_BIT) != 0) { 2639 // force lights recalculation 2640 int value = (int)mLightSensorValue; 2641 mLightSensorValue = -1; 2642 lightSensorChangedLocked(value, false); 2643 } 2644 } 2645 } 2646 2647 private void lightSensorChangedLocked(int value, boolean immediate) { 2648 if (DEBUG_LIGHT_SENSOR) { 2649 Slog.d(TAG, "lightSensorChangedLocked value=" + value + " immediate=" + immediate); 2650 } 2651 2652 // Don't do anything if the screen is off. 2653 if ((mPowerState & SCREEN_ON_BIT) == 0) { 2654 if (DEBUG_LIGHT_SENSOR) { 2655 Slog.d(TAG, "dropping lightSensorChangedLocked because screen is off"); 2656 } 2657 return; 2658 } 2659 2660 if (mLightSensorValue != value) { 2661 mLightSensorValue = value; 2662 if ((mPowerState & BATTERY_LOW_BIT) == 0) { 2663 // use maximum light sensor value seen since screen went on for LCD to avoid flicker 2664 // we only do this if we are undocked, since lighting should be stable when 2665 // stationary in a dock. 2666 int lcdValue = getAutoBrightnessValue(value, mLcdBacklightValues); 2667 int buttonValue = getAutoBrightnessValue(value, mButtonBacklightValues); 2668 int keyboardValue; 2669 if (mKeyboardVisible) { 2670 keyboardValue = getAutoBrightnessValue(value, mKeyboardBacklightValues); 2671 } else { 2672 keyboardValue = 0; 2673 } 2674 mLightSensorScreenBrightness = lcdValue; 2675 mLightSensorButtonBrightness = buttonValue; 2676 mLightSensorKeyboardBrightness = keyboardValue; 2677 2678 if (DEBUG_LIGHT_SENSOR) { 2679 Slog.d(TAG, "lcdValue " + lcdValue); 2680 Slog.d(TAG, "buttonValue " + buttonValue); 2681 Slog.d(TAG, "keyboardValue " + keyboardValue); 2682 } 2683 2684 if (mAutoBrightessEnabled && mScreenBrightnessOverride < 0) { 2685 if (!mSkippedScreenOn && !mInitialAnimation) { 2686 final int steps; 2687 if (immediate) { 2688 steps = IMMEDIATE_ANIM_STEPS; 2689 } else { 2690 synchronized (mScreenBrightnessAnimator) { 2691 if (mScreenBrightnessAnimator.currentValue <= lcdValue) { 2692 steps = AUTOBRIGHTNESS_ANIM_STEPS; 2693 } else { 2694 steps = AUTODIMNESS_ANIM_STEPS; 2695 } 2696 } 2697 } 2698 mScreenBrightnessAnimator.animateTo(lcdValue, value, 2699 SCREEN_BRIGHT_BIT, steps * NOMINAL_FRAME_TIME_MS); 2700 } 2701 } 2702 if (mButtonBrightnessOverride < 0) { 2703 mButtonLight.setBrightness(buttonValue); 2704 } 2705 if (mButtonBrightnessOverride < 0 || !mKeyboardVisible) { 2706 mKeyboardLight.setBrightness(keyboardValue); 2707 } 2708 } 2709 } 2710 } 2711 2712 /** 2713 * The user requested that we go to sleep (probably with the power button). 2714 * This overrides all wake locks that are held. 2715 */ 2716 public void goToSleep(long time) 2717 { 2718 goToSleepWithReason(time, WindowManagerPolicy.OFF_BECAUSE_OF_USER); 2719 } 2720 2721 /** 2722 * The user requested that we go to sleep (probably with the power button). 2723 * This overrides all wake locks that are held. 2724 */ 2725 public void goToSleepWithReason(long time, int reason) 2726 { 2727 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 2728 synchronized (mLocks) { 2729 goToSleepLocked(time, reason); 2730 } 2731 } 2732 2733 /** 2734 * Reboot the device immediately, passing 'reason' (may be null) 2735 * to the underlying __reboot system call. Should not return. 2736 */ 2737 public void reboot(String reason) 2738 { 2739 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null); 2740 2741 if (mHandler == null || !ActivityManagerNative.isSystemReady()) { 2742 throw new IllegalStateException("Too early to call reboot()"); 2743 } 2744 2745 final String finalReason = reason; 2746 Runnable runnable = new Runnable() { 2747 public void run() { 2748 synchronized (this) { 2749 ShutdownThread.reboot(mContext, finalReason, false); 2750 } 2751 2752 } 2753 }; 2754 // ShutdownThread must run on a looper capable of displaying the UI. 2755 mHandler.post(runnable); 2756 2757 // PowerManager.reboot() is documented not to return so just wait for the inevitable. 2758 synchronized (runnable) { 2759 while (true) { 2760 try { 2761 runnable.wait(); 2762 } catch (InterruptedException e) { 2763 } 2764 } 2765 } 2766 } 2767 2768 /** 2769 * Crash the runtime (causing a complete restart of the Android framework). 2770 * Requires REBOOT permission. Mostly for testing. Should not return. 2771 */ 2772 public void crash(final String message) 2773 { 2774 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null); 2775 Thread t = new Thread("PowerManagerService.crash()") { 2776 public void run() { throw new RuntimeException(message); } 2777 }; 2778 try { 2779 t.start(); 2780 t.join(); 2781 } catch (InterruptedException e) { 2782 Log.wtf(TAG, e); 2783 } 2784 } 2785 2786 private void goToSleepLocked(long time, int reason) { 2787 if (DEBUG) { 2788 Exception ex = new Exception(); 2789 ex.fillInStackTrace(); 2790 Slog.d(TAG, "goToSleep mLastEventTime=" + mLastEventTime + " time=" + time 2791 + " reason=" + reason, ex); 2792 } 2793 2794 if (mLastEventTime <= time) { 2795 mLastEventTime = time; 2796 // cancel all of the wake locks 2797 mWakeLockState = SCREEN_OFF; 2798 int N = mLocks.size(); 2799 int numCleared = 0; 2800 boolean proxLock = false; 2801 for (int i=0; i<N; i++) { 2802 WakeLock wl = mLocks.get(i); 2803 if (isScreenLock(wl.flags)) { 2804 if (((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) 2805 && reason == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) { 2806 proxLock = true; 2807 } else { 2808 mLocks.get(i).activated = false; 2809 numCleared++; 2810 } 2811 } 2812 } 2813 if (!proxLock) { 2814 mProxIgnoredBecauseScreenTurnedOff = true; 2815 if (DEBUG_PROXIMITY_SENSOR) { 2816 Slog.d(TAG, "setting mProxIgnoredBecauseScreenTurnedOff"); 2817 } 2818 } 2819 EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numCleared); 2820 mStillNeedSleepNotification = true; 2821 mUserState = SCREEN_OFF; 2822 setPowerState(SCREEN_OFF, false, reason); 2823 cancelTimerLocked(); 2824 } 2825 } 2826 2827 public long timeSinceScreenOn() { 2828 synchronized (mLocks) { 2829 if ((mPowerState & SCREEN_ON_BIT) != 0) { 2830 return 0; 2831 } 2832 return SystemClock.elapsedRealtime() - mScreenOffTime; 2833 } 2834 } 2835 2836 public void setKeyboardVisibility(boolean visible) { 2837 synchronized (mLocks) { 2838 if (DEBUG) { 2839 Slog.d(TAG, "setKeyboardVisibility: " + visible); 2840 } 2841 if (mKeyboardVisible != visible) { 2842 mKeyboardVisible = visible; 2843 // don't signal user activity if the screen is off; other code 2844 // will take care of turning on due to a true change to the lid 2845 // switch and synchronized with the lock screen. 2846 if ((mPowerState & SCREEN_ON_BIT) != 0) { 2847 if (mUseSoftwareAutoBrightness) { 2848 // force recompute of backlight values 2849 if (mLightSensorValue >= 0) { 2850 int value = (int)mLightSensorValue; 2851 mLightSensorValue = -1; 2852 lightSensorChangedLocked(value, false); 2853 } 2854 } 2855 userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true); 2856 } 2857 } 2858 } 2859 } 2860 2861 /** 2862 * When the keyguard is up, it manages the power state, and userActivity doesn't do anything. 2863 * When disabling user activity we also reset user power state so the keyguard can reset its 2864 * short screen timeout when keyguard is unhidden. 2865 */ 2866 public void enableUserActivity(boolean enabled) { 2867 if (DEBUG) { 2868 Slog.d(TAG, "enableUserActivity " + enabled); 2869 } 2870 synchronized (mLocks) { 2871 mUserActivityAllowed = enabled; 2872 if (!enabled) { 2873 // cancel timeout and clear mUserState so the keyguard can set a short timeout 2874 setTimeoutLocked(SystemClock.uptimeMillis(), 0); 2875 } 2876 } 2877 } 2878 2879 private void setScreenBrightnessMode(int mode) { 2880 synchronized (mLocks) { 2881 boolean enabled = (mode == SCREEN_BRIGHTNESS_MODE_AUTOMATIC); 2882 if (mUseSoftwareAutoBrightness && mAutoBrightessEnabled != enabled) { 2883 mAutoBrightessEnabled = enabled; 2884 // This will get us a new value 2885 enableLightSensorLocked(mAutoBrightessEnabled && isScreenOn()); 2886 } 2887 } 2888 } 2889 2890 /** Sets the screen off timeouts: 2891 * mKeylightDelay 2892 * mDimDelay 2893 * mScreenOffDelay 2894 * */ 2895 private void setScreenOffTimeoutsLocked() { 2896 if ((mPokey & POKE_LOCK_SHORT_TIMEOUT) != 0) { 2897 mKeylightDelay = mShortKeylightDelay; // Configurable via secure settings 2898 mDimDelay = -1; 2899 mScreenOffDelay = 0; 2900 } else if ((mPokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0) { 2901 mKeylightDelay = MEDIUM_KEYLIGHT_DELAY; 2902 mDimDelay = -1; 2903 mScreenOffDelay = 0; 2904 } else { 2905 int totalDelay = mScreenOffTimeoutSetting; 2906 if (totalDelay > mMaximumScreenOffTimeout) { 2907 totalDelay = mMaximumScreenOffTimeout; 2908 } 2909 mKeylightDelay = LONG_KEYLIGHT_DELAY; 2910 if (totalDelay < 0) { 2911 // negative number means stay on as long as possible. 2912 mScreenOffDelay = mMaximumScreenOffTimeout; 2913 } else if (mKeylightDelay < totalDelay) { 2914 // subtract the time that the keylight delay. This will give us the 2915 // remainder of the time that we need to sleep to get the accurate 2916 // screen off timeout. 2917 mScreenOffDelay = totalDelay - mKeylightDelay; 2918 } else { 2919 mScreenOffDelay = 0; 2920 } 2921 if (mDimScreen && totalDelay >= (LONG_KEYLIGHT_DELAY + LONG_DIM_TIME)) { 2922 mDimDelay = mScreenOffDelay - LONG_DIM_TIME; 2923 mScreenOffDelay = LONG_DIM_TIME; 2924 } else { 2925 mDimDelay = -1; 2926 } 2927 } 2928 if (DEBUG) { 2929 Slog.d(TAG, "setScreenOffTimeouts mKeylightDelay=" + mKeylightDelay 2930 + " mDimDelay=" + mDimDelay + " mScreenOffDelay=" + mScreenOffDelay 2931 + " mDimScreen=" + mDimScreen); 2932 } 2933 } 2934 2935 /** 2936 * Refreshes cached secure settings. Called once on startup, and 2937 * on subsequent changes to secure settings. 2938 */ 2939 private void updateSettingsValues() { 2940 mShortKeylightDelay = Settings.Secure.getInt( 2941 mContext.getContentResolver(), 2942 Settings.Secure.SHORT_KEYLIGHT_DELAY_MS, 2943 SHORT_KEYLIGHT_DELAY_DEFAULT); 2944 // Slog.i(TAG, "updateSettingsValues(): mShortKeylightDelay now " + mShortKeylightDelay); 2945 } 2946 2947 private class LockList extends ArrayList<WakeLock> 2948 { 2949 void addLock(WakeLock wl) 2950 { 2951 int index = getIndex(wl.binder); 2952 if (index < 0) { 2953 this.add(wl); 2954 } 2955 } 2956 2957 WakeLock removeLock(IBinder binder) 2958 { 2959 int index = getIndex(binder); 2960 if (index >= 0) { 2961 return this.remove(index); 2962 } else { 2963 return null; 2964 } 2965 } 2966 2967 int getIndex(IBinder binder) 2968 { 2969 int N = this.size(); 2970 for (int i=0; i<N; i++) { 2971 if (this.get(i).binder == binder) { 2972 return i; 2973 } 2974 } 2975 return -1; 2976 } 2977 2978 int gatherState() 2979 { 2980 int result = 0; 2981 int N = this.size(); 2982 for (int i=0; i<N; i++) { 2983 WakeLock wl = this.get(i); 2984 if (wl.activated) { 2985 if (isScreenLock(wl.flags)) { 2986 result |= wl.minState; 2987 } 2988 } 2989 } 2990 return result; 2991 } 2992 2993 int reactivateScreenLocksLocked() 2994 { 2995 int result = 0; 2996 int N = this.size(); 2997 for (int i=0; i<N; i++) { 2998 WakeLock wl = this.get(i); 2999 if (isScreenLock(wl.flags)) { 3000 wl.activated = true; 3001 result |= wl.minState; 3002 } 3003 } 3004 if (DEBUG_PROXIMITY_SENSOR) { 3005 Slog.d(TAG, "reactivateScreenLocksLocked mProxIgnoredBecauseScreenTurnedOff=" 3006 + mProxIgnoredBecauseScreenTurnedOff); 3007 } 3008 mProxIgnoredBecauseScreenTurnedOff = false; 3009 return result; 3010 } 3011 } 3012 3013 public void setPolicy(WindowManagerPolicy p) { 3014 synchronized (mLocks) { 3015 mPolicy = p; 3016 mLocks.notifyAll(); 3017 } 3018 } 3019 3020 WindowManagerPolicy getPolicyLocked() { 3021 while (mPolicy == null || !mDoneBooting) { 3022 try { 3023 mLocks.wait(); 3024 } catch (InterruptedException e) { 3025 // Ignore 3026 } 3027 } 3028 return mPolicy; 3029 } 3030 3031 public void systemReady() { 3032 mSensorManager = new SystemSensorManager(mHandlerThread.getLooper()); 3033 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); 3034 // don't bother with the light sensor if auto brightness is handled in hardware 3035 if (mUseSoftwareAutoBrightness) { 3036 mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); 3037 } 3038 3039 // wait until sensors are enabled before turning on screen. 3040 // some devices will not activate the light sensor properly on boot 3041 // unless we do this. 3042 if (mUseSoftwareAutoBrightness) { 3043 // turn the screen on 3044 setPowerState(SCREEN_BRIGHT); 3045 } else { 3046 // turn everything on 3047 setPowerState(ALL_BRIGHT); 3048 } 3049 3050 synchronized (mLocks) { 3051 Slog.d(TAG, "system ready!"); 3052 mDoneBooting = true; 3053 3054 enableLightSensorLocked(mUseSoftwareAutoBrightness && mAutoBrightessEnabled); 3055 3056 long identity = Binder.clearCallingIdentity(); 3057 try { 3058 mBatteryStats.noteScreenBrightness(getPreferredBrightness()); 3059 mBatteryStats.noteScreenOn(); 3060 } catch (RemoteException e) { 3061 // Nothing interesting to do. 3062 } finally { 3063 Binder.restoreCallingIdentity(identity); 3064 } 3065 } 3066 } 3067 3068 void bootCompleted() { 3069 Slog.d(TAG, "bootCompleted"); 3070 synchronized (mLocks) { 3071 mBootCompleted = true; 3072 userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true); 3073 updateWakeLockLocked(); 3074 mLocks.notifyAll(); 3075 } 3076 } 3077 3078 // for watchdog 3079 public void monitor() { 3080 synchronized (mLocks) { } 3081 } 3082 3083 public int getSupportedWakeLockFlags() { 3084 int result = PowerManager.PARTIAL_WAKE_LOCK 3085 | PowerManager.FULL_WAKE_LOCK 3086 | PowerManager.SCREEN_DIM_WAKE_LOCK; 3087 3088 if (mProximitySensor != null) { 3089 result |= PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK; 3090 } 3091 3092 return result; 3093 } 3094 3095 public void setBacklightBrightness(int brightness) { 3096 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 3097 // Don't let applications turn the screen all the way off 3098 synchronized (mLocks) { 3099 brightness = Math.max(brightness, mScreenBrightnessDim); 3100 mLcdLight.setBrightness(brightness); 3101 mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0); 3102 mButtonLight.setBrightness(brightness); 3103 long identity = Binder.clearCallingIdentity(); 3104 try { 3105 mBatteryStats.noteScreenBrightness(brightness); 3106 } catch (RemoteException e) { 3107 Slog.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e); 3108 } finally { 3109 Binder.restoreCallingIdentity(identity); 3110 } 3111 mScreenBrightnessAnimator.animateTo(brightness, SCREEN_BRIGHT_BIT, 0); 3112 } 3113 } 3114 3115 public void setAutoBrightnessAdjustment(float adj) { 3116 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 3117 synchronized (mLocks) { 3118 mLightSensorAdjustSetting = adj; 3119 if (mSensorManager != null && mLightSensorEnabled) { 3120 // clear calling identity so sensor manager battery stats are accurate 3121 long identity = Binder.clearCallingIdentity(); 3122 try { 3123 // force recompute of backlight values 3124 if (mLightSensorValue >= 0) { 3125 int value = (int)mLightSensorValue; 3126 mLightSensorValue = -1; 3127 handleLightSensorValue(value, true); 3128 } 3129 } finally { 3130 Binder.restoreCallingIdentity(identity); 3131 } 3132 } 3133 } 3134 } 3135 3136 public void setAttentionLight(boolean on, int color) { 3137 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 3138 mAttentionLight.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0); 3139 } 3140 3141 private void enableProximityLockLocked() { 3142 if (DEBUG_PROXIMITY_SENSOR) { 3143 Slog.d(TAG, "enableProximityLockLocked"); 3144 } 3145 if (!mProximitySensorEnabled) { 3146 // clear calling identity so sensor manager battery stats are accurate 3147 long identity = Binder.clearCallingIdentity(); 3148 try { 3149 mSensorManager.registerListener(mProximityListener, mProximitySensor, 3150 SensorManager.SENSOR_DELAY_NORMAL); 3151 mProximitySensorEnabled = true; 3152 } finally { 3153 Binder.restoreCallingIdentity(identity); 3154 } 3155 } 3156 } 3157 3158 private void disableProximityLockLocked() { 3159 if (DEBUG_PROXIMITY_SENSOR) { 3160 Slog.d(TAG, "disableProximityLockLocked"); 3161 } 3162 if (mProximitySensorEnabled) { 3163 // clear calling identity so sensor manager battery stats are accurate 3164 long identity = Binder.clearCallingIdentity(); 3165 try { 3166 mSensorManager.unregisterListener(mProximityListener); 3167 mHandler.removeCallbacks(mProximityTask); 3168 if (mProximityPartialLock.isHeld()) { 3169 mProximityPartialLock.release(); 3170 } 3171 mProximitySensorEnabled = false; 3172 } finally { 3173 Binder.restoreCallingIdentity(identity); 3174 } 3175 if (mProximitySensorActive) { 3176 mProximitySensorActive = false; 3177 if (DEBUG_PROXIMITY_SENSOR) { 3178 Slog.d(TAG, "disableProximityLockLocked mProxIgnoredBecauseScreenTurnedOff=" 3179 + mProxIgnoredBecauseScreenTurnedOff); 3180 } 3181 if (!mProxIgnoredBecauseScreenTurnedOff) { 3182 forceUserActivityLocked(); 3183 } 3184 } 3185 } 3186 } 3187 3188 private void proximityChangedLocked(boolean active) { 3189 if (DEBUG_PROXIMITY_SENSOR) { 3190 Slog.d(TAG, "proximityChangedLocked, active: " + active); 3191 } 3192 if (!mProximitySensorEnabled) { 3193 Slog.d(TAG, "Ignoring proximity change after sensor is disabled"); 3194 return; 3195 } 3196 if (active) { 3197 if (DEBUG_PROXIMITY_SENSOR) { 3198 Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff=" 3199 + mProxIgnoredBecauseScreenTurnedOff); 3200 } 3201 if (!mProxIgnoredBecauseScreenTurnedOff) { 3202 goToSleepLocked(SystemClock.uptimeMillis(), 3203 WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR); 3204 } 3205 mProximitySensorActive = true; 3206 } else { 3207 // proximity sensor negative events trigger as user activity. 3208 // temporarily set mUserActivityAllowed to true so this will work 3209 // even when the keyguard is on. 3210 mProximitySensorActive = false; 3211 if (DEBUG_PROXIMITY_SENSOR) { 3212 Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff=" 3213 + mProxIgnoredBecauseScreenTurnedOff); 3214 } 3215 if (!mProxIgnoredBecauseScreenTurnedOff) { 3216 forceUserActivityLocked(); 3217 } 3218 3219 if (mProximityWakeLockCount == 0) { 3220 // disable sensor if we have no listeners left after proximity negative 3221 disableProximityLockLocked(); 3222 } 3223 } 3224 } 3225 3226 private void enableLightSensorLocked(boolean enable) { 3227 if (DEBUG_LIGHT_SENSOR) { 3228 Slog.d(TAG, "enableLightSensorLocked enable=" + enable 3229 + " mLightSensorEnabled=" + mLightSensorEnabled 3230 + " mAutoBrightessEnabled=" + mAutoBrightessEnabled 3231 + " mWaitingForFirstLightSensor=" + mWaitingForFirstLightSensor); 3232 } 3233 if (!mAutoBrightessEnabled) { 3234 enable = false; 3235 } 3236 if (mSensorManager != null && mLightSensorEnabled != enable) { 3237 mLightSensorEnabled = enable; 3238 // clear calling identity so sensor manager battery stats are accurate 3239 long identity = Binder.clearCallingIdentity(); 3240 try { 3241 if (enable) { 3242 // reset our highest value when reenabling 3243 mHighestLightSensorValue = -1; 3244 // force recompute of backlight values 3245 final int value = (int)mLightSensorValue; 3246 if (value >= 0) { 3247 mLightSensorValue = -1; 3248 handleLightSensorValue(value, true); 3249 } 3250 mSensorManager.registerListener(mLightListener, mLightSensor, 3251 LIGHT_SENSOR_RATE); 3252 } else { 3253 mSensorManager.unregisterListener(mLightListener); 3254 mHandler.removeCallbacks(mAutoBrightnessTask); 3255 mLightSensorPendingDecrease = false; 3256 mLightSensorPendingIncrease = false; 3257 } 3258 } finally { 3259 Binder.restoreCallingIdentity(identity); 3260 } 3261 } 3262 } 3263 3264 SensorEventListener mProximityListener = new SensorEventListener() { 3265 public void onSensorChanged(SensorEvent event) { 3266 long milliseconds = SystemClock.elapsedRealtime(); 3267 synchronized (mLocks) { 3268 float distance = event.values[0]; 3269 long timeSinceLastEvent = milliseconds - mLastProximityEventTime; 3270 mLastProximityEventTime = milliseconds; 3271 mHandler.removeCallbacks(mProximityTask); 3272 boolean proximityTaskQueued = false; 3273 3274 // compare against getMaximumRange to support sensors that only return 0 or 1 3275 boolean active = (distance >= 0.0 && distance < PROXIMITY_THRESHOLD && 3276 distance < mProximitySensor.getMaximumRange()); 3277 3278 if (DEBUG_PROXIMITY_SENSOR) { 3279 Slog.d(TAG, "mProximityListener.onSensorChanged active: " + active); 3280 } 3281 if (timeSinceLastEvent < PROXIMITY_SENSOR_DELAY) { 3282 // enforce delaying atleast PROXIMITY_SENSOR_DELAY before processing 3283 mProximityPendingValue = (active ? 1 : 0); 3284 mHandler.postDelayed(mProximityTask, PROXIMITY_SENSOR_DELAY - timeSinceLastEvent); 3285 proximityTaskQueued = true; 3286 } else { 3287 // process the value immediately 3288 mProximityPendingValue = -1; 3289 proximityChangedLocked(active); 3290 } 3291 3292 // update mProximityPartialLock state 3293 boolean held = mProximityPartialLock.isHeld(); 3294 if (!held && proximityTaskQueued) { 3295 // hold wakelock until mProximityTask runs 3296 mProximityPartialLock.acquire(); 3297 } else if (held && !proximityTaskQueued) { 3298 mProximityPartialLock.release(); 3299 } 3300 } 3301 } 3302 3303 public void onAccuracyChanged(Sensor sensor, int accuracy) { 3304 // ignore 3305 } 3306 }; 3307 3308 private void handleLightSensorValue(int value, boolean immediate) { 3309 long milliseconds = SystemClock.elapsedRealtime(); 3310 if (mLightSensorValue == -1 3311 || milliseconds < mLastScreenOnTime + mLightSensorWarmupTime 3312 || mWaitingForFirstLightSensor) { 3313 // process the value immediately if screen has just turned on 3314 mHandler.removeCallbacks(mAutoBrightnessTask); 3315 mLightSensorPendingDecrease = false; 3316 mLightSensorPendingIncrease = false; 3317 lightSensorChangedLocked(value, immediate); 3318 } else { 3319 if ((value > mLightSensorValue && mLightSensorPendingDecrease) || 3320 (value < mLightSensorValue && mLightSensorPendingIncrease) || 3321 (value == mLightSensorValue) || 3322 (!mLightSensorPendingDecrease && !mLightSensorPendingIncrease)) { 3323 // delay processing to debounce the sensor 3324 mHandler.removeCallbacks(mAutoBrightnessTask); 3325 mLightSensorPendingDecrease = (value < mLightSensorValue); 3326 mLightSensorPendingIncrease = (value > mLightSensorValue); 3327 if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) { 3328 mLightSensorPendingValue = value; 3329 mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY); 3330 } 3331 } else { 3332 mLightSensorPendingValue = value; 3333 } 3334 } 3335 } 3336 3337 SensorEventListener mLightListener = new SensorEventListener() { 3338 @Override 3339 public void onSensorChanged(SensorEvent event) { 3340 if (DEBUG_LIGHT_SENSOR) { 3341 Slog.d(TAG, "onSensorChanged: light value: " + event.values[0]); 3342 } 3343 synchronized (mLocks) { 3344 // ignore light sensor while screen is turning off 3345 if (isScreenTurningOffLocked()) { 3346 return; 3347 } 3348 handleLightSensorValue((int)event.values[0], mWaitingForFirstLightSensor); 3349 if (mWaitingForFirstLightSensor && !mPreparingForScreenOn) { 3350 if (DEBUG_LIGHT_ANIMATION) { 3351 Slog.d(TAG, "onSensorChanged: Clearing mWaitingForFirstLightSensor."); 3352 } 3353 mWaitingForFirstLightSensor = false; 3354 } 3355 } 3356 } 3357 3358 @Override 3359 public void onAccuracyChanged(Sensor sensor, int accuracy) { 3360 // ignore 3361 } 3362 }; 3363} 3364