diff options
author | Jeff Brown <jeffbrown@google.com> | 2012-07-27 15:51:34 -0700 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2012-08-15 03:06:24 -0700 |
commit | 9630704ed3b265f008a8f64ec60a33cf9dcd3345 (patch) | |
tree | 0c905e55ac062b625bf7a9ced250f05213d7873f /core/java | |
parent | ff7e6ef4f18ff94a9836492ff3ccd1ba7f6804f3 (diff) | |
download | frameworks_base-9630704ed3b265f008a8f64ec60a33cf9dcd3345.zip frameworks_base-9630704ed3b265f008a8f64ec60a33cf9dcd3345.tar.gz frameworks_base-9630704ed3b265f008a8f64ec60a33cf9dcd3345.tar.bz2 |
Power manager rewrite.
The major goal of this rewrite is to make it easier to implement
power management policies correctly. According, the new
implementation primarily uses state-based rather than event-based
triggers for applying changes to the current power state.
For example, when an application requests that the proximity
sensor be used to manage the screen state (by way of a wake lock),
the power manager makes note of the fact that the set of
wake locks changed. Then it executes a common update function
that recalculates the entire state, first looking at wake locks,
then considering user activity, and eventually determining whether
the screen should be turned on or off. At this point it may
make a request to a component called the DisplayPowerController
to asynchronously update the display's powe state. Likewise,
DisplayPowerController makes note of the updated power request
and schedules its own update function to figure out what needs
to be changed.
The big benefit of this approach is that it's easy to mutate
multiple properties of the power state simultaneously then
apply their joint effects together all at once. Transitions
between states are detected and resolved by the update in
a consistent manner.
The new power manager service has is implemented as a set of
loosely coupled components. For the most part, information
only flows one way through these components (by issuing a
request to that component) although some components support
sending a message back to indicate when the work has been
completed. For example, the DisplayPowerController posts
a callback runnable asynchronously to tell the PowerManagerService
when the display is ready. An important feature of this
approach is that each component neatly encapsulates its
state and maintains its own invariants. Moreover, we do
not need to worry about deadlocks or awkward mutual exclusion
semantics because most of the requests are asynchronous.
The benefits of this design are especially apparent in
the implementation of the screen on / off and brightness
control animations which are able to take advantage of
framework features like properties, ObjectAnimator
and Choreographer.
The screen on / off animation is now the responsibility
of the power manager (instead of surface flinger). This change
makes it much easier to ensure that the animation is properly
coordinated with other power state changes and eliminates
the cause of race conditions in the older implementation.
The because of the userActivity() function has been changed
so that it never wakes the device from sleep. This change
removes ambiguity around forcing or disabling user activity
for various purposes. To wake the device, use wakeUp().
To put it to sleep, use goToSleep(). Simple.
The power manager service interface and API has been significantly
simplified and consolidated. Also fixed some inconsistencies
related to how the minimum and maximum screen brightness setting
was presented in brightness control widgets and enforced behind
the scenes.
At present the following features are implemented:
- Wake locks.
- User activity.
- Wake up / go to sleep.
- Power state broadcasts.
- Battery stats and event log notifications.
- Dreams.
- Proximity screen off.
- Animated screen on / off transitions.
- Auto-dimming.
- Auto-brightness control for the screen backlight with
different timeouts for ramping up versus ramping down.
- Auto-on when plugged or unplugged.
- Stay on when plugged.
- Device administration maximum user activity timeout.
- Application controlled brightness via window manager.
The following features are not yet implemented:
- Reduced user activity timeout for the key guard.
- Reduced user activity timeout for the phone application.
- Coordinating screen on barriers with the window manager.
- Preventing auto-rotation during power state changes.
- Auto-brightness adjustment setting (feature was disabled
in previous version of the power manager service pending
an improved UI design so leaving it out for now).
- Interpolated brightness control (a proposed new scheme
for more compactly specifying auto-brightness levels
in config.xml).
- Button / keyboard backlight control.
- Change window manager to associated WorkSource with
KEEP_SCREEN_ON_FLAG wake lock instead of talking
directly to the battery stats service.
- Optionally support animating screen brightness when
turning on/off instead of playing electron beam animation
(config_animateScreenLights).
Change-Id: I1d7a52e98f0449f76d70bf421f6a7f245957d1d7
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/app/ContextImpl.java | 3 | ||||
-rw-r--r-- | core/java/android/os/IPowerManager.aidl | 38 | ||||
-rw-r--r-- | core/java/android/os/LocalPowerManager.java | 18 | ||||
-rw-r--r-- | core/java/android/os/PowerManager.java | 159 | ||||
-rw-r--r-- | core/java/android/os/WorkSource.java | 18 | ||||
-rw-r--r-- | core/java/android/provider/Settings.java | 2 | ||||
-rw-r--r-- | core/java/android/service/dreams/DreamManagerService.java | 4 | ||||
-rw-r--r-- | core/java/android/util/TimeUtils.java | 13 | ||||
-rw-r--r-- | core/java/android/view/WindowManagerPolicy.java | 34 |
9 files changed, 186 insertions, 103 deletions
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 1ef14eb..fd4c304 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -418,7 +418,8 @@ class ContextImpl extends Context { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(POWER_SERVICE); IPowerManager service = IPowerManager.Stub.asInterface(b); - return new PowerManager(service, ctx.mMainThread.getHandler()); + return new PowerManager(ctx.getOuterContext(), + service, ctx.mMainThread.getHandler()); }}); registerService(SEARCH_SERVICE, new ServiceFetcher() { diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index 270e9be..7aee644 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -23,27 +23,33 @@ import android.os.WorkSource; interface IPowerManager { - // WARNING: changes in acquireWakeLock() signature must be reflected in IPowerManager.cpp/h - void acquireWakeLock(int flags, IBinder lock, String tag, in WorkSource ws); - void updateWakeLockWorkSource(IBinder lock, in WorkSource ws); - void goToSleep(long time); - void goToSleepWithReason(long time, int reason); - // WARNING: changes in releaseWakeLock() signature must be reflected in IPowerManager.cpp/h + // WARNING: The first two methods must remain the first two methods because their + // transaction numbers must not change unless IPowerManager.cpp is also updated. + void acquireWakeLock(IBinder lock, int flags, String tag, in WorkSource ws); void releaseWakeLock(IBinder lock, int flags); - void userActivity(long when, boolean noChangeLights); - void userActivityWithForce(long when, boolean noChangeLights, boolean force); + + void updateWakeLockWorkSource(IBinder lock, in WorkSource ws); + boolean isWakeLockLevelSupported(int level); + + void userActivity(long time, int event, int flags); + void wakeUp(long time); + void goToSleep(long time, int reason); + + boolean isScreenOn(); + void reboot(String reason); + void crash(String message); + void clearUserActivityTimeout(long now, long timeout); void setPokeLock(int pokey, IBinder lock, String tag); - int getSupportedWakeLockFlags(); void setStayOnSetting(int val); - void setMaximumScreenOffTimeount(int timeMs); + void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs); void preventScreenOn(boolean prevent); - boolean isScreenOn(); - void reboot(String reason); - void crash(String message); - // sets the brightness of the backlights (screen, keyboard, button) 0-255 - void setBacklightBrightness(int brightness); + // temporarily overrides the screen brightness settings to allow the user to + // see the effect of a settings change without applying it immediately + void setTemporaryScreenBrightnessSettingOverride(int brightness); + void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj); + + // sets the attention light (used by phone app only) void setAttentionLight(boolean on, int color); - void setAutoBrightnessAdjustment(float adj); } diff --git a/core/java/android/os/LocalPowerManager.java b/core/java/android/os/LocalPowerManager.java index 09336c7..519315c 100644 --- a/core/java/android/os/LocalPowerManager.java +++ b/core/java/android/os/LocalPowerManager.java @@ -18,25 +18,11 @@ package android.os; /** @hide */ public interface LocalPowerManager { + // FIXME: Replace poke locks with something else. + public static final int POKE_LOCK_IGNORE_TOUCH_EVENTS = 0x1; public static final int POKE_LOCK_SHORT_TIMEOUT = 0x2; public static final int POKE_LOCK_MEDIUM_TIMEOUT = 0x4; public static final int POKE_LOCK_TIMEOUT_MASK = 0x6; - - void goToSleep(long time); - - // notify power manager when keyboard is opened/closed - void setKeyboardVisibility(boolean visible); - - // when the keyguard is up, it manages the power state, and userActivity doesn't do anything. - void enableUserActivity(boolean enabled); - - // the same as the method on PowerManager - void userActivity(long time, boolean noChangeLights, int eventType); - - boolean isScreenOn(); - - void setScreenBrightnessOverride(int brightness); - void setButtonBrightnessOverride(int brightness); } diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index a757303..efdbcac 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -16,6 +16,7 @@ package android.os; +import android.content.Context; import android.util.Log; /** @@ -42,8 +43,8 @@ import android.util.Log; * wl.release(); * } * </p><p> - * The following flags are defined, with varying effects on system power. - * <i>These flags are mutually exclusive - you may only specify one of them.</i> + * The following wake lock levels are defined, with varying effects on system power. + * <i>These levels are mutually exclusive - you may only specify one of them.</i> * * <table border="2" width="85%" align="center" frame="hsides" rules="rows"> * <thead> @@ -177,7 +178,7 @@ public final class PowerManager { /** * Wake lock level: Turns the screen off when the proximity sensor activates. * <p> - * Since not all devices have proximity sensors, use {@link #getSupportedWakeLockFlags} + * Since not all devices have proximity sensors, use {@link #isWakeLockLevelSupported} * to determine whether this wake lock level is supported. * </p> * @@ -227,28 +228,23 @@ public final class PowerManager { public static final int WAIT_FOR_PROXIMITY_NEGATIVE = 1; /** - * Brightness value to use when battery is low. - * @hide - */ - public static final int BRIGHTNESS_LOW_BATTERY = 10; - - /** * Brightness value for fully on. * @hide */ public static final int BRIGHTNESS_ON = 255; /** - * Brightness value for dim backlight. + * Brightness value for fully off. * @hide */ - public static final int BRIGHTNESS_DIM = 20; + public static final int BRIGHTNESS_OFF = 0; /** - * Brightness value for fully off. + * A nominal default brightness value. + * Use {@link #getDefaultScreenBrightnessSetting()} instead. * @hide */ - public static final int BRIGHTNESS_OFF = 0; + private static final int BRIGHTNESS_DEFAULT = 102; // Note: Be sure to update android.os.BatteryStats and PowerManager.h // if adding or modifying user activity event constants. @@ -271,18 +267,82 @@ public final class PowerManager { */ public static final int USER_ACTIVITY_EVENT_TOUCH = 2; + /** + * User activity flag: Do not restart the user activity timeout or brighten + * the display in response to user activity if it is already dimmed. + * @hide + */ + public static final int USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS = 1 << 0; + + /** + * Special wake lock tag used for the wake lock in the Window Manager that handles the + * {@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON} flag. + * @hide + */ + public static final String KEEP_SCREEN_ON_FLAG_TAG = "KEEP_SCREEN_ON_FLAG"; + + /** + * Go to sleep reason code: Going to sleep due by user request. + * @hide + */ + public static final int GO_TO_SLEEP_REASON_USER = 0; + + /** + * Go to sleep reason code: Going to sleep due by request of the + * device administration policy. + * @hide + */ + public static final int GO_TO_SLEEP_REASON_DEVICE_ADMIN = 1; + + /** + * Go to sleep reason code: Going to sleep due to a screen timeout. + * @hide + */ + public static final int GO_TO_SLEEP_REASON_TIMEOUT = 2; + + final Context mContext; final IPowerManager mService; final Handler mHandler; /** * {@hide} */ - public PowerManager(IPowerManager service, Handler handler) { + public PowerManager(Context context, IPowerManager service, Handler handler) { + mContext = context; mService = service; mHandler = handler; } /** + * Gets the minimum supported screen brightness setting. + * The screen may be allowed to become dimmer than this value but + * this is the minimum value that can be set by the user. + * @hide + */ + public int getMinimumScreenBrightnessSetting() { + return mContext.getResources().getInteger( + com.android.internal.R.integer.config_screenBrightnessDim); + } + + /** + * Gets the maximum supported screen brightness setting. + * The screen may be allowed to become dimmer than this value but + * this is the maximum value that can be set by the user. + * @hide + */ + public int getMaximumScreenBrightnessSetting() { + return BRIGHTNESS_ON; + } + + /** + * Gets the default screen brightness setting. + * @hide + */ + public int getDefaultScreenBrightnessSetting() { + return BRIGHTNESS_DEFAULT; + } + + /** * Creates a new wake lock with the specified level and flags. * <p> * The {@code levelAndFlags} parameter specifies a wake lock level and optional flags @@ -360,8 +420,10 @@ public final class PowerManager { /** * Notifies the power manager that user activity happened. * <p> - * Turns the device from whatever state it's in to full on, and resets - * the auto-off timer. + * Resets the auto-off timer and brightens the screen if the device + * is not asleep. This is what happens normally when a key or the touch + * screen is pressed or when some other user activity occurs. + * This method does not wake up the device if it has been put to sleep. * </p><p> * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. * </p> @@ -375,10 +437,14 @@ public final class PowerManager { * We want the device to stay on while the button is down, but we're about * to turn off the screen so we don't want the keyboard backlight to turn on again. * Otherwise the lights flash on and then off and it looks weird. + * + * @see #wakeUp + * @see #goToSleep */ public void userActivity(long when, boolean noChangeLights) { try { - mService.userActivity(when, noChangeLights); + mService.userActivity(when, USER_ACTIVITY_EVENT_OTHER, + noChangeLights ? USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS : 0); } catch (RemoteException e) { } } @@ -386,8 +452,8 @@ public final class PowerManager { /** * Forces the device to go to sleep. * <p> - * Overrides all the wake locks that are held. This is what happen when the power - * key is pressed to turn off the screen. + * Overrides all the wake locks that are held. + * This is what happens when the power key is pressed to turn off the screen. * </p><p> * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. * </p> @@ -396,10 +462,37 @@ public final class PowerManager { * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly * order the user activity with other power management functions. It should be set * to the timestamp of the input event that caused the request to go to sleep. + * + * @see #userActivity + * @see #wakeUp */ public void goToSleep(long time) { try { - mService.goToSleep(time); + mService.goToSleep(time, GO_TO_SLEEP_REASON_USER); + } catch (RemoteException e) { + } + } + + /** + * Forces the device to wake up from sleep. + * <p> + * If the device is currently asleep, wakes it up, otherwise does nothing. + * This is what happens when the power key is pressed to turn on the screen. + * </p><p> + * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. + * </p> + * + * @param time The time when the request to wake up was issued, in the + * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly + * order the user activity with other power management functions. It should be set + * to the timestamp of the input event that caused the request to wake up. + * + * @see #userActivity + * @see #goToSleep + */ + public void wakeUp(long time) { + try { + mService.wakeUp(time); } catch (RemoteException e) { } } @@ -416,34 +509,24 @@ public final class PowerManager { */ public void setBacklightBrightness(int brightness) { try { - mService.setBacklightBrightness(brightness); + mService.setTemporaryScreenBrightnessSettingOverride(brightness); } catch (RemoteException e) { } } /** - * Returns the set of wake lock levels and flags for {@link #newWakeLock} - * that are supported on the device. - * <p> - * For example, to test to see if the {@link #PROXIMITY_SCREEN_OFF_WAKE_LOCK} - * is supported: - * {@samplecode - * PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); - * int supportedFlags = pm.getSupportedWakeLockFlags(); - * boolean proximitySupported = ((supportedFlags & PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) - * == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK); - * } - * </p> + * Returns true if the specified wake lock level is supported. * - * @return The set of supported WakeLock flags. + * @param level The wake lock level to check. + * @return True if the specified wake lock level is supported. * * {@hide} */ - public int getSupportedWakeLockFlags() { + public boolean isWakeLockLevelSupported(int level) { try { - return mService.getSupportedWakeLockFlags(); + return mService.isWakeLockLevelSupported(level); } catch (RemoteException e) { - return 0; + return false; } } @@ -593,7 +676,7 @@ public final class PowerManager { // been explicitly released by the keyguard. mHandler.removeCallbacks(mReleaser); try { - mService.acquireWakeLock(mFlags, mToken, mTag, mWorkSource); + mService.acquireWakeLock(mToken, mFlags, mTag, mWorkSource); } catch (RemoteException e) { } mHeld = true; diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java index a85f4fa..ba77df7 100644 --- a/core/java/android/os/WorkSource.java +++ b/core/java/android/os/WorkSource.java @@ -1,5 +1,9 @@ package android.os; +import com.android.internal.util.ArrayUtils; + +import java.util.Arrays; + /** * Describes the source of some work that may be done by someone else. * Currently the public representation of what a work source is is not @@ -313,6 +317,20 @@ public class WorkSource implements Parcelable { dest.writeIntArray(mUids); } + @Override + public String toString() { + StringBuilder result = new StringBuilder(); + result.append("{WorkSource: uids=["); + for (int i = 0; i < mNum; i++) { + if (i != 0) { + result.append(", "); + } + result.append(mUids[i]); + } + result.append("]}"); + return result.toString(); + } + public static final Parcelable.Creator<WorkSource> CREATOR = new Parcelable.Creator<WorkSource>() { public WorkSource createFromParcel(Parcel in) { diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 01252f0..e08ec1f 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -1381,7 +1381,9 @@ public final class Settings { /** * Whether or not to dim the screen. 0=no 1=yes + * @deprecated This setting is no longer used. */ + @Deprecated public static final String DIM_SCREEN = "dim_screen"; /** diff --git a/core/java/android/service/dreams/DreamManagerService.java b/core/java/android/service/dreams/DreamManagerService.java index dd177cb..fc3f501 100644 --- a/core/java/android/service/dreams/DreamManagerService.java +++ b/core/java/android/service/dreams/DreamManagerService.java @@ -123,7 +123,9 @@ public class DreamManagerService // IDreamManager method @Override public boolean isDreaming() { - return mCurrentDream != null; + synchronized (mLock) { + return mCurrentDreamToken != null; + } } public void bindDreamComponentL(ComponentName componentName, boolean test) { diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java index 7d33ff4a..5a4f322 100644 --- a/core/java/android/util/TimeUtils.java +++ b/core/java/android/util/TimeUtils.java @@ -18,6 +18,7 @@ package android.util; import android.content.res.Resources; import android.content.res.XmlResourceParser; +import android.os.SystemClock; import android.text.format.DateUtils; import com.android.internal.util.XmlUtils; @@ -391,6 +392,18 @@ public class TimeUtils { formatDuration(time-now, pw, 0); } + /** @hide Just for debugging; not internationalized. */ + public static String formatUptime(long time) { + final long diff = time - SystemClock.uptimeMillis(); + if (diff > 0) { + return time + " (in " + diff + " ms)"; + } + if (diff < 0) { + return time + " (" + -diff + " ms ago)"; + } + return time + " (now)"; + } + /** * Convert a System.currentTimeMillis() value to a time of day value like * that printed in logs. MM-DD HH:MM:SS.MMM diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 407bae5..7aa3bb4 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -22,7 +22,6 @@ import android.content.res.Configuration; import android.graphics.Rect; import android.graphics.RectF; import android.os.IBinder; -import android.os.LocalPowerManager; import android.os.Looper; import android.view.animation.Animation; @@ -115,11 +114,11 @@ public interface WindowManagerPolicy { public final static int ACTION_PASS_TO_USER = 0x00000001; /** - * This key event should extend the user activity timeout and turn the lights on. + * This key event should wake the device. * To be returned from {@link #interceptKeyBeforeQueueing}. * Do not return this and {@link #ACTION_GO_TO_SLEEP} or {@link #ACTION_PASS_TO_USER}. */ - public final static int ACTION_POKE_USER_ACTIVITY = 0x00000002; + public final static int ACTION_WAKE_UP = 0x00000002; /** * This key event should put the device to sleep (and engage keyguard if necessary) @@ -473,11 +472,9 @@ public interface WindowManagerPolicy { * Perform initialization of the policy. * * @param context The system context we are running in. - * @param powerManager */ public void init(Context context, IWindowManager windowManager, - WindowManagerFuncs windowManagerFuncs, - LocalPowerManager powerManager); + WindowManagerFuncs windowManagerFuncs); /** * Called by window manager once it has the initial, default native @@ -1093,31 +1090,6 @@ public interface WindowManagerPolicy { public void lockNow(); /** - * Check to see if a screensaver should be run instead of powering off the screen on timeout. - * - * @return true if the screensaver should run, false if the screen should turn off. - * - * @hide - */ - public boolean isScreenSaverEnabled(); - - /** - * Start the screensaver (if it is enabled and not yet running). - * - * @return Whether the screensaver was successfully started. - * - * @hide - */ - public boolean startScreenSaver(); - - /** - * Stop the screensaver if it is running. - * - * @hide - */ - public void stopScreenSaver(); - - /** * Set the last used input method window state. This state is used to make IME transition * smooth. * @hide |