diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:45 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:45 -0800 |
commit | d83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /services/java/com/android/server/PowerManagerService.java | |
parent | 076357b8567458d4b6dfdcf839ef751634cd2bfb (diff) | |
download | frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.zip frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.tar.gz frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'services/java/com/android/server/PowerManagerService.java')
-rw-r--r-- | services/java/com/android/server/PowerManagerService.java | 1864 |
1 files changed, 0 insertions, 1864 deletions
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java deleted file mode 100644 index f41d21f..0000000 --- a/services/java/com/android/server/PowerManagerService.java +++ /dev/null @@ -1,1864 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server; - -import com.android.internal.app.IBatteryStats; -import com.android.server.am.BatteryStatsService; - -import android.app.ActivityManagerNative; -import android.app.IActivityManager; -import android.content.BroadcastReceiver; -import android.content.ContentQueryMap; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.database.Cursor; -import android.os.BatteryStats; -import android.os.Binder; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.IBinder; -import android.os.IPowerManager; -import android.os.LocalPowerManager; -import android.os.Power; -import android.os.PowerManager; -import android.os.Process; -import android.os.RemoteException; -import android.os.SystemClock; -import android.provider.Settings.SettingNotFoundException; -import android.provider.Settings; -import android.util.EventLog; -import android.util.Log; -import android.view.WindowManagerPolicy; -import static android.provider.Settings.System.DIM_SCREEN; -import static android.provider.Settings.System.SCREEN_BRIGHTNESS; -import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; -import static android.provider.Settings.System.STAY_ON_WHILE_PLUGGED_IN; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Observable; -import java.util.Observer; - -class PowerManagerService extends IPowerManager.Stub implements LocalPowerManager, Watchdog.Monitor { - - private static final String TAG = "PowerManagerService"; - static final String PARTIAL_NAME = "PowerManagerService"; - - private static final boolean LOG_PARTIAL_WL = false; - - // Indicates whether touch-down cycles should be logged as part of the - // LOG_POWER_SCREEN_STATE log events - private static final boolean LOG_TOUCH_DOWNS = true; - - private static final int LOCK_MASK = PowerManager.PARTIAL_WAKE_LOCK - | PowerManager.SCREEN_DIM_WAKE_LOCK - | PowerManager.SCREEN_BRIGHT_WAKE_LOCK - | PowerManager.FULL_WAKE_LOCK; - - // time since last state: time since last event: - // The short keylight delay comes from Gservices; this is the default. - private static final int SHORT_KEYLIGHT_DELAY_DEFAULT = 6000; // t+6 sec - private static final int MEDIUM_KEYLIGHT_DELAY = 15000; // t+15 sec - private static final int LONG_KEYLIGHT_DELAY = 6000; // t+6 sec - private static final int LONG_DIM_TIME = 7000; // t+N-5 sec - - // Cached Gservices settings; see updateGservicesValues() - private int mShortKeylightDelay = SHORT_KEYLIGHT_DELAY_DEFAULT; - - // flags for setPowerState - private static final int SCREEN_ON_BIT = 0x00000001; - private static final int SCREEN_BRIGHT_BIT = 0x00000002; - private static final int BUTTON_BRIGHT_BIT = 0x00000004; - private static final int KEYBOARD_BRIGHT_BIT = 0x00000008; - private static final int BATTERY_LOW_BIT = 0x00000010; - - // values for setPowerState - - // SCREEN_OFF == everything off - private static final int SCREEN_OFF = 0x00000000; - - // SCREEN_DIM == screen on, screen backlight dim - private static final int SCREEN_DIM = SCREEN_ON_BIT; - - // SCREEN_BRIGHT == screen on, screen backlight bright - private static final int SCREEN_BRIGHT = SCREEN_ON_BIT | SCREEN_BRIGHT_BIT; - - // SCREEN_BUTTON_BRIGHT == screen on, screen and button backlights bright - private static final int SCREEN_BUTTON_BRIGHT = SCREEN_BRIGHT | BUTTON_BRIGHT_BIT; - - // SCREEN_BUTTON_BRIGHT == screen on, screen, button and keyboard backlights bright - private static final int ALL_BRIGHT = SCREEN_BUTTON_BRIGHT | KEYBOARD_BRIGHT_BIT; - - // used for noChangeLights in setPowerState() - private static final int LIGHTS_MASK = SCREEN_BRIGHT_BIT | BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT; - - static final boolean ANIMATE_SCREEN_LIGHTS = true; - static final boolean ANIMATE_BUTTON_LIGHTS = false; - static final boolean ANIMATE_KEYBOARD_LIGHTS = false; - - static final int ANIM_STEPS = 60/4; - - // These magic numbers are the initial state of the LEDs at boot. Ideally - // we should read them from the driver, but our current hardware returns 0 - // for the initial value. Oops! - static final int INITIAL_SCREEN_BRIGHTNESS = 255; - static final int INITIAL_BUTTON_BRIGHTNESS = Power.BRIGHTNESS_OFF; - static final int INITIAL_KEYBOARD_BRIGHTNESS = Power.BRIGHTNESS_OFF; - - static final int LOG_POWER_SLEEP_REQUESTED = 2724; - static final int LOG_POWER_SCREEN_BROADCAST_SEND = 2725; - static final int LOG_POWER_SCREEN_BROADCAST_DONE = 2726; - static final int LOG_POWER_SCREEN_BROADCAST_STOP = 2727; - static final int LOG_POWER_SCREEN_STATE = 2728; - static final int LOG_POWER_PARTIAL_WAKE_STATE = 2729; - - private final int MY_UID; - - private boolean mDoneBooting = false; - private int mStayOnConditions = 0; - private int mNotificationQueue = -1; - private int mNotificationWhy; - private int mPartialCount = 0; - private int mPowerState; - private boolean mOffBecauseOfUser; - private int mUserState; - private boolean mKeyboardVisible = false; - private boolean mUserActivityAllowed = true; - private int mTotalDelaySetting; - private int mKeylightDelay; - private int mDimDelay; - private int mScreenOffDelay; - private int mWakeLockState; - private long mLastEventTime = 0; - private long mScreenOffTime; - private volatile WindowManagerPolicy mPolicy; - private final LockList mLocks = new LockList(); - private Intent mScreenOffIntent; - private Intent mScreenOnIntent; - private Context mContext; - private UnsynchronizedWakeLock mBroadcastWakeLock; - private UnsynchronizedWakeLock mStayOnWhilePluggedInScreenDimLock; - private UnsynchronizedWakeLock mStayOnWhilePluggedInPartialLock; - private UnsynchronizedWakeLock mPreventScreenOnPartialLock; - private HandlerThread mHandlerThread; - private Handler mHandler; - private TimeoutTask mTimeoutTask = new TimeoutTask(); - private LightAnimator mLightAnimator = new LightAnimator(); - private final BrightnessState mScreenBrightness - = new BrightnessState(Power.SCREEN_LIGHT); - private final BrightnessState mKeyboardBrightness - = new BrightnessState(Power.KEYBOARD_LIGHT); - private final BrightnessState mButtonBrightness - = new BrightnessState(Power.BUTTON_LIGHT); - private boolean mIsPowered = false; - private IActivityManager mActivityService; - private IBatteryStats mBatteryStats; - private BatteryService mBatteryService; - private boolean mDimScreen = true; - private long mNextTimeout; - private volatile int mPokey = 0; - private volatile boolean mPokeAwakeOnSet = false; - private volatile boolean mInitComplete = false; - private HashMap<IBinder,PokeLock> mPokeLocks = new HashMap<IBinder,PokeLock>(); - private long mScreenOnTime; - private long mScreenOnStartTime; - private boolean mPreventScreenOn; - private int mScreenBrightnessOverride = -1; - - // Used when logging number and duration of touch-down cycles - private long mTotalTouchDownTime; - private long mLastTouchDown; - private int mTouchCycles; - - // could be either static or controllable at runtime - private static final boolean mSpew = false; - - /* - static PrintStream mLog; - static { - try { - mLog = new PrintStream("/data/power.log"); - } - catch (FileNotFoundException e) { - android.util.Log.e(TAG, "Life is hard", e); - } - } - static class Log { - static void d(String tag, String s) { - mLog.println(s); - android.util.Log.d(tag, s); - } - static void i(String tag, String s) { - mLog.println(s); - android.util.Log.i(tag, s); - } - static void w(String tag, String s) { - mLog.println(s); - android.util.Log.w(tag, s); - } - static void e(String tag, String s) { - mLog.println(s); - android.util.Log.e(tag, s); - } - } - */ - - /** - * This class works around a deadlock between the lock in PowerManager.WakeLock - * and our synchronizing on mLocks. PowerManager.WakeLock synchronizes on its - * mToken object so it can be accessed from any thread, but it calls into here - * with its lock held. This class is essentially a reimplementation of - * PowerManager.WakeLock, but without that extra synchronized block, because we'll - * only call it with our own locks held. - */ - private class UnsynchronizedWakeLock { - int mFlags; - String mTag; - IBinder mToken; - int mCount = 0; - boolean mRefCounted; - - UnsynchronizedWakeLock(int flags, String tag, boolean refCounted) { - mFlags = flags; - mTag = tag; - mToken = new Binder(); - mRefCounted = refCounted; - } - - public void acquire() { - if (!mRefCounted || mCount++ == 0) { - long ident = Binder.clearCallingIdentity(); - try { - PowerManagerService.this.acquireWakeLockLocked(mFlags, mToken, - MY_UID, mTag); - } finally { - Binder.restoreCallingIdentity(ident); - } - } - } - - public void release() { - if (!mRefCounted || --mCount == 0) { - PowerManagerService.this.releaseWakeLockLocked(mToken, false); - } - if (mCount < 0) { - throw new RuntimeException("WakeLock under-locked " + mTag); - } - } - - public String toString() { - return "UnsynchronizedWakeLock(mFlags=0x" + Integer.toHexString(mFlags) - + " mCount=" + mCount + ")"; - } - } - - private final class BatteryReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - synchronized (mLocks) { - boolean wasPowered = mIsPowered; - mIsPowered = mBatteryService.isPowered(); - - if (mIsPowered != wasPowered) { - // update mStayOnWhilePluggedIn wake lock - updateWakeLockLocked(); - - // treat plugging and unplugging the devices as a user activity. - // users find it disconcerting when they unplug the device - // and it shuts off right away. - // temporarily set mUserActivityAllowed to true so this will work - // even when the keyguard is on. - synchronized (mLocks) { - boolean savedActivityAllowed = mUserActivityAllowed; - mUserActivityAllowed = true; - userActivity(SystemClock.uptimeMillis(), false); - mUserActivityAllowed = savedActivityAllowed; - } - } - } - } - } - - /** - * Set the setting that determines whether the device stays on when plugged in. - * The argument is a bit string, with each bit specifying a power source that, - * when the device is connected to that source, causes the device to stay on. - * See {@link android.os.BatteryManager} for the list of power sources that - * can be specified. Current values include {@link android.os.BatteryManager#BATTERY_PLUGGED_AC} - * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB} - * @param val an {@code int} containing the bits that specify which power sources - * should cause the device to stay on. - */ - public void setStayOnSetting(int val) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS, null); - Settings.System.putInt(mContext.getContentResolver(), - Settings.System.STAY_ON_WHILE_PLUGGED_IN, val); - } - - private class SettingsObserver implements Observer { - private int getInt(String name) { - return mSettings.getValues(name).getAsInteger(Settings.System.VALUE); - } - - public void update(Observable o, Object arg) { - synchronized (mLocks) { - // STAY_ON_WHILE_PLUGGED_IN - mStayOnConditions = getInt(STAY_ON_WHILE_PLUGGED_IN); - updateWakeLockLocked(); - - // SCREEN_OFF_TIMEOUT - mTotalDelaySetting = getInt(SCREEN_OFF_TIMEOUT); - - // DIM_SCREEN - //mDimScreen = getInt(DIM_SCREEN) != 0; - - // recalculate everything - setScreenOffTimeoutsLocked(); - } - } - } - - PowerManagerService() - { - // Hack to get our uid... should have a func for this. - long token = Binder.clearCallingIdentity(); - MY_UID = Binder.getCallingUid(); - Binder.restoreCallingIdentity(token); - - // XXX remove this when the kernel doesn't timeout wake locks - Power.setLastUserActivityTimeout(7*24*3600*1000); // one week - - // assume nothing is on yet - mUserState = mPowerState = 0; - - // Add ourself to the Watchdog monitors. - Watchdog.getInstance().addMonitor(this); - mScreenOnStartTime = SystemClock.elapsedRealtime(); - } - - private ContentQueryMap mSettings; - - void init(Context context, IActivityManager activity, BatteryService battery) { - mContext = context; - mActivityService = activity; - mBatteryStats = BatteryStatsService.getService(); - mBatteryService = battery; - - mHandlerThread = new HandlerThread("PowerManagerService") { - @Override - protected void onLooperPrepared() { - super.onLooperPrepared(); - initInThread(); - } - }; - mHandlerThread.start(); - - synchronized (mHandlerThread) { - while (!mInitComplete) { - try { - mHandlerThread.wait(); - } catch (InterruptedException e) { - // Ignore - } - } - } - } - - void initInThread() { - mHandler = new Handler(); - - mBroadcastWakeLock = new UnsynchronizedWakeLock( - PowerManager.PARTIAL_WAKE_LOCK, "sleep_notification", true); - mStayOnWhilePluggedInScreenDimLock = new UnsynchronizedWakeLock( - PowerManager.SCREEN_DIM_WAKE_LOCK, "StayOnWhilePluggedIn Screen Dim", false); - mStayOnWhilePluggedInPartialLock = new UnsynchronizedWakeLock( - PowerManager.PARTIAL_WAKE_LOCK, "StayOnWhilePluggedIn Partial", false); - mPreventScreenOnPartialLock = new UnsynchronizedWakeLock( - PowerManager.PARTIAL_WAKE_LOCK, "PreventScreenOn Partial", false); - - mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON); - mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); - mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF); - mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); - - ContentResolver resolver = mContext.getContentResolver(); - Cursor settingsCursor = resolver.query(Settings.System.CONTENT_URI, null, - "(" + Settings.System.NAME + "=?) or (" - + Settings.System.NAME + "=?) or (" - + Settings.System.NAME + "=?)", - new String[]{STAY_ON_WHILE_PLUGGED_IN, SCREEN_OFF_TIMEOUT, DIM_SCREEN}, - null); - mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mHandler); - SettingsObserver settingsObserver = new SettingsObserver(); - mSettings.addObserver(settingsObserver); - - // pretend that the settings changed so we will get their initial state - settingsObserver.update(mSettings, null); - - // register for the battery changed notifications - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_BATTERY_CHANGED); - mContext.registerReceiver(new BatteryReceiver(), filter); - - // Listen for Gservices changes - IntentFilter gservicesChangedFilter = - new IntentFilter(Settings.Gservices.CHANGED_ACTION); - mContext.registerReceiver(new GservicesChangedReceiver(), gservicesChangedFilter); - // And explicitly do the initial update of our cached settings - updateGservicesValues(); - - // turn everything on - setPowerState(ALL_BRIGHT); - - synchronized (mHandlerThread) { - mInitComplete = true; - mHandlerThread.notifyAll(); - } - } - - private class WakeLock implements IBinder.DeathRecipient - { - WakeLock(int f, IBinder b, String t, int u) { - super(); - flags = f; - binder = b; - tag = t; - uid = u == MY_UID ? Process.SYSTEM_UID : u; - if (u != MY_UID || ( - !"KEEP_SCREEN_ON_FLAG".equals(tag) - && !"KeyInputQueue".equals(tag))) { - monitorType = (f & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK - ? BatteryStats.WAKE_TYPE_PARTIAL - : BatteryStats.WAKE_TYPE_FULL; - } else { - monitorType = -1; - } - try { - b.linkToDeath(this, 0); - } catch (RemoteException e) { - binderDied(); - } - } - public void binderDied() { - synchronized (mLocks) { - releaseWakeLockLocked(this.binder, true); - } - } - final int flags; - final IBinder binder; - final String tag; - final int uid; - final int monitorType; - boolean activated = true; - int minState; - } - - private void updateWakeLockLocked() { - if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) { - // keep the device on if we're plugged in and mStayOnWhilePluggedIn is set. - mStayOnWhilePluggedInScreenDimLock.acquire(); - mStayOnWhilePluggedInPartialLock.acquire(); - } else { - mStayOnWhilePluggedInScreenDimLock.release(); - mStayOnWhilePluggedInPartialLock.release(); - } - } - - private boolean isScreenLock(int flags) - { - int n = flags & LOCK_MASK; - return n == PowerManager.FULL_WAKE_LOCK - || n == PowerManager.SCREEN_BRIGHT_WAKE_LOCK - || n == PowerManager.SCREEN_DIM_WAKE_LOCK; - } - - public void acquireWakeLock(int flags, IBinder lock, String tag) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null); - int uid = Binder.getCallingUid(); - long ident = Binder.clearCallingIdentity(); - try { - synchronized (mLocks) { - acquireWakeLockLocked(flags, lock, uid, tag); - } - } finally { - Binder.restoreCallingIdentity(ident); - } - } - - public void acquireWakeLockLocked(int flags, IBinder lock, int uid, String tag) { - int acquireUid = -1; - String acquireName = null; - int acquireType = -1; - - if (mSpew) { - Log.d(TAG, "acquireWakeLock flags=0x" + Integer.toHexString(flags) + " tag=" + tag); - } - - int index = mLocks.getIndex(lock); - WakeLock wl; - boolean newlock; - if (index < 0) { - wl = new WakeLock(flags, lock, tag, uid); - switch (wl.flags & LOCK_MASK) - { - case PowerManager.FULL_WAKE_LOCK: - wl.minState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT); - break; - case PowerManager.SCREEN_BRIGHT_WAKE_LOCK: - wl.minState = SCREEN_BRIGHT; - break; - case PowerManager.SCREEN_DIM_WAKE_LOCK: - wl.minState = SCREEN_DIM; - break; - case PowerManager.PARTIAL_WAKE_LOCK: - break; - default: - // just log and bail. we're in the server, so don't - // throw an exception. - Log.e(TAG, "bad wakelock type for lock '" + tag + "' " - + " flags=" + flags); - return; - } - mLocks.addLock(wl); - newlock = true; - } else { - wl = mLocks.get(index); - newlock = false; - } - if (isScreenLock(flags)) { - // if this causes a wakeup, we reactivate all of the locks and - // set it to whatever they want. otherwise, we modulate that - // by the current state so we never turn it more on than - // it already is. - if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) { - reactivateWakeLocksLocked(); - if (mSpew) { - Log.d(TAG, "wakeup here mUserState=0x" + Integer.toHexString(mUserState) - + " mLocks.gatherState()=0x" - + Integer.toHexString(mLocks.gatherState()) - + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState)); - } - mWakeLockState = mLocks.gatherState(); - } else { - if (mSpew) { - Log.d(TAG, "here mUserState=0x" + Integer.toHexString(mUserState) - + " mLocks.gatherState()=0x" - + Integer.toHexString(mLocks.gatherState()) - + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState)); - } - mWakeLockState = (mUserState | mWakeLockState) & mLocks.gatherState(); - } - setPowerState(mWakeLockState | mUserState); - } - else if ((flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) { - if (newlock) { - mPartialCount++; - if (mPartialCount == 1) { - if (LOG_PARTIAL_WL) EventLog.writeEvent(LOG_POWER_PARTIAL_WAKE_STATE, 1, tag); - } - } - Power.acquireWakeLock(Power.PARTIAL_WAKE_LOCK,PARTIAL_NAME); - } - if (newlock) { - acquireUid = wl.uid; - acquireName = wl.tag; - acquireType = wl.monitorType; - } - - if (acquireType >= 0) { - try { - mBatteryStats.noteStartWakelock(acquireUid, acquireName, acquireType); - } catch (RemoteException e) { - // Ignore - } - } - } - - public void releaseWakeLock(IBinder lock) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null); - - synchronized (mLocks) { - releaseWakeLockLocked(lock, false); - } - } - - private void releaseWakeLockLocked(IBinder lock, boolean death) { - int releaseUid; - String releaseName; - int releaseType; - - WakeLock wl = mLocks.removeLock(lock); - if (wl == null) { - return; - } - - if (mSpew) { - Log.d(TAG, "releaseWakeLock flags=0x" - + Integer.toHexString(wl.flags) + " tag=" + wl.tag); - } - - if (isScreenLock(wl.flags)) { - mWakeLockState = mLocks.gatherState(); - // goes in the middle to reduce flicker - if ((wl.flags & PowerManager.ON_AFTER_RELEASE) != 0) { - userActivity(SystemClock.uptimeMillis(), false); - } - setPowerState(mWakeLockState | mUserState); - } - else if ((wl.flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) { - mPartialCount--; - if (mPartialCount == 0) { - if (LOG_PARTIAL_WL) EventLog.writeEvent(LOG_POWER_PARTIAL_WAKE_STATE, 0, wl.tag); - Power.releaseWakeLock(PARTIAL_NAME); - } - } - // Unlink the lock from the binder. - wl.binder.unlinkToDeath(wl, 0); - releaseUid = wl.uid; - releaseName = wl.tag; - releaseType = wl.monitorType; - - if (releaseType >= 0) { - long origId = Binder.clearCallingIdentity(); - try { - mBatteryStats.noteStopWakelock(releaseUid, releaseName, releaseType); - } catch (RemoteException e) { - // Ignore - } finally { - Binder.restoreCallingIdentity(origId); - } - } - } - - private void reactivateWakeLocksLocked() - { - int N = mLocks.size(); - for (int i=0; i<N; i++) { - WakeLock wl = mLocks.get(i); - if (isScreenLock(wl.flags)) { - mLocks.get(i).activated = true; - } - } - } - - private class PokeLock implements IBinder.DeathRecipient - { - PokeLock(int p, IBinder b, String t) { - super(); - this.pokey = p; - this.binder = b; - this.tag = t; - try { - b.linkToDeath(this, 0); - } catch (RemoteException e) { - binderDied(); - } - } - public void binderDied() { - setPokeLock(0, this.binder, this.tag); - } - int pokey; - IBinder binder; - String tag; - boolean awakeOnSet; - } - - public void setPokeLock(int pokey, IBinder token, String tag) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); - if (token == null) { - Log.e(TAG, "setPokeLock got null token for tag='" + tag + "'"); - return; - } - - if ((pokey & POKE_LOCK_TIMEOUT_MASK) == POKE_LOCK_TIMEOUT_MASK) { - throw new IllegalArgumentException("setPokeLock can't have both POKE_LOCK_SHORT_TIMEOUT" - + " and POKE_LOCK_MEDIUM_TIMEOUT"); - } - - synchronized (mLocks) { - if (pokey != 0) { - PokeLock p = mPokeLocks.get(token); - int oldPokey = 0; - if (p != null) { - oldPokey = p.pokey; - p.pokey = pokey; - } else { - p = new PokeLock(pokey, token, tag); - mPokeLocks.put(token, p); - } - int oldTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK; - int newTimeout = pokey & POKE_LOCK_TIMEOUT_MASK; - if (((mPowerState & SCREEN_ON_BIT) == 0) && (oldTimeout != newTimeout)) { - p.awakeOnSet = true; - } - } else { - mPokeLocks.remove(token); - } - - int oldPokey = mPokey; - int cumulative = 0; - boolean oldAwakeOnSet = mPokeAwakeOnSet; - boolean awakeOnSet = false; - for (PokeLock p: mPokeLocks.values()) { - cumulative |= p.pokey; - if (p.awakeOnSet) { - awakeOnSet = true; - } - } - mPokey = cumulative; - mPokeAwakeOnSet = awakeOnSet; - - int oldCumulativeTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK; - int newCumulativeTimeout = pokey & POKE_LOCK_TIMEOUT_MASK; - - if (oldCumulativeTimeout != newCumulativeTimeout) { - setScreenOffTimeoutsLocked(); - // reset the countdown timer, but use the existing nextState so it doesn't - // change anything - setTimeoutLocked(SystemClock.uptimeMillis(), mTimeoutTask.nextState); - } - } - } - - private static String lockType(int type) - { - switch (type) - { - case PowerManager.FULL_WAKE_LOCK: - return "FULL_WAKE_LOCK "; - case PowerManager.SCREEN_BRIGHT_WAKE_LOCK: - return "SCREEN_BRIGHT_WAKE_LOCK"; - case PowerManager.SCREEN_DIM_WAKE_LOCK: - return "SCREEN_DIM_WAKE_LOCK "; - case PowerManager.PARTIAL_WAKE_LOCK: - return "PARTIAL_WAKE_LOCK "; - default: - return "??? "; - } - } - - private static String dumpPowerState(int state) { - return (((state & KEYBOARD_BRIGHT_BIT) != 0) - ? "KEYBOARD_BRIGHT_BIT " : "") - + (((state & SCREEN_BRIGHT_BIT) != 0) - ? "SCREEN_BRIGHT_BIT " : "") - + (((state & SCREEN_ON_BIT) != 0) - ? "SCREEN_ON_BIT " : "") - + (((state & BATTERY_LOW_BIT) != 0) - ? "BATTERY_LOW_BIT " : ""); - } - - @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) - != PackageManager.PERMISSION_GRANTED) { - pw.println("Permission Denial: can't dump PowerManager from from pid=" - + Binder.getCallingPid() - + ", uid=" + Binder.getCallingUid()); - return; - } - - long now = SystemClock.uptimeMillis(); - - pw.println("Power Manager State:"); - pw.println(" mIsPowered=" + mIsPowered - + " mPowerState=" + mPowerState - + " mScreenOffTime=" + (SystemClock.elapsedRealtime()-mScreenOffTime) - + " ms"); - pw.println(" mPartialCount=" + mPartialCount); - pw.println(" mWakeLockState=" + dumpPowerState(mWakeLockState)); - pw.println(" mUserState=" + dumpPowerState(mUserState)); - pw.println(" mPowerState=" + dumpPowerState(mPowerState)); - pw.println(" mLocks.gather=" + dumpPowerState(mLocks.gatherState())); - pw.println(" mNextTimeout=" + mNextTimeout + " now=" + now - + " " + ((mNextTimeout-now)/1000) + "s from now"); - pw.println(" mDimScreen=" + mDimScreen - + " mStayOnConditions=" + mStayOnConditions); - pw.println(" mOffBecauseOfUser=" + mOffBecauseOfUser - + " mUserState=" + mUserState); - pw.println(" mNotificationQueue=" + mNotificationQueue - + " mNotificationWhy=" + mNotificationWhy); - pw.println(" mPokey=" + mPokey + " mPokeAwakeonSet=" + mPokeAwakeOnSet); - pw.println(" mKeyboardVisible=" + mKeyboardVisible - + " mUserActivityAllowed=" + mUserActivityAllowed); - pw.println(" mKeylightDelay=" + mKeylightDelay + " mDimDelay=" + mDimDelay - + " mScreenOffDelay=" + mScreenOffDelay); - pw.println(" mPreventScreenOn=" + mPreventScreenOn - + " mScreenBrightnessOverride=" + mScreenBrightnessOverride); - pw.println(" mTotalDelaySetting=" + mTotalDelaySetting); - pw.println(" mBroadcastWakeLock=" + mBroadcastWakeLock); - pw.println(" mStayOnWhilePluggedInScreenDimLock=" + mStayOnWhilePluggedInScreenDimLock); - pw.println(" mStayOnWhilePluggedInPartialLock=" + mStayOnWhilePluggedInPartialLock); - pw.println(" mPreventScreenOnPartialLock=" + mPreventScreenOnPartialLock); - mScreenBrightness.dump(pw, " mScreenBrightness: "); - mKeyboardBrightness.dump(pw, " mKeyboardBrightness: "); - mButtonBrightness.dump(pw, " mButtonBrightness: "); - - int N = mLocks.size(); - pw.println(); - pw.println("mLocks.size=" + N + ":"); - for (int i=0; i<N; i++) { - WakeLock wl = mLocks.get(i); - String type = lockType(wl.flags & LOCK_MASK); - String acquireCausesWakeup = ""; - if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) { - acquireCausesWakeup = "ACQUIRE_CAUSES_WAKEUP "; - } - String activated = ""; - if (wl.activated) { - activated = " activated"; - } - pw.println(" " + type + " '" + wl.tag + "'" + acquireCausesWakeup - + activated + " (minState=" + wl.minState + ")"); - } - - pw.println(); - pw.println("mPokeLocks.size=" + mPokeLocks.size() + ":"); - for (PokeLock p: mPokeLocks.values()) { - pw.println(" poke lock '" + p.tag + "':" - + ((p.pokey & POKE_LOCK_IGNORE_CHEEK_EVENTS) != 0 - ? " POKE_LOCK_IGNORE_CHEEK_EVENTS" : "") - + ((p.pokey & POKE_LOCK_SHORT_TIMEOUT) != 0 - ? " POKE_LOCK_SHORT_TIMEOUT" : "") - + ((p.pokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0 - ? " POKE_LOCK_MEDIUM_TIMEOUT" : "")); - } - - pw.println(); - } - - private void setTimeoutLocked(long now, int nextState) - { - if (mDoneBooting) { - mHandler.removeCallbacks(mTimeoutTask); - mTimeoutTask.nextState = nextState; - long when = now; - switch (nextState) - { - case SCREEN_BRIGHT: - when += mKeylightDelay; - break; - case SCREEN_DIM: - if (mDimDelay >= 0) { - when += mDimDelay; - break; - } else { - Log.w(TAG, "mDimDelay=" + mDimDelay + " while trying to dim"); - } - case SCREEN_OFF: - synchronized (mLocks) { - when += mScreenOffDelay; - } - break; - } - if (mSpew) { - Log.d(TAG, "setTimeoutLocked now=" + now + " nextState=" + nextState - + " when=" + when); - } - mHandler.postAtTime(mTimeoutTask, when); - mNextTimeout = when; // for debugging - } - } - - private void cancelTimerLocked() - { - mHandler.removeCallbacks(mTimeoutTask); - mTimeoutTask.nextState = -1; - } - - private class TimeoutTask implements Runnable - { - int nextState; // access should be synchronized on mLocks - public void run() - { - synchronized (mLocks) { - if (mSpew) { - Log.d(TAG, "user activity timeout timed out nextState=" + this.nextState); - } - - if (nextState == -1) { - return; - } - - mUserState = this.nextState; - setPowerState(this.nextState | mWakeLockState); - - long now = SystemClock.uptimeMillis(); - - switch (this.nextState) - { - case SCREEN_BRIGHT: - if (mDimDelay >= 0) { - setTimeoutLocked(now, SCREEN_DIM); - break; - } - case SCREEN_DIM: - setTimeoutLocked(now, SCREEN_OFF); - break; - } - } - } - } - - private void sendNotificationLocked(boolean on, int why) - { - - if (!on) { - mNotificationWhy = why; - } - - int value = on ? 1 : 0; - if (mNotificationQueue == -1) { - // empty - // Acquire the broadcast wake lock before changing the power - // state. It will be release after the broadcast is sent. - mBroadcastWakeLock.acquire(); - EventLog.writeEvent(LOG_POWER_SCREEN_BROADCAST_SEND, mBroadcastWakeLock.mCount); - mNotificationQueue = value; - mHandler.post(mNotificationTask); - } else if (mNotificationQueue != value) { - // it's a pair, so cancel it - mNotificationQueue = -1; - mHandler.removeCallbacks(mNotificationTask); - EventLog.writeEvent(LOG_POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount); - mBroadcastWakeLock.release(); - } else { - // else, same so do nothing -- maybe we should warn? - Log.w(TAG, "Duplicate notification: on=" + on + " why=" + why); - } - } - - private Runnable mNotificationTask = new Runnable() - { - public void run() - { - int value; - int why; - WindowManagerPolicy policy; - synchronized (mLocks) { - policy = getPolicyLocked(); - value = mNotificationQueue; - why = mNotificationWhy; - mNotificationQueue = -1; - } - if (value == 1) { - mScreenOnStart = SystemClock.uptimeMillis(); - - policy.screenTurnedOn(); - try { - ActivityManagerNative.getDefault().wakingUp(); - } catch (RemoteException e) { - // ignore it - } - - if (mSpew) { - Log.d(TAG, "mBroadcastWakeLock=" + mBroadcastWakeLock); - } - if (mContext != null) { - if (ActivityManagerNative.isSystemReady()) { - mContext.sendOrderedBroadcast(mScreenOnIntent, null, - mScreenOnBroadcastDone, mHandler, 0, null, null); - } - } else { - synchronized (mLocks) { - EventLog.writeEvent(LOG_POWER_SCREEN_BROADCAST_STOP, 2, - mBroadcastWakeLock.mCount); - mBroadcastWakeLock.release(); - } - } - } - else if (value == 0) { - mScreenOffStart = SystemClock.uptimeMillis(); - - policy.screenTurnedOff(why); - try { - ActivityManagerNative.getDefault().goingToSleep(); - } catch (RemoteException e) { - // ignore it. - } - - if (mContext != null) { - mContext.sendOrderedBroadcast(mScreenOffIntent, null, - mScreenOffBroadcastDone, mHandler, 0, null, null); - } else { - synchronized (mLocks) { - EventLog.writeEvent(LOG_POWER_SCREEN_BROADCAST_STOP, 3, - mBroadcastWakeLock.mCount); - mBroadcastWakeLock.release(); - } - } - } - else { - // If we're in this case, then this handler is running for a previous - // paired transaction. mBroadcastWakeLock will already have been released - // in sendNotificationLocked. - } - } - }; - - long mScreenOnStart; - private BroadcastReceiver mScreenOnBroadcastDone = new BroadcastReceiver() { - public void onReceive(Context context, Intent intent) { - synchronized (mLocks) { - EventLog.writeEvent(LOG_POWER_SCREEN_BROADCAST_DONE, 1, - SystemClock.uptimeMillis() - mScreenOnStart, mBroadcastWakeLock.mCount); - mBroadcastWakeLock.release(); - } - } - }; - - long mScreenOffStart; - private BroadcastReceiver mScreenOffBroadcastDone = new BroadcastReceiver() { - public void onReceive(Context context, Intent intent) { - synchronized (mLocks) { - EventLog.writeEvent(LOG_POWER_SCREEN_BROADCAST_DONE, 0, - SystemClock.uptimeMillis() - mScreenOffStart, mBroadcastWakeLock.mCount); - mBroadcastWakeLock.release(); - } - } - }; - - void logPointerUpEvent() { - if (LOG_TOUCH_DOWNS) { - mTotalTouchDownTime += SystemClock.elapsedRealtime() - mLastTouchDown; - mLastTouchDown = 0; - } - } - - void logPointerDownEvent() { - if (LOG_TOUCH_DOWNS) { - // If we are not already timing a down/up sequence - if (mLastTouchDown == 0) { - mLastTouchDown = SystemClock.elapsedRealtime(); - mTouchCycles++; - } - } - } - - /** - * Prevents the screen from turning on even if it *should* turn on due - * to a subsequent full wake lock being acquired. - * <p> - * This is a temporary hack that allows an activity to "cover up" any - * display glitches that happen during the activity's startup - * sequence. (Specifically, this API was added to work around a - * cosmetic bug in the "incoming call" sequence, where the lock screen - * would flicker briefly before the incoming call UI became visible.) - * TODO: There ought to be a more elegant way of doing this, - * probably by having the PowerManager and ActivityManager - * work together to let apps specify that the screen on/off - * state should be synchronized with the Activity lifecycle. - * <p> - * Note that calling preventScreenOn(true) will NOT turn the screen - * off if it's currently on. (This API only affects *future* - * acquisitions of full wake locks.) - * But calling preventScreenOn(false) WILL turn the screen on if - * it's currently off because of a prior preventScreenOn(true) call. - * <p> - * Any call to preventScreenOn(true) MUST be followed promptly by a call - * to preventScreenOn(false). In fact, if the preventScreenOn(false) - * call doesn't occur within 5 seconds, we'll turn the screen back on - * ourselves (and log a warning about it); this prevents a buggy app - * from disabling the screen forever.) - * <p> - * TODO: this feature should really be controlled by a new type of poke - * lock (rather than an IPowerManager call). - */ - public void preventScreenOn(boolean prevent) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); - - synchronized (mLocks) { - if (prevent) { - // First of all, grab a partial wake lock to - // make sure the CPU stays on during the entire - // preventScreenOn(true) -> preventScreenOn(false) sequence. - mPreventScreenOnPartialLock.acquire(); - - // Post a forceReenableScreen() call (for 5 seconds in the - // future) to make sure the matching preventScreenOn(false) call - // has happened by then. - mHandler.removeCallbacks(mForceReenableScreenTask); - mHandler.postDelayed(mForceReenableScreenTask, 5000); - - // Finally, set the flag that prevents the screen from turning on. - // (Below, in setPowerState(), we'll check mPreventScreenOn and - // we *won't* call Power.setScreenState(true) if it's set.) - mPreventScreenOn = true; - } else { - // (Re)enable the screen. - mPreventScreenOn = false; - - // We're "undoing" a the prior preventScreenOn(true) call, so we - // no longer need the 5-second safeguard. - mHandler.removeCallbacks(mForceReenableScreenTask); - - // Forcibly turn on the screen if it's supposed to be on. (This - // handles the case where the screen is currently off because of - // a prior preventScreenOn(true) call.) - if ((mPowerState & SCREEN_ON_BIT) != 0) { - if (mSpew) { - Log.d(TAG, - "preventScreenOn: turning on after a prior preventScreenOn(true)!"); - } - int err = Power.setScreenState(true); - if (err != 0) { - Log.w(TAG, "preventScreenOn: error from Power.setScreenState(): " + err); - } - } - - // Release the partial wake lock that we held during the - // preventScreenOn(true) -> preventScreenOn(false) sequence. - mPreventScreenOnPartialLock.release(); - } - } - } - - public void setScreenBrightnessOverride(int brightness) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); - - synchronized (mLocks) { - if (mScreenBrightnessOverride != brightness) { - mScreenBrightnessOverride = brightness; - updateLightsLocked(mPowerState, SCREEN_ON_BIT); - } - } - } - - /** - * Sanity-check that gets called 5 seconds after any call to - * preventScreenOn(true). This ensures that the original call - * is followed promptly by a call to preventScreenOn(false). - */ - private void forceReenableScreen() { - // We shouldn't get here at all if mPreventScreenOn is false, since - // we should have already removed any existing - // mForceReenableScreenTask messages... - if (!mPreventScreenOn) { - Log.w(TAG, "forceReenableScreen: mPreventScreenOn is false, nothing to do"); - return; - } - - // Uh oh. It's been 5 seconds since a call to - // preventScreenOn(true) and we haven't re-enabled the screen yet. - // This means the app that called preventScreenOn(true) is either - // slow (i.e. it took more than 5 seconds to call preventScreenOn(false)), - // or buggy (i.e. it forgot to call preventScreenOn(false), or - // crashed before doing so.) - - // Log a warning, and forcibly turn the screen back on. - Log.w(TAG, "App called preventScreenOn(true) but didn't promptly reenable the screen! " - + "Forcing the screen back on..."); - preventScreenOn(false); - } - - private Runnable mForceReenableScreenTask = new Runnable() { - public void run() { - forceReenableScreen(); - } - }; - - private void setPowerState(int state) - { - setPowerState(state, false, false); - } - - private void setPowerState(int newState, boolean noChangeLights, boolean becauseOfUser) - { - synchronized (mLocks) { - int err; - - if (mSpew) { - Log.d(TAG, "setPowerState: mPowerState=0x" + Integer.toHexString(mPowerState) - + " newState=0x" + Integer.toHexString(newState) - + " noChangeLights=" + noChangeLights); - } - - if (noChangeLights) { - newState = (newState & ~LIGHTS_MASK) | (mPowerState & LIGHTS_MASK); - } - - if (batteryIsLow()) { - newState |= BATTERY_LOW_BIT; - } else { - newState &= ~BATTERY_LOW_BIT; - } - if (newState == mPowerState) { - return; - } - - if (!mDoneBooting) { - newState |= ALL_BRIGHT; - } - - boolean oldScreenOn = (mPowerState & SCREEN_ON_BIT) != 0; - boolean newScreenOn = (newState & SCREEN_ON_BIT) != 0; - - if (mSpew) { - Log.d(TAG, "setPowerState: mPowerState=" + mPowerState - + " newState=" + newState + " noChangeLights=" + noChangeLights); - Log.d(TAG, " oldKeyboardBright=" + ((mPowerState & KEYBOARD_BRIGHT_BIT) != 0) - + " newKeyboardBright=" + ((newState & KEYBOARD_BRIGHT_BIT) != 0)); - Log.d(TAG, " oldScreenBright=" + ((mPowerState & SCREEN_BRIGHT_BIT) != 0) - + " newScreenBright=" + ((newState & SCREEN_BRIGHT_BIT) != 0)); - Log.d(TAG, " oldButtonBright=" + ((mPowerState & BUTTON_BRIGHT_BIT) != 0) - + " newButtonBright=" + ((newState & BUTTON_BRIGHT_BIT) != 0)); - Log.d(TAG, " oldScreenOn=" + oldScreenOn - + " newScreenOn=" + newScreenOn); - Log.d(TAG, " oldBatteryLow=" + ((mPowerState & BATTERY_LOW_BIT) != 0) - + " newBatteryLow=" + ((newState & BATTERY_LOW_BIT) != 0)); - } - - if (mPowerState != newState) { - err = updateLightsLocked(newState, 0); - if (err != 0) { - return; - } - mPowerState = (mPowerState & ~LIGHTS_MASK) | (newState & LIGHTS_MASK); - } - - if (oldScreenOn != newScreenOn) { - if (newScreenOn) { - // Turn on the screen UNLESS there was a prior - // preventScreenOn(true) request. (Note that the lifetime - // of a single preventScreenOn() request is limited to 5 - // seconds to prevent a buggy app from disabling the - // screen forever; see forceReenableScreen().) - boolean reallyTurnScreenOn = true; - if (mSpew) { - Log.d(TAG, "- turning screen on... mPreventScreenOn = " - + mPreventScreenOn); - } - - if (mPreventScreenOn) { - if (mSpew) { - Log.d(TAG, "- PREVENTING screen from really turning on!"); - } - reallyTurnScreenOn = false; - } - if (reallyTurnScreenOn) { - err = Power.setScreenState(true); - long identity = Binder.clearCallingIdentity(); - try { - mBatteryStats.noteScreenOn(); - } catch (RemoteException e) { - Log.w(TAG, "RemoteException calling noteScreenOn on BatteryStatsService", e); - } finally { - Binder.restoreCallingIdentity(identity); - } - } else { - Power.setScreenState(false); - // But continue as if we really did turn the screen on... - err = 0; - } - - mScreenOnStartTime = SystemClock.elapsedRealtime(); - mLastTouchDown = 0; - mTotalTouchDownTime = 0; - mTouchCycles = 0; - EventLog.writeEvent(LOG_POWER_SCREEN_STATE, 1, becauseOfUser ? 1 : 0, - mTotalTouchDownTime, mTouchCycles); - if (err == 0) { - mPowerState |= SCREEN_ON_BIT; - sendNotificationLocked(true, -1); - } - } else { - mScreenOffTime = SystemClock.elapsedRealtime(); - long identity = Binder.clearCallingIdentity(); - try { - mBatteryStats.noteScreenOff(); - } catch (RemoteException e) { - Log.w(TAG, "RemoteException calling noteScreenOff on BatteryStatsService", e); - } finally { - Binder.restoreCallingIdentity(identity); - } - mPowerState &= ~SCREEN_ON_BIT; - if (!mScreenBrightness.animating) { - err = screenOffFinishedAnimating(becauseOfUser); - } else { - mOffBecauseOfUser = becauseOfUser; - err = 0; - mLastTouchDown = 0; - } - } - } - } - } - - private int screenOffFinishedAnimating(boolean becauseOfUser) { - // I don't think we need to check the current state here because all of these - // Power.setScreenState and sendNotificationLocked can both handle being - // called multiple times in the same state. -joeo - EventLog.writeEvent(LOG_POWER_SCREEN_STATE, 0, becauseOfUser ? 1 : 0, - mTotalTouchDownTime, mTouchCycles); - mLastTouchDown = 0; - int err = Power.setScreenState(false); - if (mScreenOnStartTime != 0) { - mScreenOnTime += SystemClock.elapsedRealtime() - mScreenOnStartTime; - mScreenOnStartTime = 0; - } - if (err == 0) { - int why = becauseOfUser - ? WindowManagerPolicy.OFF_BECAUSE_OF_USER - : WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT; - sendNotificationLocked(false, why); - } - return err; - } - - private boolean batteryIsLow() { - return (!mIsPowered && - mBatteryService.getBatteryLevel() <= Power.LOW_BATTERY_THRESHOLD); - } - - private int updateLightsLocked(int newState, int forceState) { - int oldState = mPowerState; - int difference = (newState ^ oldState) | forceState; - if (difference == 0) { - return 0; - } - - int offMask = 0; - int dimMask = 0; - int onMask = 0; - - int preferredBrightness = getPreferredBrightness(); - boolean startAnimation = false; - - if ((difference & KEYBOARD_BRIGHT_BIT) != 0) { - if (ANIMATE_KEYBOARD_LIGHTS) { - if ((newState & KEYBOARD_BRIGHT_BIT) == 0) { - mKeyboardBrightness.setTargetLocked(Power.BRIGHTNESS_OFF, - ANIM_STEPS, INITIAL_KEYBOARD_BRIGHTNESS); - } else { - mKeyboardBrightness.setTargetLocked(preferredBrightness, - ANIM_STEPS, INITIAL_KEYBOARD_BRIGHTNESS); - } - startAnimation = true; - } else { - if ((newState & KEYBOARD_BRIGHT_BIT) == 0) { - offMask |= Power.KEYBOARD_LIGHT; - } else { - onMask |= Power.KEYBOARD_LIGHT; - } - } - } - - if ((difference & BUTTON_BRIGHT_BIT) != 0) { - if (ANIMATE_BUTTON_LIGHTS) { - if ((newState & BUTTON_BRIGHT_BIT) == 0) { - mButtonBrightness.setTargetLocked(Power.BRIGHTNESS_OFF, - ANIM_STEPS, INITIAL_BUTTON_BRIGHTNESS); - } else { - mButtonBrightness.setTargetLocked(preferredBrightness, - ANIM_STEPS, INITIAL_BUTTON_BRIGHTNESS); - } - startAnimation = true; - } else { - if ((newState & BUTTON_BRIGHT_BIT) == 0) { - offMask |= Power.BUTTON_LIGHT; - } else { - onMask |= Power.BUTTON_LIGHT; - } - } - } - - if ((difference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) { - if (ANIMATE_SCREEN_LIGHTS) { - if ((newState & SCREEN_BRIGHT_BIT) == 0) { - // dim or turn off backlight, depending on if the screen is on - // the scale is because the brightness ramp isn't linear and this biases - // it so the later parts take longer. - final float scale = 1.5f; - float ratio = (((float)Power.BRIGHTNESS_DIM)/preferredBrightness); - if (ratio > 1.0f) ratio = 1.0f; - if ((newState & SCREEN_ON_BIT) == 0) { - int steps; - if ((oldState & SCREEN_BRIGHT_BIT) != 0) { - // was bright - steps = ANIM_STEPS; - } else { - // was dim - steps = (int)(ANIM_STEPS*ratio*scale); - } - mScreenBrightness.setTargetLocked(Power.BRIGHTNESS_OFF, - steps, INITIAL_SCREEN_BRIGHTNESS); - } else { - int steps; - if ((oldState & SCREEN_ON_BIT) != 0) { - // was bright - steps = (int)(ANIM_STEPS*(1.0f-ratio)*scale); - } else { - // was dim - steps = (int)(ANIM_STEPS*ratio); - } - if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) { - // If the "stay on while plugged in" option is - // turned on, then the screen will often not - // automatically turn off while plugged in. To - // still have a sense of when it is inactive, we - // will then count going dim as turning off. - mScreenOffTime = SystemClock.elapsedRealtime(); - } - mScreenBrightness.setTargetLocked(Power.BRIGHTNESS_DIM, - steps, INITIAL_SCREEN_BRIGHTNESS); - } - } else { - mScreenBrightness.setTargetLocked(preferredBrightness, - ANIM_STEPS, INITIAL_SCREEN_BRIGHTNESS); - } - startAnimation = true; - } else { - if ((newState & SCREEN_BRIGHT_BIT) == 0) { - // dim or turn off backlight, depending on if the screen is on - if ((newState & SCREEN_ON_BIT) == 0) { - offMask |= Power.SCREEN_LIGHT; - } else { - dimMask |= Power.SCREEN_LIGHT; - } - } else { - onMask |= Power.SCREEN_LIGHT; - } - } - } - - if (startAnimation) { - if (mSpew) { - Log.i(TAG, "Scheduling light animator!"); - } - mHandler.removeCallbacks(mLightAnimator); - mHandler.post(mLightAnimator); - } - - int err = 0; - if (offMask != 0) { - //Log.i(TAG, "Setting brightess off: " + offMask); - err |= Power.setLightBrightness(offMask, Power.BRIGHTNESS_OFF); - } - if (dimMask != 0) { - int brightness = Power.BRIGHTNESS_DIM; - if ((newState & BATTERY_LOW_BIT) != 0 && - brightness > Power.BRIGHTNESS_LOW_BATTERY) { - brightness = Power.BRIGHTNESS_LOW_BATTERY; - } - //Log.i(TAG, "Setting brightess dim " + brightness + ": " + offMask); - err |= Power.setLightBrightness(dimMask, brightness); - } - if (onMask != 0) { - int brightness = getPreferredBrightness(); - if ((newState & BATTERY_LOW_BIT) != 0 && - brightness > Power.BRIGHTNESS_LOW_BATTERY) { - brightness = Power.BRIGHTNESS_LOW_BATTERY; - } - //Log.i(TAG, "Setting brightess on " + brightness + ": " + onMask); - err |= Power.setLightBrightness(onMask, brightness); - } - - return err; - } - - class BrightnessState { - final int mask; - - boolean initialized; - int targetValue; - float curValue; - float delta; - boolean animating; - - BrightnessState(int m) { - mask = m; - } - - public void dump(PrintWriter pw, String prefix) { - pw.println(prefix + "animating=" + animating - + " targetValue=" + targetValue - + " curValue=" + curValue - + " delta=" + delta); - } - - void setTargetLocked(int target, int stepsToTarget, int initialValue) { - if (!initialized) { - initialized = true; - curValue = (float)initialValue; - } - targetValue = target; - delta = (targetValue-curValue) / stepsToTarget; - if (mSpew) { - Log.i(TAG, "Setting target " + mask + ": cur=" + curValue - + " target=" + targetValue + " delta=" + delta); - } - animating = true; - } - - boolean stepLocked() { - if (!animating) return false; - if (false && mSpew) { - Log.i(TAG, "Step target " + mask + ": cur=" + curValue - + " target=" + targetValue + " delta=" + delta); - } - curValue += delta; - int curIntValue = (int)curValue; - boolean more = true; - if (delta == 0) { - more = false; - } else if (delta > 0) { - if (curIntValue >= targetValue) { - curValue = curIntValue = targetValue; - more = false; - } - } else { - if (curIntValue <= targetValue) { - curValue = curIntValue = targetValue; - more = false; - } - } - //Log.i(TAG, "Animating brightess " + curIntValue + ": " + mask); - Power.setLightBrightness(mask, curIntValue); - animating = more; - if (!more) { - if (mask == Power.SCREEN_LIGHT && curIntValue == Power.BRIGHTNESS_OFF) { - screenOffFinishedAnimating(mOffBecauseOfUser); - } - } - return more; - } - } - - private class LightAnimator implements Runnable { - public void run() { - synchronized (mLocks) { - long now = SystemClock.uptimeMillis(); - boolean more = mScreenBrightness.stepLocked(); - if (mKeyboardBrightness.stepLocked()) { - more = true; - } - if (mButtonBrightness.stepLocked()) { - more = true; - } - if (more) { - mHandler.postAtTime(mLightAnimator, now+(1000/60)); - } - } - } - } - - private int getPreferredBrightness() { - try { - if (mScreenBrightnessOverride >= 0) { - return mScreenBrightnessOverride; - } - final int brightness = Settings.System.getInt(mContext.getContentResolver(), - SCREEN_BRIGHTNESS); - // Don't let applications turn the screen all the way off - return Math.max(brightness, Power.BRIGHTNESS_DIM); - } catch (SettingNotFoundException snfe) { - return Power.BRIGHTNESS_ON; - } - } - - boolean screenIsOn() { - synchronized (mLocks) { - return (mPowerState & SCREEN_ON_BIT) != 0; - } - } - - boolean screenIsBright() { - synchronized (mLocks) { - return (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT; - } - } - - public void userActivityWithForce(long time, boolean noChangeLights, boolean force) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); - userActivity(time, noChangeLights, OTHER_EVENT, force); - } - - public void userActivity(long time, boolean noChangeLights) { - userActivity(time, noChangeLights, OTHER_EVENT, false); - } - - public void userActivity(long time, boolean noChangeLights, int eventType) { - userActivity(time, noChangeLights, eventType, false); - } - - public void userActivity(long time, boolean noChangeLights, int eventType, boolean force) { - //mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); - - if (((mPokey & POKE_LOCK_IGNORE_CHEEK_EVENTS) != 0) - && !((eventType == OTHER_EVENT) || (eventType == BUTTON_EVENT))) { - if (false) { - Log.d(TAG, "dropping mPokey=0x" + Integer.toHexString(mPokey)); - } - return; - } - - if (false) { - if (((mPokey & POKE_LOCK_IGNORE_CHEEK_EVENTS) != 0)) { - Log.d(TAG, "userActivity !!!");//, new RuntimeException()); - } else { - Log.d(TAG, "mPokey=0x" + Integer.toHexString(mPokey)); - } - } - - synchronized (mLocks) { - if (mSpew) { - Log.d(TAG, "userActivity mLastEventTime=" + mLastEventTime + " time=" + time - + " mUserActivityAllowed=" + mUserActivityAllowed - + " mUserState=0x" + Integer.toHexString(mUserState) - + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState)); - } - if (mLastEventTime <= time || force) { - mLastEventTime = time; - if (mUserActivityAllowed || force) { - // Only turn on button backlights if a button was pressed. - if (eventType == BUTTON_EVENT) { - mUserState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT); - } else { - // don't clear button/keyboard backlights when the screen is touched. - mUserState |= SCREEN_BRIGHT; - } - - reactivateWakeLocksLocked(); - mWakeLockState = mLocks.gatherState(); - setPowerState(mUserState | mWakeLockState, noChangeLights, true); - setTimeoutLocked(time, SCREEN_BRIGHT); - } - } - } - } - - /** - * The user requested that we go to sleep (probably with the power button). - * This overrides all wake locks that are held. - */ - public void goToSleep(long time) - { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); - synchronized (mLocks) { - goToSleepLocked(time); - } - } - - /** - * Returns the time the screen has been on since boot, in millis. - * @return screen on time - */ - public long getScreenOnTime() { - synchronized (mLocks) { - if (mScreenOnStartTime == 0) { - return mScreenOnTime; - } else { - return SystemClock.elapsedRealtime() - mScreenOnStartTime + mScreenOnTime; - } - } - } - - private void goToSleepLocked(long time) { - - if (mLastEventTime <= time) { - mLastEventTime = time; - // cancel all of the wake locks - mWakeLockState = SCREEN_OFF; - int N = mLocks.size(); - int numCleared = 0; - for (int i=0; i<N; i++) { - WakeLock wl = mLocks.get(i); - if (isScreenLock(wl.flags)) { - mLocks.get(i).activated = false; - numCleared++; - } - } - EventLog.writeEvent(LOG_POWER_SLEEP_REQUESTED, numCleared); - mUserState = SCREEN_OFF; - setPowerState(SCREEN_OFF, false, true); - cancelTimerLocked(); - } - } - - public long timeSinceScreenOn() { - synchronized (mLocks) { - if ((mPowerState & SCREEN_ON_BIT) != 0) { - return 0; - } - return SystemClock.elapsedRealtime() - mScreenOffTime; - } - } - - public void setKeyboardVisibility(boolean visible) { - mKeyboardVisible = visible; - } - - /** - * When the keyguard is up, it manages the power state, and userActivity doesn't do anything. - */ - public void enableUserActivity(boolean enabled) { - synchronized (mLocks) { - mUserActivityAllowed = enabled; - mLastEventTime = SystemClock.uptimeMillis(); // we might need to pass this in - } - } - - /** Sets the screen off timeouts: - * mKeylightDelay - * mDimDelay - * mScreenOffDelay - * */ - private void setScreenOffTimeoutsLocked() { - if ((mPokey & POKE_LOCK_SHORT_TIMEOUT) != 0) { - mKeylightDelay = mShortKeylightDelay; // Configurable via Gservices - mDimDelay = -1; - mScreenOffDelay = 0; - } else if ((mPokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0) { - mKeylightDelay = MEDIUM_KEYLIGHT_DELAY; - mDimDelay = -1; - mScreenOffDelay = 0; - } else { - int totalDelay = mTotalDelaySetting; - mKeylightDelay = LONG_KEYLIGHT_DELAY; - if (totalDelay < 0) { - mScreenOffDelay = Integer.MAX_VALUE; - } else if (mKeylightDelay < totalDelay) { - // subtract the time that the keylight delay. This will give us the - // remainder of the time that we need to sleep to get the accurate - // screen off timeout. - mScreenOffDelay = totalDelay - mKeylightDelay; - } else { - mScreenOffDelay = 0; - } - if (mDimScreen && totalDelay >= (LONG_KEYLIGHT_DELAY + LONG_DIM_TIME)) { - mDimDelay = mScreenOffDelay - LONG_DIM_TIME; - mScreenOffDelay = LONG_DIM_TIME; - } else { - mDimDelay = -1; - } - } - if (mSpew) { - Log.d(TAG, "setScreenOffTimeouts mKeylightDelay=" + mKeylightDelay - + " mDimDelay=" + mDimDelay + " mScreenOffDelay=" + mScreenOffDelay - + " mDimScreen=" + mDimScreen); - } - } - - /** - * Refreshes cached Gservices settings. Called once on startup, and - * on subsequent Settings.Gservices.CHANGED_ACTION broadcasts (see - * GservicesChangedReceiver). - */ - private void updateGservicesValues() { - mShortKeylightDelay = Settings.Gservices.getInt( - mContext.getContentResolver(), - Settings.Gservices.SHORT_KEYLIGHT_DELAY_MS, - SHORT_KEYLIGHT_DELAY_DEFAULT); - // Log.i(TAG, "updateGservicesValues(): mShortKeylightDelay now " + mShortKeylightDelay); - } - - /** - * Receiver for the Gservices.CHANGED_ACTION broadcast intent, - * which tells us we need to refresh our cached Gservices settings. - */ - private class GservicesChangedReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - // Log.i(TAG, "GservicesChangedReceiver.onReceive(): " + intent); - updateGservicesValues(); - } - } - - private class LockList extends ArrayList<WakeLock> - { - void addLock(WakeLock wl) - { - int index = getIndex(wl.binder); - if (index < 0) { - this.add(wl); - } - } - - WakeLock removeLock(IBinder binder) - { - int index = getIndex(binder); - if (index >= 0) { - return this.remove(index); - } else { - return null; - } - } - - int getIndex(IBinder binder) - { - int N = this.size(); - for (int i=0; i<N; i++) { - if (this.get(i).binder == binder) { - return i; - } - } - return -1; - } - - int gatherState() - { - int result = 0; - int N = this.size(); - for (int i=0; i<N; i++) { - WakeLock wl = this.get(i); - if (wl.activated) { - if (isScreenLock(wl.flags)) { - result |= wl.minState; - } - } - } - return result; - } - } - - void setPolicy(WindowManagerPolicy p) { - synchronized (mLocks) { - mPolicy = p; - mLocks.notifyAll(); - } - } - - WindowManagerPolicy getPolicyLocked() { - while (mPolicy == null || !mDoneBooting) { - try { - mLocks.wait(); - } catch (InterruptedException e) { - // Ignore - } - } - return mPolicy; - } - - void systemReady() { - synchronized (mLocks) { - Log.d(TAG, "system ready!"); - mDoneBooting = true; - userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true); - updateWakeLockLocked(); - mLocks.notifyAll(); - } - } - - public void monitor() { - synchronized (mLocks) { } - } -} |