diff options
author | Jeff Brown <jeffbrown@google.com> | 2014-07-19 11:33:47 -0700 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2014-07-22 01:18:26 +0000 |
commit | 970d4132ea28e748c1010be39450a98bbf7466f3 (patch) | |
tree | 0bbaa479dbb4c9b9f8b49b9fe7e7344d7f0581cc | |
parent | f89bff9ed875c1e3ad8e682e651c5994b246cc53 (diff) |
Allow dreams to control screen state and brightness.
Added setDozeScreenState() and setDozeScreenBrightness() methods to
DreamService. The values specified here only take effect once
startDozing is called and can be changed while dozing.
This required some significant rework of the display power controller
but the result seems quite nice and better represents the policy
we want to apply.
Changed the test dream a little bit to make it flash the screen
every minute using the new functions.
Bug: 15903322
Change-Id: I83bcc34503f1b87727d2b2b3c0ef08507f9f0808
14 files changed, 519 insertions, 200 deletions
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java index e58c54d33c10..99af2e7a33b0 100644 --- a/core/java/android/hardware/display/DisplayManagerInternal.java +++ b/core/java/android/hardware/display/DisplayManagerInternal.java @@ -19,6 +19,7 @@ package android.hardware.display; import android.hardware.SensorManager; import android.os.Handler; import android.os.PowerManager; +import android.view.Display; import android.view.DisplayInfo; /** @@ -132,13 +133,19 @@ public abstract class DisplayManagerInternal { * have to micro-manage screen off animations, auto-brightness and other effects. */ public static final class DisplayPowerRequest { - public static final int SCREEN_STATE_OFF = 0; - public static final int SCREEN_STATE_DOZE = 1; - public static final int SCREEN_STATE_DIM = 2; - public static final int SCREEN_STATE_BRIGHT = 3; - - // The requested minimum screen power state: off, doze, dim or bright. - public int screenState; + // Policy: Turn screen off as if the user pressed the power button + // including playing a screen off animation if applicable. + public static final int POLICY_OFF = 0; + // Policy: Enable dozing and always-on display functionality. + public static final int POLICY_DOZE = 1; + // Policy: Make the screen dim when the user activity timeout is + // about to expire. + public static final int POLICY_DIM = 2; + // Policy: Make the screen bright as usual. + public static final int POLICY_BRIGHT = 3; + + // The basic overall policy to apply: off, doze, dim or bright. + public int policy; // If true, the proximity sensor overrides the screen state when an object is // nearby, turning it off temporarily until the object is moved away. @@ -169,44 +176,39 @@ public abstract class DisplayManagerInternal { // visible to the user. public boolean blockScreenOn; + // Overrides the policy for adjusting screen brightness and state while dozing. + public int dozeScreenBrightness; + public int dozeScreenState; + public DisplayPowerRequest() { - screenState = SCREEN_STATE_BRIGHT; + policy = POLICY_BRIGHT; useProximitySensor = false; screenBrightness = PowerManager.BRIGHTNESS_ON; screenAutoBrightnessAdjustment = 0.0f; useAutoBrightness = false; blockScreenOn = false; + dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT; + dozeScreenState = Display.STATE_UNKNOWN; } public DisplayPowerRequest(DisplayPowerRequest other) { copyFrom(other); } - // Returns true if we want the screen on in any mode, including doze. - public boolean wantScreenOnAny() { - return screenState != SCREEN_STATE_OFF; - } - - // Returns true if we want the screen on in a normal mode, excluding doze. - // This is usually what we want to tell the rest of the system. For compatibility - // reasons, we pretend the screen is off when dozing. - public boolean wantScreenOnNormal() { - return screenState == SCREEN_STATE_DIM || screenState == SCREEN_STATE_BRIGHT; - } - - public boolean wantLightSensorEnabled() { - // Specifically, we don't want the light sensor while dozing. - return useAutoBrightness && wantScreenOnNormal(); + public boolean isBrightOrDim() { + return policy == POLICY_BRIGHT || policy == POLICY_DIM; } public void copyFrom(DisplayPowerRequest other) { - screenState = other.screenState; + policy = other.policy; useProximitySensor = other.useProximitySensor; screenBrightness = other.screenBrightness; screenAutoBrightnessAdjustment = other.screenAutoBrightnessAdjustment; useAutoBrightness = other.useAutoBrightness; blockScreenOn = other.blockScreenOn; lowPowerMode = other.lowPowerMode; + dozeScreenBrightness = other.dozeScreenBrightness; + dozeScreenState = other.dozeScreenState; } @Override @@ -217,13 +219,15 @@ public abstract class DisplayManagerInternal { public boolean equals(DisplayPowerRequest other) { return other != null - && screenState == other.screenState + && policy == other.policy && useProximitySensor == other.useProximitySensor && screenBrightness == other.screenBrightness && screenAutoBrightnessAdjustment == other.screenAutoBrightnessAdjustment && useAutoBrightness == other.useAutoBrightness && blockScreenOn == other.blockScreenOn - && lowPowerMode == other.lowPowerMode; + && lowPowerMode == other.lowPowerMode + && dozeScreenBrightness == other.dozeScreenBrightness + && dozeScreenState == other.dozeScreenState; } @Override @@ -233,13 +237,30 @@ public abstract class DisplayManagerInternal { @Override public String toString() { - return "screenState=" + screenState + return "policy=" + policyToString(policy) + ", useProximitySensor=" + useProximitySensor + ", screenBrightness=" + screenBrightness + ", screenAutoBrightnessAdjustment=" + screenAutoBrightnessAdjustment + ", useAutoBrightness=" + useAutoBrightness + ", blockScreenOn=" + blockScreenOn - + ", lowPowerMode=" + lowPowerMode; + + ", lowPowerMode=" + lowPowerMode + + ", dozeScreenBrightness=" + dozeScreenBrightness + + ", dozeScreenState=" + Display.stateToString(dozeScreenState); + } + + public static String policyToString(int policy) { + switch (policy) { + case POLICY_OFF: + return "OFF"; + case POLICY_DOZE: + return "DOZE"; + case POLICY_DIM: + return "DIM"; + case POLICY_BRIGHT: + return "BRIGHT"; + default: + return Integer.toString(policy); + } } } diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 92e80a5afd1a..dda6d27d3edd 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -263,6 +263,12 @@ public final class PowerManager { */ public static final int BRIGHTNESS_OFF = 0; + /** + * Brightness value for default policy handling by the system. + * @hide + */ + public static final int BRIGHTNESS_DEFAULT = -1; + // Note: Be sure to update android.os.BatteryStats and PowerManager.h // if adding or modifying user activity event constants. diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java index 08a15eb7dfa1..14f4a83e29ec 100644 --- a/core/java/android/os/PowerManagerInternal.java +++ b/core/java/android/os/PowerManagerInternal.java @@ -16,6 +16,8 @@ package android.os; +import android.view.Display; + /** * Power manager local system service interface. * @@ -53,6 +55,17 @@ public abstract class PowerManagerInternal { */ public abstract void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis); + /** + * Used by the dream manager to override certain properties while dozing. + * + * @param screenState The overridden screen state, or {@link Display.STATE_UNKNOWN} + * to disable the override. + * @param screenBrightness The overridden screen brightness, or + * {@link PowerManager#BRIGHTNESS_DEFAULT} to disable the override. + */ + public abstract void setDozeOverrideFromDreamManager( + int screenState, int screenBrightness); + public abstract boolean getLowPowerModeEnabled(); public abstract void registerLowPowerModeObserver(LowPowerModeListener listener); diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index 5fa542ab114a..5cf8aa6a821d 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -27,10 +27,13 @@ import android.graphics.PixelFormat; import android.graphics.drawable.ColorDrawable; import android.os.Handler; import android.os.IBinder; +import android.os.PowerManager; +import android.os.RemoteException; import android.os.RemoteException; import android.os.ServiceManager; import android.util.Slog; import android.view.ActionMode; +import android.view.Display; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; @@ -42,6 +45,7 @@ import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.view.WindowManager.LayoutParams; import android.view.accessibility.AccessibilityEvent; +import android.util.MathUtils; import com.android.internal.policy.PolicyManager; import com.android.internal.util.DumpUtils; @@ -133,8 +137,11 @@ import com.android.internal.util.DumpUtils.Dump; * android:exported="true" * android:icon="@drawable/my_icon" * android:label="@string/my_dream_label" - * android:permission="android.permission.BIND_DREAM_SERVICE" > - * ... + * android:permission="android.permission.BIND_DREAM_SERVICE"> + * <intent-filter> + * <action android:name=”android.service.dreams.DreamService” /> + * <category android:name=”android.intent.category.DEFAULT” /> + * </intent-filter> * </service> * </pre> */ @@ -177,6 +184,8 @@ public class DreamService extends Service implements Window.Callback { private boolean mDozing; private boolean mWindowless; private DozeHardware mDozeHardware; + private int mDozeScreenState = Display.STATE_UNKNOWN; + private int mDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT; private boolean mDebug = false; @@ -560,7 +569,7 @@ public class DreamService extends Service implements Window.Callback { * * @return True if this dream can doze. * @see #startDozing - * @hide experimental + * @hide For use by system UI components only. */ public boolean canDoze() { return mCanDoze; @@ -593,13 +602,19 @@ public class DreamService extends Service implements Window.Callback { * </p> * * @see #stopDozing - * @hide experimental + * @hide For use by system UI components only. */ public void startDozing() { if (mCanDoze && !mDozing) { mDozing = true; + updateDoze(); + } + } + + private void updateDoze() { + if (mDozing) { try { - mSandman.startDozing(mWindowToken); + mSandman.startDozing(mWindowToken, mDozeScreenState, mDozeScreenBrightness); } catch (RemoteException ex) { // system server died } @@ -615,7 +630,7 @@ public class DreamService extends Service implements Window.Callback { * </p> * * @see #startDozing - * @hide experimental + * @hide For use by system UI components only. */ public void stopDozing() { if (mDozing) { @@ -636,7 +651,7 @@ public class DreamService extends Service implements Window.Callback { * @return True if the dream is dozing. * * @see #setDozing(boolean) - * @hide experimental + * @hide For use by system UI components only. */ public boolean isDozing() { return mDozing; @@ -649,7 +664,7 @@ public class DreamService extends Service implements Window.Callback { * @return An instance of {@link DozeHardware} or null if this device does not offer * hardware support for dozing. * - * @hide experimental + * @hide For use by system UI components only. */ public DozeHardware getDozeHardware() { if (mCanDoze && mDozeHardware == null && mWindowToken != null) { @@ -666,11 +681,116 @@ public class DreamService extends Service implements Window.Callback { } /** + * Gets the screen state to use while dozing. + * + * @return The screen state to use while dozing, such as {@link Display#STATE_ON}, + * {@link Display#STATE_DOZE}, {@link Display#STATE_DOZE_SUSPEND}, + * or {@link Display#STATE_OFF}, or {@link Display#STATE_UNKNOWN} for the default + * behavior. + * + * @see #setDozeScreenState + * @hide For use by system UI components only. + */ + public int getDozeScreenState() { + return mDozeScreenState; + } + + /** + * Sets the screen state to use while dozing. + * <p> + * The value of this property determines the power state of the primary display + * once {@link #startDozing} has been called. The default value is + * {@link Display#STATE_UNKNOWN} which lets the system decide. + * The dream may set a different state before starting to doze and may + * perform transitions between states while dozing to conserve power and + * achieve various effects. + * </p><p> + * It is recommended that the state be set to {@link Display#STATE_DOZE_SUSPEND} + * once the dream has completely finished drawing and before it releases its wakelock + * to allow the display hardware to be fully suspended. While suspended, the + * display will preserve its on-screen contents or hand off control to dedicated + * doze hardware if the devices supports it. If the doze suspend state is + * used, the dream must make sure to set the mode back + * to {@link Display#STATE_DOZE} or {@link Display#STATE_ON} before drawing again + * since the display updates may be ignored and not seen by the user otherwise. + * </p><p> + * The set of available display power states and their behavior while dozing is + * hardware dependent and may vary across devices. The dream may therefore + * need to be modified or configured to correctly support the hardware. + * </p> + * + * @param state The screen state to use while dozing, such as {@link Display#STATE_ON}, + * {@link Display#STATE_DOZE}, {@link Display#STATE_DOZE_SUSPEND}, + * or {@link Display#STATE_OFF}, or {@link Display#STATE_UNKNOWN} for the default + * behavior. + * + * @hide For use by system UI components only. + */ + public void setDozeScreenState(int state) { + if (mDozeScreenState != state) { + mDozeScreenState = state; + updateDoze(); + } + } + + /** + * Gets the screen brightness to use while dozing. + * + * @return The screen brightness while dozing as a value between + * {@link PowerManager#BRIGHTNESS_OFF} (0) and {@link PowerManager#BRIGHTNESS_ON} (255), + * or {@link PowerManager#BRIGHTNESS_DEFAULT} (-1) to ask the system to apply + * its default policy based on the screen state. + * + * @see #setDozeScreenBrightness + * @hide For use by system UI components only. + */ + public int getDozeScreenBrightness() { + return mDozeScreenBrightness; + } + + /** + * Sets the screen brightness to use while dozing. + * <p> + * The value of this property determines the power state of the primary display + * once {@link #startDozing} has been called. The default value is + * {@link PowerManager#BRIGHTNESS_DEFAULT} which lets the system decide. + * The dream may set a different brightness before starting to doze and may adjust + * the brightness while dozing to conserve power and achieve various effects. + * </p><p> + * Note that dream may specify any brightness in the full 0-255 range, including + * values that are less than the minimum value for manual screen brightness + * adjustments by the user. In particular, the value may be set to 0 which may + * turn off the backlight entirely while still leaving the screen on although + * this behavior is device dependent and not guaranteed. + * </p><p> + * The available range of display brightness values and their behavior while dozing is + * hardware dependent and may vary across devices. The dream may therefore + * need to be modified or configured to correctly support the hardware. + * </p> + * + * @param brightness The screen brightness while dozing as a value between + * {@link PowerManager#BRIGHTNESS_OFF} (0) and {@link PowerManager#BRIGHTNESS_ON} (255), + * or {@link PowerManager#BRIGHTNESS_DEFAULT} (-1) to ask the system to apply + * its default policy based on the screen state. + * + * @hide For use by system UI components only. + */ + public void setDozeScreenBrightness(int brightness) { + if (brightness != PowerManager.BRIGHTNESS_DEFAULT) { + brightness = clampAbsoluteBrightness(brightness); + } + if (mDozeScreenBrightness != brightness) { + mDozeScreenBrightness = brightness; + updateDoze(); + } + } + + /** * Called when this Dream is constructed. */ @Override public void onCreate() { - if (mDebug) Slog.v(TAG, "onCreate() on thread " + Thread.currentThread().getId()); + if (mDebug) Slog.v(TAG, "onCreate()"); super.onCreate(); } @@ -844,8 +964,6 @@ public class DreamService extends Service implements Window.Callback { return; } - if (mDebug) Slog.v(TAG, "Attached on thread " + Thread.currentThread().getId()); - mWindowToken = windowToken; mCanDoze = canDoze; if (mWindowless && !mCanDoze) { @@ -963,7 +1081,17 @@ public class DreamService extends Service implements Window.Callback { if (isScreenBright()) pw.print(" bright"); if (isWindowless()) pw.print(" windowless"); if (isDozing()) pw.print(" dozing"); + else if (canDoze()) pw.print(" candoze"); pw.println(); + if (canDoze()) { + pw.println(" doze hardware: " + mDozeHardware); + pw.println(" doze screen state: " + Display.stateToString(mDozeScreenState)); + pw.println(" doze screen brightness: " + mDozeScreenBrightness); + } + } + + private static int clampAbsoluteBrightness(int value) { + return MathUtils.constrain(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON); } private final class DreamServiceWrapper extends IDreamService.Stub { diff --git a/core/java/android/service/dreams/IDreamManager.aidl b/core/java/android/service/dreams/IDreamManager.aidl index 9608a4da3686..648426cbce7d 100644 --- a/core/java/android/service/dreams/IDreamManager.aidl +++ b/core/java/android/service/dreams/IDreamManager.aidl @@ -32,7 +32,7 @@ interface IDreamManager { void testDream(in ComponentName componentName); boolean isDreaming(); void finishSelf(in IBinder token, boolean immediate); - void startDozing(in IBinder token); + void startDozing(in IBinder token, int screenState, int screenBrightness); void stopDozing(in IBinder token); IDozeHardware getDozeHardware(in IBinder token); -}
\ No newline at end of file +} diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index b17fa4a8d498..154d2277e3cd 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -831,4 +831,13 @@ public final class Display { return Integer.toString(state); } } + + /** + * Returns true if display updates may be suspended while in the specified + * display power state. + * @hide + */ + public static boolean isSuspendedState(int state) { + return state == STATE_OFF || state == STATE_DOZE_SUSPEND; + } } diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java index 4740caee244a..45d377107768 100644 --- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java +++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java @@ -26,7 +26,6 @@ import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; -import android.hardware.display.DisplayManagerInternal; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -199,9 +198,10 @@ class AutomaticBrightnessController { return mScreenAutoBrightness; } - public void updatePowerState(DisplayManagerInternal.DisplayPowerRequest request) { - if (setScreenAutoBrightnessAdjustment(request.screenAutoBrightnessAdjustment) - | setLightSensorEnabled(request.wantLightSensorEnabled())) { + public void configure(boolean enable, float adjustment) { + boolean changed = setLightSensorEnabled(enable); + changed |= setScreenAutoBrightnessAdjustment(adjustment); + if (changed) { updateAutoBrightness(false /*sendUpdate*/); } } diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index a361e1082f40..09221a3e9c1d 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -213,9 +213,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // The elapsed real time when the screen on was blocked. private long mScreenOnBlockStartRealTime; - // True if the screen auto-brightness value is actually being used to - // set the display brightness. - private boolean mUsingScreenAutoBrightness; + // Remembers whether certain kinds of brightness adjustments + // were recently applied so that we can decide how to transition. + private boolean mAppliedAutoBrightness; + private boolean mAppliedDimming; + private boolean mAppliedLowPower; // The controller for the automatic brightness level. private AutomaticBrightnessController mAutomaticBrightnessController; @@ -428,7 +430,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // Update the power state request. final boolean mustNotify; boolean mustInitialize = false; - boolean wasDimOrDoze = false; boolean autoBrightnessAdjustmentChanged = false; synchronized (mLock) { @@ -444,8 +445,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mPendingRequestChangedLocked = false; mustInitialize = true; } else if (mPendingRequestChangedLocked) { - wasDimOrDoze = (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM - || mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DOZE); autoBrightnessAdjustmentChanged = (mPowerRequest.screenAutoBrightnessAdjustment != mPendingRequestLocked.screenAutoBrightnessAdjustment); mPowerRequest.copyFrom(mPendingRequestLocked); @@ -463,10 +462,32 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call initialize(); } + // Compute the basic display state using the policy. + // We might override this below based on other factors. + int state; + int brightness = PowerManager.BRIGHTNESS_DEFAULT; + switch (mPowerRequest.policy) { + case DisplayPowerRequest.POLICY_OFF: + state = Display.STATE_OFF; + break; + case DisplayPowerRequest.POLICY_DOZE: + if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) { + state = mPowerRequest.dozeScreenState; + } else { + state = Display.STATE_DOZE; + } + brightness = mPowerRequest.dozeScreenBrightness; + break; + case DisplayPowerRequest.POLICY_DIM: + case DisplayPowerRequest.POLICY_BRIGHT: + default: + state = Display.STATE_ON; + break; + } + // Apply the proximity sensor. if (mProximitySensor != null) { - if (mPowerRequest.useProximitySensor - && mPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) { + if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) { setProximitySensorEnabled(true); if (!mScreenOffBecauseOfProximity && mProximity == PROXIMITY_POSITIVE) { @@ -476,7 +497,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } else if (mWaitingForNegativeProximity && mScreenOffBecauseOfProximity && mProximity == PROXIMITY_POSITIVE - && mPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) { + && state != Display.STATE_OFF) { setProximitySensorEnabled(true); } else { setProximitySensorEnabled(false); @@ -490,63 +511,89 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } else { mWaitingForNegativeProximity = false; } + if (mScreenOffBecauseOfProximity) { + state = Display.STATE_OFF; + } + + // Use zero brightness when screen is off. + if (state == Display.STATE_OFF) { + brightness = PowerManager.BRIGHTNESS_OFF; + } + + // Use default brightness when dozing unless overridden. + if (brightness < 0 && (state == Display.STATE_DOZE + || state == Display.STATE_DOZE_SUSPEND)) { + brightness = mScreenBrightnessDozeConfig; + } - // Turn on the light sensor if needed. + // Configure auto-brightness. + boolean autoBrightnessEnabled = false; if (mAutomaticBrightnessController != null) { - mAutomaticBrightnessController.updatePowerState(mPowerRequest); - } - - // Set the screen brightness. - if (mPowerRequest.wantScreenOnAny()) { - int target; - boolean slow; - int screenAutoBrightness = mAutomaticBrightnessController != null ? - mAutomaticBrightnessController.getAutomaticScreenBrightness() : -1; - if (screenAutoBrightness >= 0 && mPowerRequest.useAutoBrightness) { - // Use current auto-brightness value. - target = screenAutoBrightness; - slow = mUsingScreenAutoBrightness && !autoBrightnessAdjustmentChanged; - mUsingScreenAutoBrightness = true; + autoBrightnessEnabled = mPowerRequest.useAutoBrightness + && state == Display.STATE_ON && brightness < 0; + mAutomaticBrightnessController.configure(autoBrightnessEnabled, + mPowerRequest.screenAutoBrightnessAdjustment); + } + + // Apply auto-brightness. + boolean slowChange = false; + if (brightness < 0) { + if (autoBrightnessEnabled) { + brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness(); + } + if (brightness >= 0) { + // Use current auto-brightness value and slowly adjust to changes. + brightness = clampScreenBrightness(brightness); + if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) { + slowChange = true; // slowly adapt to auto-brightness + } + mAppliedAutoBrightness = true; } else { - // Light sensor is disabled or not ready yet. - // Use the current brightness setting from the request, which is expected - // provide a nominal default value for the case where auto-brightness - // is not ready yet. - target = mPowerRequest.screenBrightness; - slow = false; - mUsingScreenAutoBrightness = false; - } - if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DOZE) { - // Dim quickly to the doze state. - target = mScreenBrightnessDozeConfig; - slow = false; - } else if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM) { - // Dim quickly by at least some minimum amount. - target = Math.min(target - SCREEN_DIM_MINIMUM_REDUCTION, - mScreenBrightnessDimConfig); - slow = false; - } else if (wasDimOrDoze) { - // Brighten quickly. - slow = false; - } - // If low power mode is enabled, brightness level - // would be scaled down to half - if (mPowerRequest.lowPowerMode) { - target = target/2; - } - animateScreenBrightness(clampScreenBrightness(target), - slow ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST); + mAppliedAutoBrightness = false; + } } else { - // Screen is off. Don't bother changing the brightness. - mUsingScreenAutoBrightness = false; + mAppliedAutoBrightness = false; + } + + // Apply manual brightness. + // Use the current brightness setting from the request, which is expected + // provide a nominal default value for the case where auto-brightness + // is not ready yet. + if (brightness < 0) { + brightness = clampScreenBrightness(mPowerRequest.screenBrightness); + } + + // Apply dimming by at least some minimum amount when user activity + // timeout is about to expire. + if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) { + brightness = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION, + mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum); + if (!mAppliedDimming) { + slowChange = false; + } + mAppliedDimming = true; + } + + // If low power mode is enabled, cut the brightness level by half + // as long as it is above the minimum threshold. + if (mPowerRequest.lowPowerMode) { + if (brightness > mScreenBrightnessRangeMinimum) { + brightness = Math.max(brightness / 2, mScreenBrightnessRangeMinimum); + } + if (!mAppliedLowPower) { + slowChange = false; + } + mAppliedLowPower = true; + } + + // Animate the screen brightness when the screen is on. + if (state != Display.STATE_OFF) { + animateScreenBrightness(brightness, slowChange + ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST); } // Animate the screen on or off unless blocked. - if (mScreenOffBecauseOfProximity) { - // Screen off due to proximity. - setScreenState(Display.STATE_OFF); - unblockScreenOn(); - } else if (mPowerRequest.wantScreenOnAny()) { + if (state == Display.STATE_ON) { // Want screen on. // Wait for previous off animation to complete beforehand. // It is relatively short but if we cancel it and switch to the @@ -555,21 +602,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // Turn the screen on. The contents of the screen may not yet // be visible if the electron beam has not been dismissed because // its last frame of animation is solid black. - - if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DOZE) { - if (!mScreenBrightnessRampAnimator.isAnimating()) { - setScreenState(Display.STATE_DOZE); - } - } else { - setScreenState(Display.STATE_ON); - } - + setScreenState(Display.STATE_ON); if (mPowerRequest.blockScreenOn && mPowerState.getElectronBeamLevel() == 0.0f) { blockScreenOn(); } else { unblockScreenOn(); - if (USE_ELECTRON_BEAM_ON_ANIMATION) { + if (USE_ELECTRON_BEAM_ON_ANIMATION && mPowerRequest.isBrightOrDim()) { + // Perform screen on animation. if (!mElectronBeamOnAnimator.isStarted()) { if (mPowerState.getElectronBeamLevel() == 1.0f) { mPowerState.dismissElectronBeam(); @@ -583,28 +623,59 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } } } else { + // Skip screen on animation. mPowerState.setElectronBeamLevel(1.0f); mPowerState.dismissElectronBeam(); } } } + } else if (state == Display.STATE_DOZE) { + // Want screen dozing. + // Wait for brightness animation to complete beforehand when entering doze + // from screen on. + unblockScreenOn(); + if (!mScreenBrightnessRampAnimator.isAnimating() + || mPowerState.getScreenState() != Display.STATE_ON) { + // Set screen state and dismiss the black surface without fanfare. + setScreenState(state); + mPowerState.setElectronBeamLevel(1.0f); + mPowerState.dismissElectronBeam(); + } + } else if (state == Display.STATE_DOZE_SUSPEND) { + // Want screen dozing and suspended. + // Wait for brightness animation to complete beforehand unless already + // suspended because we may not be able to change it after suspension. + unblockScreenOn(); + if (!mScreenBrightnessRampAnimator.isAnimating() + || mPowerState.getScreenState() == Display.STATE_DOZE_SUSPEND) { + // Set screen state and dismiss the black surface without fanfare. + setScreenState(state); + mPowerState.setElectronBeamLevel(1.0f); + mPowerState.dismissElectronBeam(); + } } else { // Want screen off. // Wait for previous on animation to complete beforehand. unblockScreenOn(); if (!mElectronBeamOnAnimator.isStarted()) { - if (!mElectronBeamOffAnimator.isStarted()) { - if (mPowerState.getElectronBeamLevel() == 0.0f) { - setScreenState(Display.STATE_OFF); - } else if (mPowerState.prepareElectronBeam( - mElectronBeamFadesConfig ? - ElectronBeam.MODE_FADE : - ElectronBeam.MODE_COOL_DOWN) - && mPowerState.getScreenState() != Display.STATE_OFF) { - mElectronBeamOffAnimator.start(); - } else { - mElectronBeamOffAnimator.end(); + if (mPowerRequest.policy == DisplayPowerRequest.POLICY_OFF) { + // Perform screen off animation. + if (!mElectronBeamOffAnimator.isStarted()) { + if (mPowerState.getElectronBeamLevel() == 0.0f) { + setScreenState(Display.STATE_OFF); + } else if (mPowerState.prepareElectronBeam( + mElectronBeamFadesConfig ? + ElectronBeam.MODE_FADE : + ElectronBeam.MODE_COOL_DOWN) + && mPowerState.getScreenState() != Display.STATE_OFF) { + mElectronBeamOffAnimator.start(); + } else { + mElectronBeamOffAnimator.end(); + } } + } else { + // Skip screen off animation. + setScreenState(Display.STATE_OFF); } } } @@ -856,7 +927,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call pw.println(" mPendingProximityDebounceTime=" + TimeUtils.formatUptime(mPendingProximityDebounceTime)); pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity); - pw.println(" mUsingScreenAutoBrightness=" + mUsingScreenAutoBrightness); + pw.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness); + pw.println(" mAppliedDimming=" + mAppliedDimming); + pw.println(" mAppliedLowPower=" + mAppliedLowPower); pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" + mScreenBrightnessRampAnimator.isAnimating()); diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java index a5f884984037..4821e746949b 100644 --- a/services/core/java/com/android/server/display/DisplayPowerState.java +++ b/services/core/java/com/android/server/display/DisplayPowerState.java @@ -402,13 +402,14 @@ final class DisplayPowerState { Slog.d(TAG, "Updating screen state: state=" + Display.stateToString(state) + ", backlight=" + backlight); } - if (stateChanged && state != Display.STATE_OFF) { + boolean suspending = Display.isSuspendedState(state); + if (stateChanged && !suspending) { mBlanker.requestDisplayState(state); } if (backlightChanged) { mBacklight.setBrightness(backlight); } - if (stateChanged && state == Display.STATE_OFF) { + if (stateChanged && suspending) { mBlanker.requestDisplayState(state); } } diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java index 4ccf73bd05ee..107a6f687406 100644 --- a/services/core/java/com/android/server/dreams/DreamManagerService.java +++ b/services/core/java/com/android/server/dreams/DreamManagerService.java @@ -38,6 +38,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.PowerManager; +import android.os.PowerManagerInternal; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; @@ -48,6 +49,7 @@ import android.service.dreams.IDozeHardware; import android.service.dreams.IDreamManager; import android.text.TextUtils; import android.util.Slog; +import android.view.Display; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -71,6 +73,7 @@ public final class DreamManagerService extends SystemService { private final DreamHandler mHandler; private final DreamController mController; private final PowerManager mPowerManager; + private final PowerManagerInternal mPowerManagerInternal; private final PowerManager.WakeLock mDozeWakeLock; private final McuHal mMcuHal; // synchronized on self @@ -81,6 +84,8 @@ public final class DreamManagerService extends SystemService { private boolean mCurrentDreamCanDoze; private boolean mCurrentDreamIsDozing; private boolean mCurrentDreamIsWaking; + private int mCurrentDreamDozeScreenState = Display.STATE_UNKNOWN; + private int mCurrentDreamDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT; private DozeHardwareWrapper mCurrentDreamDozeHardware; public DreamManagerService(Context context) { @@ -90,6 +95,7 @@ public final class DreamManagerService extends SystemService { mController = new DreamController(context, mHandler, mControllerListener); mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); + mPowerManagerInternal = getLocalService(PowerManagerInternal.class); mDozeWakeLock = mPowerManager.newWakeLock(PowerManager.DOZE_WAKE_LOCK, TAG); mMcuHal = McuHal.open(); @@ -134,6 +140,9 @@ public final class DreamManagerService extends SystemService { pw.println("mCurrentDreamCanDoze=" + mCurrentDreamCanDoze); pw.println("mCurrentDreamIsDozing=" + mCurrentDreamIsDozing); pw.println("mCurrentDreamIsWaking=" + mCurrentDreamIsWaking); + pw.println("mCurrentDreamDozeScreenState=" + + Display.stateToString(mCurrentDreamDozeScreenState)); + pw.println("mCurrentDreamDozeScreenBrightness=" + mCurrentDreamDozeScreenBrightness); pw.println("mCurrentDreamDozeHardware=" + mCurrentDreamDozeHardware); pw.println("getDozeComponent()=" + getDozeComponent()); pw.println(); @@ -213,16 +222,24 @@ public final class DreamManagerService extends SystemService { } } - private void startDozingInternal(IBinder token) { + private void startDozingInternal(IBinder token, int screenState, + int screenBrightness) { if (DEBUG) { - Slog.d(TAG, "Dream requested to start dozing: " + token); + Slog.d(TAG, "Dream requested to start dozing: " + token + + ", screenState=" + screenState + + ", screenBrightness=" + screenBrightness); } synchronized (mLock) { - if (mCurrentDreamToken == token && mCurrentDreamCanDoze - && !mCurrentDreamIsDozing) { - mCurrentDreamIsDozing = true; - mDozeWakeLock.acquire(); + if (mCurrentDreamToken == token && mCurrentDreamCanDoze) { + mCurrentDreamDozeScreenState = screenState; + mCurrentDreamDozeScreenBrightness = screenBrightness; + mPowerManagerInternal.setDozeOverrideFromDreamManager( + screenState, screenBrightness); + if (!mCurrentDreamIsDozing) { + mCurrentDreamIsDozing = true; + mDozeWakeLock.acquire(); + } } } } @@ -236,6 +253,8 @@ public final class DreamManagerService extends SystemService { if (mCurrentDreamToken == token && mCurrentDreamIsDozing) { mCurrentDreamIsDozing = false; mDozeWakeLock.release(); + mPowerManagerInternal.setDozeOverrideFromDreamManager( + Display.STATE_UNKNOWN, PowerManager.BRIGHTNESS_DEFAULT); } } } @@ -399,6 +418,8 @@ public final class DreamManagerService extends SystemService { mCurrentDreamIsDozing = false; mDozeWakeLock.release(); } + mCurrentDreamDozeScreenState = Display.STATE_UNKNOWN; + mCurrentDreamDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT; if (mCurrentDreamDozeHardware != null) { mCurrentDreamDozeHardware.release(); mCurrentDreamDozeHardware = null; @@ -593,7 +614,7 @@ public final class DreamManagerService extends SystemService { } @Override // Binder call - public void startDozing(IBinder token) { + public void startDozing(IBinder token, int screenState, int screenBrightness) { // Requires no permission, called by Dream from an arbitrary process. if (token == null) { throw new IllegalArgumentException("token must not be null"); @@ -601,7 +622,7 @@ public final class DreamManagerService extends SystemService { final long ident = Binder.clearCallingIdentity(); try { - startDozingInternal(token); + startDozingInternal(token, screenState, screenBrightness); } finally { Binder.restoreCallingIdentity(ident); } diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 4b1e8ebe1303..8c52fadb7fc8 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -404,6 +404,12 @@ public final class PowerManagerService extends com.android.server.SystemService // Use NaN to disable. private float mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN; + // The screen state to use while dozing. + private int mDozeScreenStateOverrideFromDreamManager = Display.STATE_UNKNOWN; + + // The screen brightness to use while dozing. + private int mDozeScreenBrightnessOverrideFromDreamManager = PowerManager.BRIGHTNESS_DEFAULT; + // Time when we last logged a warning about calling userActivity() without permission. private long mLastWarningAboutUserActivityPermission = Long.MIN_VALUE; @@ -1370,11 +1376,12 @@ public final class PowerManagerService extends com.android.server.SystemService if (mUserActivitySummary == 0 && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) { nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout; - if (now < nextTimeout - && mDisplayPowerRequest.wantScreenOnNormal()) { - mUserActivitySummary = mDisplayPowerRequest.screenState - == DisplayPowerRequest.SCREEN_STATE_BRIGHT ? - USER_ACTIVITY_SCREEN_BRIGHT : USER_ACTIVITY_SCREEN_DIM; + if (now < nextTimeout) { + if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT) { + mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT; + } else if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) { + mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM; + } } } if (mUserActivitySummary != 0) { @@ -1631,7 +1638,7 @@ public final class PowerManagerService extends com.android.server.SystemService if (mWakefulness != WAKEFULNESS_DREAMING || !mDreamsSupportedConfig || !mDreamsEnabledSetting - || !mDisplayPowerRequest.wantScreenOnNormal() + || !mDisplayPowerRequest.isBrightOrDim() || !mBootCompleted) { return false; } @@ -1672,8 +1679,7 @@ public final class PowerManagerService extends com.android.server.SystemService if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED | DIRTY_SETTINGS | DIRTY_SCREEN_ON_BLOCKER_RELEASED)) != 0) { - final int newScreenState = getDesiredScreenPowerStateLocked(); - mDisplayPowerRequest.screenState = newScreenState; + mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked(); int screenBrightness = mScreenBrightnessSettingDefault; float screenAutoBrightnessAdjustment = 0.0f; @@ -1713,13 +1719,22 @@ public final class PowerManagerService extends com.android.server.SystemService mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled; + if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) { + mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager; + mDisplayPowerRequest.dozeScreenBrightness = + mDozeScreenBrightnessOverrideFromDreamManager; + } else { + mDisplayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN; + mDisplayPowerRequest.dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT; + } + mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest, mRequestWaitForNegativeProximity); mRequestWaitForNegativeProximity = false; if (DEBUG_SPEW) { Slog.d(TAG, "updateScreenStateLocked: mDisplayReady=" + mDisplayReady - + ", newScreenState=" + newScreenState + + ", policy=" + mDisplayPowerRequest.policy + ", mWakefulness=" + mWakefulness + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary) + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary) @@ -1737,22 +1752,22 @@ public final class PowerManagerService extends com.android.server.SystemService return value >= -1.0f && value <= 1.0f; } - private int getDesiredScreenPowerStateLocked() { + private int getDesiredScreenPolicyLocked() { if (mWakefulness == WAKEFULNESS_ASLEEP) { - return DisplayPowerRequest.SCREEN_STATE_OFF; + return DisplayPowerRequest.POLICY_OFF; } if ((mWakeLockSummary & WAKE_LOCK_DOZE) != 0) { - return DisplayPowerRequest.SCREEN_STATE_DOZE; + return DisplayPowerRequest.POLICY_DOZE; } if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0 || (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0 || !mBootCompleted) { - return DisplayPowerRequest.SCREEN_STATE_BRIGHT; + return DisplayPowerRequest.POLICY_BRIGHT; } - return DisplayPowerRequest.SCREEN_STATE_DIM; + return DisplayPowerRequest.POLICY_DIM; } private final DisplayManagerInternal.DisplayPowerCallbacks mDisplayPowerCallbacks = @@ -1895,7 +1910,7 @@ public final class PowerManagerService extends com.android.server.SystemService if (!mDisplayReady) { return true; } - if (mDisplayPowerRequest.wantScreenOnNormal()) { + if (mDisplayPowerRequest.isBrightOrDim()) { // If we asked for the screen to be on but it is off due to the proximity // sensor then we may suspend but only if the configuration allows it. // On some hardware it may not be safe to suspend because the proximity @@ -2103,6 +2118,19 @@ public final class PowerManagerService extends com.android.server.SystemService } } + private void setDozeOverrideFromDreamManagerInternal( + int screenState, int screenBrightness) { + synchronized (mLock) { + if (mDozeScreenStateOverrideFromDreamManager != screenState + || mDozeScreenBrightnessOverrideFromDreamManager != screenBrightness) { + mDozeScreenStateOverrideFromDreamManager = screenState; + mDozeScreenBrightnessOverrideFromDreamManager = screenBrightness; + mDirty |= DIRTY_SETTINGS; + updatePowerStateLocked(); + } + } + } + private void powerHintInternal(int hintId, int data) { nativeSendPowerHint(hintId, data); } @@ -2257,6 +2285,10 @@ public final class PowerManagerService extends com.android.server.SystemService + mTemporaryScreenBrightnessSettingOverride); pw.println(" mTemporaryScreenAutoBrightnessAdjustmentSettingOverride=" + mTemporaryScreenAutoBrightnessAdjustmentSettingOverride); + pw.println(" mDozeScreenStateOverrideFromDreamManager=" + + mDozeScreenStateOverrideFromDreamManager); + pw.println(" mDozeScreenBrightnessOverrideFromDreamManager=" + + mDozeScreenBrightnessOverrideFromDreamManager); pw.println(" mScreenBrightnessSettingMinimum=" + mScreenBrightnessSettingMinimum); pw.println(" mScreenBrightnessSettingMaximum=" + mScreenBrightnessSettingMaximum); pw.println(" mScreenBrightnessSettingDefault=" + mScreenBrightnessSettingDefault); @@ -3026,63 +3058,44 @@ public final class PowerManagerService extends com.android.server.SystemService } private final class LocalService extends PowerManagerInternal { - /** - * Used by the window manager to override the screen brightness based on the - * current foreground activity. - * - * This method must only be called by the window manager. - * - * @param brightness The overridden brightness, or -1 to disable the override. - */ @Override - public void setScreenBrightnessOverrideFromWindowManager(int brightness) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.DEVICE_POWER, null); - - final long ident = Binder.clearCallingIdentity(); - try { - setScreenBrightnessOverrideFromWindowManagerInternal(brightness); - } finally { - Binder.restoreCallingIdentity(ident); + public void setScreenBrightnessOverrideFromWindowManager(int screenBrightness) { + if (screenBrightness < PowerManager.BRIGHTNESS_DEFAULT + || screenBrightness > PowerManager.BRIGHTNESS_ON) { + screenBrightness = PowerManager.BRIGHTNESS_DEFAULT; } + setScreenBrightnessOverrideFromWindowManagerInternal(screenBrightness); } - /** - * Used by the window manager to override the button brightness based on the - * current foreground activity. - * - * This method must only be called by the window manager. - * - * @param brightness The overridden brightness, or -1 to disable the override. - */ @Override - public void setButtonBrightnessOverrideFromWindowManager(int brightness) { + public void setButtonBrightnessOverrideFromWindowManager(int screenBrightness) { // Do nothing. // Button lights are not currently supported in the new implementation. - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.DEVICE_POWER, null); } - /** - * Used by the window manager to override the user activity timeout based on the - * current foreground activity. It can only be used to make the timeout shorter - * than usual, not longer. - * - * This method must only be called by the window manager. - * - * @param timeoutMillis The overridden timeout, or -1 to disable the override. - */ @Override - public void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.DEVICE_POWER, null); - - final long ident = Binder.clearCallingIdentity(); - try { - setUserActivityTimeoutOverrideFromWindowManagerInternal(timeoutMillis); - } finally { - Binder.restoreCallingIdentity(ident); + public void setDozeOverrideFromDreamManager(int screenState, int screenBrightness) { + switch (screenState) { + case Display.STATE_UNKNOWN: + case Display.STATE_OFF: + case Display.STATE_DOZE: + case Display.STATE_DOZE_SUSPEND: + case Display.STATE_ON: + break; + default: + screenState = Display.STATE_UNKNOWN; + break; + } + if (screenBrightness < PowerManager.BRIGHTNESS_DEFAULT + || screenBrightness > PowerManager.BRIGHTNESS_ON) { + screenBrightness = PowerManager.BRIGHTNESS_DEFAULT; } + setDozeOverrideFromDreamManagerInternal(screenState, screenBrightness); + } + + @Override + public void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis) { + setUserActivityTimeoutOverrideFromWindowManagerInternal(timeoutMillis); } @Override diff --git a/tests/DozeTest/AndroidManifest.xml b/tests/DozeTest/AndroidManifest.xml index c199f69aeb1e..03778d6fe4cc 100644 --- a/tests/DozeTest/AndroidManifest.xml +++ b/tests/DozeTest/AndroidManifest.xml @@ -22,7 +22,8 @@ android:name="DozeTestDream" android:exported="true" android:icon="@drawable/ic_app" - android:label="@string/doze_dream_name"> + android:label="@string/doze_dream_name" + android:permission="android.permission.BIND_DREAM_SERVICE"> <!-- Commented out to prevent this dream from appearing in the list of dreams that the user can select via the Settings application. <intent-filter> diff --git a/tests/DozeTest/res/layout/dream.xml b/tests/DozeTest/res/layout/dream.xml index 1c8fd3fccbf4..bced2306db06 100644 --- a/tests/DozeTest/res/layout/dream.xml +++ b/tests/DozeTest/res/layout/dream.xml @@ -18,7 +18,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_vertical" - android:orientation="vertical"> + android:orientation="vertical" + android:background="#bb2288"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/tests/DozeTest/src/com/android/dreams/dozetest/DozeTestDream.java b/tests/DozeTest/src/com/android/dreams/dozetest/DozeTestDream.java index a0b2d1aeea17..f72e331c37a7 100644 --- a/tests/DozeTest/src/com/android/dreams/dozetest/DozeTestDream.java +++ b/tests/DozeTest/src/com/android/dreams/dozetest/DozeTestDream.java @@ -22,11 +22,13 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.os.Handler; import android.os.PowerManager; import android.service.dreams.DozeHardware; import android.service.dreams.DreamService; import android.text.format.DateFormat; import android.util.Log; +import android.view.Display; import android.widget.TextView; import java.util.Date; @@ -51,10 +53,16 @@ public class DozeTestDream extends DreamService { // Doesn't mean anything. Real hardware won't handle it. private static final String TEST_PING_MESSAGE = "test.ping"; + // Not all hardware supports dozing. We should use Display.STATE_DOZE but + // for testing purposes it is convenient to use Display.STATE_ON so the + // test still works on hardware that does not support dozing. + private static final int DISPLAY_STATE_WHEN_DOZING = Display.STATE_ON; + private PowerManager mPowerManager; private PowerManager.WakeLock mWakeLock; private AlarmManager mAlarmManager; private PendingIntent mAlarmIntent; + private Handler mHandler = new Handler(); private TextView mAlarmClock; @@ -64,6 +72,8 @@ public class DozeTestDream extends DreamService { private boolean mDreaming; private DozeHardware mDozeHardware; + private long mLastTime = Long.MIN_VALUE; + @Override public void onCreate() { super.onCreate(); @@ -80,6 +90,8 @@ public class DozeTestDream extends DreamService { registerReceiver(mAlarmReceiver, filter); mAlarmIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); + + setDozeScreenState(DISPLAY_STATE_WHEN_DOZING); } @Override @@ -143,13 +155,33 @@ public class DozeTestDream extends DreamService { if (mDreaming) { long now = System.currentTimeMillis(); now -= now % 60000; // back up to last minute boundary + if (mLastTime == now) { + return; + } + mLastTime = now; mTime.setTime(now); mAlarmClock.setText(mTimeFormat.format(mTime)); mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, now + 60000, mAlarmIntent); - mWakeLock.acquire(UPDATE_TIME_TIMEOUT); + mWakeLock.acquire(UPDATE_TIME_TIMEOUT + 5000 /*for testing brightness*/); + + // flash the screen a bit to test these functions + setDozeScreenState(DISPLAY_STATE_WHEN_DOZING); + setDozeScreenBrightness(200); + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + setDozeScreenBrightness(50); + } + }, 2000); + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + setDozeScreenState(Display.STATE_OFF); + } + }, 5000); } } |