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