diff options
14 files changed, 308 insertions, 84 deletions
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java index 13ba6cc37d22..aea125835748 100644 --- a/core/java/android/hardware/display/DisplayManagerInternal.java +++ b/core/java/android/hardware/display/DisplayManagerInternal.java @@ -167,6 +167,8 @@ public abstract class DisplayManagerInternal { public static final int POLICY_DIM = 2; // Policy: Make the screen bright as usual. public static final int POLICY_BRIGHT = 3; + // Policy: Keep the screen and display optimized for VR mode. + public static final int POLICY_VR = 4; // The basic overall policy to apply: off, doze, dim or bright. public int policy; @@ -233,6 +235,10 @@ public abstract class DisplayManagerInternal { return policy == POLICY_BRIGHT || policy == POLICY_DIM; } + public boolean isVr() { + return policy == POLICY_VR; + } + public void copyFrom(DisplayPowerRequest other) { policy = other.policy; useProximitySensor = other.useProximitySensor; @@ -301,6 +307,8 @@ public abstract class DisplayManagerInternal { return "DIM"; case POLICY_BRIGHT: return "BRIGHT"; + case POLICY_VR: + return "VR"; default: return Integer.toString(policy); } diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 8d4d0a558334..f6804a8847a5 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -49,23 +49,23 @@ import android.util.Log; * <i>These levels are mutually exclusive - you may only specify one of them.</i> * * <table> - * <tr><th>Flag Value</th> + * <tr><th>Flag Value</th> * <th>CPU</th> <th>Screen</th> <th>Keyboard</th></tr> * * <tr><td>{@link #PARTIAL_WAKE_LOCK}</td> - * <td>On*</td> <td>Off</td> <td>Off</td> + * <td>On*</td> <td>Off</td> <td>Off</td> * </tr> - * + * * <tr><td>{@link #SCREEN_DIM_WAKE_LOCK}</td> - * <td>On</td> <td>Dim</td> <td>Off</td> + * <td>On</td> <td>Dim</td> <td>Off</td> * </tr> * * <tr><td>{@link #SCREEN_BRIGHT_WAKE_LOCK}</td> - * <td>On</td> <td>Bright</td> <td>Off</td> + * <td>On</td> <td>Bright</td> <td>Off</td> * </tr> - * + * * <tr><td>{@link #FULL_WAKE_LOCK}</td> - * <td>On</td> <td>Bright</td> <td>Bright</td> + * <td>On</td> <td>Bright</td> <td>Bright</td> * </tr> * </table> * </p><p> @@ -85,13 +85,13 @@ import android.util.Log; * the illumination to remain on once it turns on (e.g. from user activity). This flag * will force the screen and/or keyboard to turn on immediately, when the WakeLock is * acquired. A typical use would be for notifications which are important for the user to - * see immediately.</td> + * see immediately.</td> * </tr> - * + * * <tr><td>{@link #ON_AFTER_RELEASE}</td> * <td>If this flag is set, the user activity timer will be reset when the WakeLock is - * released, causing the illumination to remain on a bit longer. This can be used to - * reduce flicker if you are cycling between wake lock conditions.</td> + * released, causing the illumination to remain on a bit longer. This can be used to + * reduce flicker if you are cycling between wake lock conditions.</td> * </tr> * </table> * <p> @@ -473,6 +473,35 @@ public final class PowerManager { } /** + * Gets the minimum supported screen brightness setting for VR Mode. + * @hide + */ + public int getMinimumScreenBrightnessForVrSetting() { + return mContext.getResources().getInteger( + com.android.internal.R.integer.config_screenBrightnessForVrSettingMinimum); + } + + /** + * Gets the maximum supported screen brightness setting for VR Mode. + * 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 getMaximumScreenBrightnessForVrSetting() { + return mContext.getResources().getInteger( + com.android.internal.R.integer.config_screenBrightnessForVrSettingMaximum); + } + + /** + * Gets the default screen brightness for VR setting. + * @hide + */ + public int getDefaultScreenBrightnessForVrSetting() { + return mContext.getResources().getInteger( + com.android.internal.R.integer.config_screenBrightnessForVrSettingDefault); + } + + /** * Returns true if the twilight service should be used to adjust screen brightness * policy. This setting is experimental and disabled by default. * @hide diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index f796752ef450..066e0a26895a 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -2757,6 +2757,15 @@ public final class Settings { new InclusiveIntegerRangeValidator(0, 255); /** + * The screen backlight brightness between 0 and 255. + * @hide + */ + public static final String SCREEN_BRIGHTNESS_FOR_VR = "screen_brightness_for_vr"; + + private static final Validator SCREEN_BRIGHTNESS_FOR_VR_VALIDATOR = + new InclusiveIntegerRangeValidator(0, 255); + + /** * Control whether to enable automatic brightness mode. */ public static final String SCREEN_BRIGHTNESS_MODE = "screen_brightness_mode"; @@ -3750,6 +3759,7 @@ public final class Settings { VALIDATORS.put(DIM_SCREEN, DIM_SCREEN_VALIDATOR); VALIDATORS.put(SCREEN_OFF_TIMEOUT, SCREEN_OFF_TIMEOUT_VALIDATOR); VALIDATORS.put(SCREEN_BRIGHTNESS, SCREEN_BRIGHTNESS_VALIDATOR); + VALIDATORS.put(SCREEN_BRIGHTNESS_FOR_VR, SCREEN_BRIGHTNESS_FOR_VR_VALIDATOR); VALIDATORS.put(SCREEN_BRIGHTNESS_MODE, SCREEN_BRIGHTNESS_MODE_VALIDATOR); VALIDATORS.put(MODE_RINGER_STREAMS_AFFECTED, MODE_RINGER_STREAMS_AFFECTED_VALIDATOR); VALIDATORS.put(MUTE_STREAMS_AFFECTED, MUTE_STREAMS_AFFECTED_VALIDATOR); diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 85a4bf9d9e8f..e29155821eaa 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -284,6 +284,15 @@ public final class Display { */ public static final int STATE_DOZE_SUSPEND = 4; + /** + * Display state: The display is on and optimized for VR mode. + * + * @see #getState + * @see android.os.PowerManager#isInteractive + * @hide + */ + public static final int STATE_VR = 5; + /* The color mode constants defined below must be kept in sync with the ones in * system/graphics.h */ @@ -868,7 +877,8 @@ public final class Display { * Gets the state of the display, such as whether it is on or off. * * @return The state of the display: one of {@link #STATE_OFF}, {@link #STATE_ON}, - * {@link #STATE_DOZE}, {@link #STATE_DOZE_SUSPEND}, or {@link #STATE_UNKNOWN}. + * {@link #STATE_DOZE}, {@link #STATE_DOZE_SUSPEND}, or + * {@link #STATE_UNKNOWN}. */ public int getState() { synchronized (this) { @@ -984,6 +994,8 @@ public final class Display { return "DOZE"; case STATE_DOZE_SUSPEND: return "DOZE_SUSPEND"; + case STATE_VR: + return "VR"; default: return Integer.toString(state); } diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index ebfb837c5395..281203e7453c 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1043,6 +1043,16 @@ Must be in the range specified by minimum and maximum. --> <integer name="config_screenBrightnessSettingDefault">102</integer> + <!-- Default screen brightness for VR setting. --> + <integer name="config_screenBrightnessForVrSettingDefault">86</integer> + + <!-- Minimum screen brightness setting allowed for VR. Device panels start increasing pulse + width as brightness decreases below this theshold. --> + <integer name="config_screenBrightnessForVrSettingMinimum">79</integer> + + <!-- Maximum screen brightness setting allowed for VR. --> + <integer name="config_screenBrightnessForVrSettingMaximum">255</integer> + <!-- Screen brightness used to dim the screen while dozing in a very low power state. May be less than the minimum allowed brightness setting that can be set by the user. --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index d95f6e9e1a68..3eb2df0fe12d 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1776,6 +1776,9 @@ <java-symbol type="integer" name="config_screenBrightnessSettingMinimum" /> <java-symbol type="integer" name="config_screenBrightnessSettingMaximum" /> <java-symbol type="integer" name="config_screenBrightnessSettingDefault" /> + <java-symbol type="integer" name="config_screenBrightnessForVrSettingDefault" /> + <java-symbol type="integer" name="config_screenBrightnessForVrSettingMaximum" /> + <java-symbol type="integer" name="config_screenBrightnessForVrSettingMinimum" /> <java-symbol type="integer" name="config_screenBrightnessDark" /> <java-symbol type="integer" name="config_screenBrightnessDim" /> <java-symbol type="integer" name="config_screenBrightnessDoze" /> diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java index 1c6fffb6dde7..14c41616c8e5 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java +++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java @@ -30,6 +30,9 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; import android.provider.Settings; +import android.service.vr.IVrManager; +import android.service.vr.IVrStateCallbacks; +import android.util.Log; import android.widget.ImageView; import com.android.internal.logging.MetricsLogger; @@ -52,9 +55,12 @@ public class BrightnessController implements ToggleSlider.Listener { private static final int MSG_SET_CHECKED = 2; private static final int MSG_ATTACH_LISTENER = 3; private static final int MSG_DETACH_LISTENER = 4; + private static final int MSG_VR_MODE_CHANGED = 5; private final int mMinimumBacklight; private final int mMaximumBacklight; + private final int mMinimumBacklightForVr; + private final int mMaximumBacklightForVr; private final Context mContext; private final ImageView mIcon; @@ -62,6 +68,7 @@ public class BrightnessController implements ToggleSlider.Listener { private final boolean mAutomaticAvailable; private final IPowerManager mPower; private final CurrentUserTracker mUserTracker; + private final IVrManager mVrManager; private Handler mBackgroundHandler; private final BrightnessObserver mBrightnessObserver; @@ -69,7 +76,8 @@ public class BrightnessController implements ToggleSlider.Listener { private ArrayList<BrightnessStateChangeCallback> mChangeCallbacks = new ArrayList<BrightnessStateChangeCallback>(); - private volatile boolean mAutomatic; + private volatile boolean mAutomatic; // Brightness adjusted automatically using ambient light. + private volatile boolean mIsVrModeEnabled; private boolean mListening; private boolean mExternalChange; @@ -84,6 +92,8 @@ public class BrightnessController implements ToggleSlider.Listener { Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE); private final Uri BRIGHTNESS_URI = Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS); + private final Uri BRIGHTNESS_FOR_VR_URI = + Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FOR_VR); private final Uri BRIGHTNESS_ADJ_URI = Settings.System.getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ); @@ -105,6 +115,8 @@ public class BrightnessController implements ToggleSlider.Listener { mBackgroundHandler.post(mUpdateSliderRunnable); } else if (BRIGHTNESS_URI.equals(uri) && !mAutomatic) { mBackgroundHandler.post(mUpdateSliderRunnable); + } else if (BRIGHTNESS_FOR_VR_URI.equals(uri)) { + mBackgroundHandler.post(mUpdateSliderRunnable); } else if (BRIGHTNESS_ADJ_URI.equals(uri) && mAutomatic) { mBackgroundHandler.post(mUpdateSliderRunnable); } else { @@ -126,6 +138,9 @@ public class BrightnessController implements ToggleSlider.Listener { BRIGHTNESS_URI, false, this, UserHandle.USER_ALL); cr.registerContentObserver( + BRIGHTNESS_FOR_VR_URI, + false, this, UserHandle.USER_ALL); + cr.registerContentObserver( BRIGHTNESS_ADJ_URI, false, this, UserHandle.USER_ALL); } @@ -191,7 +206,14 @@ public class BrightnessController implements ToggleSlider.Listener { private final Runnable mUpdateSliderRunnable = new Runnable() { @Override public void run() { - if (mAutomatic) { + if (mIsVrModeEnabled) { + int value = Settings.System.getIntForUser(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_FOR_VR, mMaximumBacklight, + UserHandle.USER_CURRENT); + mHandler.obtainMessage(MSG_UPDATE_SLIDER, + mMaximumBacklightForVr - mMinimumBacklightForVr, + value - mMinimumBacklightForVr).sendToTarget(); + } else if (mAutomatic) { float value = Settings.System.getFloatForUser(mContext.getContentResolver(), Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0, UserHandle.USER_CURRENT); @@ -208,6 +230,14 @@ public class BrightnessController implements ToggleSlider.Listener { } }; + private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() { + @Override + public void onVrStateChanged(boolean enabled) { + mHandler.obtainMessage(MSG_VR_MODE_CHANGED, enabled ? 1 : 0, 0) + .sendToTarget(); + } + }; + private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { @@ -229,6 +259,10 @@ public class BrightnessController implements ToggleSlider.Listener { break; case MSG_DETACH_LISTENER: mControl.setOnChangedListener(null); + break; + case MSG_VR_MODE_CHANGED: + updateVrMode(msg.arg1 != 0); + break; default: super.handleMessage(msg); } @@ -255,10 +289,13 @@ public class BrightnessController implements ToggleSlider.Listener { PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); mMinimumBacklight = pm.getMinimumScreenBrightnessSetting(); mMaximumBacklight = pm.getMaximumScreenBrightnessSetting(); + mMinimumBacklightForVr = pm.getMinimumScreenBrightnessForVrSetting(); + mMaximumBacklightForVr = pm.getMaximumScreenBrightnessForVrSetting(); mAutomaticAvailable = context.getResources().getBoolean( com.android.internal.R.bool.config_automatic_brightness_available); mPower = IPowerManager.Stub.asInterface(ServiceManager.getService("power")); + mVrManager = IVrManager.Stub.asInterface(ServiceManager.getService("vrmanager")); } public void setBackgroundLooper(Looper backgroundLooper) { @@ -283,6 +320,15 @@ public class BrightnessController implements ToggleSlider.Listener { return; } + if (mVrManager != null) { + try { + mVrManager.registerListener(mVrStateCallbacks); + mIsVrModeEnabled = mVrManager.getVrModeState(); + } catch (RemoteException e) { + Log.e(TAG, "Failed to register VR mode state listener: ", e); + } + } + mBackgroundHandler.post(mStartListeningRunnable); mListening = true; } @@ -293,6 +339,14 @@ public class BrightnessController implements ToggleSlider.Listener { return; } + if (mVrManager != null) { + try { + mVrManager.unregisterListener(mVrStateCallbacks); + } catch (RemoteException e) { + Log.e(TAG, "Failed to unregister VR mode state listener: ", e); + } + } + mBackgroundHandler.post(mStopListeningRunnable); mListening = false; } @@ -303,7 +357,22 @@ public class BrightnessController implements ToggleSlider.Listener { updateIcon(mAutomatic); if (mExternalChange) return; - if (!mAutomatic) { + if (mIsVrModeEnabled) { + final int val = value + mMinimumBacklightForVr; + if (stopTracking) { + MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS_FOR_VR, val); + } + setBrightness(val); + if (!tracking) { + AsyncTask.execute(new Runnable() { + public void run() { + Settings.System.putIntForUser(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_FOR_VR, val, + UserHandle.USER_CURRENT); + } + }); + } + } else if (!mAutomatic) { final int val = value + mMinimumBacklight; if (stopTracking) { MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS, val); @@ -367,4 +436,11 @@ public class BrightnessController implements ToggleSlider.Listener { com.android.systemui.R.drawable.ic_qs_brightness_auto_off); } } + + private void updateVrMode(boolean isEnabled) { + if (mIsVrModeEnabled != isEnabled) { + mIsVrModeEnabled = isEnabled; + mBackgroundHandler.post(mUpdateSliderRunnable); + } + } } diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index 20cca8e6d371..ff3a9c5fa7b9 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -2219,6 +2219,12 @@ message MetricsEvent { // OS: N-MR2 ACTION_LOCK_BECAUSE_SIM_REMOVED = 497; + // ACTION: QS Brightness Slider (with auto brightness disabled, and VR enabled) + // SUBTYPE: slider value + // CATEGORY: QUICK_SETTINGS + // OS: 6.0 + ACTION_BRIGHTNESS_FOR_VR = 498; + // ACTION: A captive portal was detected during network validation // CATEGORY: NOTIFICATION // OS: N-MR2 diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index de5bffda424f..5087ecdb3489 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -589,6 +589,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call brightness = mPowerRequest.dozeScreenBrightness; } break; + case DisplayPowerRequest.POLICY_VR: + state = Display.STATE_VR; + break; case DisplayPowerRequest.POLICY_DIM: case DisplayPowerRequest.POLICY_BRIGHT: default: @@ -630,6 +633,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // Animate the screen state change unless already animating. // The transition may be deferred, so after this point we will use the // actual state instead of the desired one. + final int oldState = mPowerState.getScreenState(); animateScreenStateChange(state, performScreenOffTransition); state = mPowerState.getScreenState(); @@ -732,9 +736,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } // Animate the screen brightness when the screen is on or dozing. - // Skip the animation when the screen is off or suspended. + // Skip the animation when the screen is off or suspended or transition to/from VR. if (!mPendingScreenOff) { - if (state == Display.STATE_ON || state == Display.STATE_DOZE) { + boolean wasOrWillBeInVr = (state == Display.STATE_VR || oldState == Display.STATE_VR); + if ((state == Display.STATE_ON || state == Display.STATE_DOZE) && !wasOrWillBeInVr) { animateScreenBrightness(brightness, slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast); } else { @@ -918,6 +923,23 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mPowerState.setColorFadeLevel(1.0f); mPowerState.dismissColorFade(); } + } else if (target == Display.STATE_VR) { + // Wait for brightness animation to complete beforehand when entering VR + // from screen on to prevent a perceptible jump because brightness may operate + // differently when the display is configured for dozing. + if (mScreenBrightnessRampAnimator.isAnimating() + && mPowerState.getScreenState() == Display.STATE_ON) { + return; + } + + // Set screen state. + if (!setScreenState(Display.STATE_VR)) { + return; // screen on blocked + } + + // Dismiss the black surface without fanfare. + mPowerState.setColorFadeLevel(1.0f); + mPowerState.dismissColorFade(); } else if (target == Display.STATE_DOZE) { // Want screen dozing. // Wait for brightness animation to complete beforehand when entering doze diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index 61c2eacaa8f9..867322578a66 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -471,6 +471,16 @@ final class LocalDisplayAdapter extends DisplayAdapter { } } + // If the state change was from or to VR, then we need to tell the light + // so that it can apply appropriate VR brightness settings. This should + // happen prior to changing the brightness but also if there is no + // brightness change at all. + if ((state == Display.STATE_VR || currentState == Display.STATE_VR) && + currentState != state) { + setVrMode(state == Display.STATE_VR); + } + + // Apply brightness changes given that we are in a non-suspended state. if (brightnessChanged) { setDisplayBrightness(brightness); @@ -482,6 +492,15 @@ final class LocalDisplayAdapter extends DisplayAdapter { } } + private void setVrMode(boolean isVrEnabled) { + if (DEBUG) { + Slog.d(TAG, "setVrMode(" + + "id=" + displayId + + ", state=" + Display.stateToString(state) + ")"); + } + mBacklight.setVrMode(isVrEnabled); + } + private void setDisplayState(int state) { if (DEBUG) { Slog.d(TAG, "setDisplayState(" diff --git a/services/core/java/com/android/server/lights/Light.java b/services/core/java/com/android/server/lights/Light.java index b18a18129248..6d0a51040c73 100644 --- a/services/core/java/com/android/server/lights/Light.java +++ b/services/core/java/com/android/server/lights/Light.java @@ -43,4 +43,5 @@ public abstract class Light { public abstract void pulse(); public abstract void pulse(int color, int onMS); public abstract void turnOff(); + public abstract void setVrMode(boolean enabled); } diff --git a/services/core/java/com/android/server/lights/LightsService.java b/services/core/java/com/android/server/lights/LightsService.java index ca6481792dfe..eead11464d64 100644 --- a/services/core/java/com/android/server/lights/LightsService.java +++ b/services/core/java/com/android/server/lights/LightsService.java @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2008 The Android Open Source Project +/* * Copyright (C) 2008 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. @@ -17,18 +16,13 @@ package com.android.server.lights; import com.android.server.SystemService; -import com.android.server.vr.VrManagerService; import android.app.ActivityManager; import android.content.Context; import android.os.Handler; import android.os.Message; -import android.os.RemoteException; import android.os.Trace; -import android.os.UserHandle; import android.provider.Settings; -import android.service.vr.IVrManager; -import android.service.vr.IVrStateCallbacks; import android.util.Slog; public class LightsService extends SystemService { @@ -36,7 +30,6 @@ public class LightsService extends SystemService { static final boolean DEBUG = false; final LightImpl mLights[] = new LightImpl[LightsManager.LIGHT_ID_COUNT]; - private boolean mVrModeEnabled; private final class LightImpl extends Light { @@ -52,6 +45,13 @@ public class LightsService extends SystemService { @Override public void setBrightness(int brightness, int brightnessMode) { synchronized (this) { + // LOW_PERSISTENCE cannot be manually set + if (brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE) { + Slog.w(TAG, "setBrightness with LOW_PERSISTENCE unexpected #" + mId + + ": brightness=0x" + Integer.toHexString(brightness)); + return; + } + int color = brightness & 0x000000ff; color = 0xff000000 | (color << 16) | (color << 8) | color; setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode); @@ -80,11 +80,9 @@ public class LightsService extends SystemService { @Override public void pulse(int color, int onMS) { synchronized (this) { - if (mBrightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE) { - return; - } if (mColor == 0 && !mFlashing) { - setLightLocked(color, LIGHT_FLASH_HARDWARE, onMS, 1000, BRIGHTNESS_MODE_USER); + setLightLocked(color, LIGHT_FLASH_HARDWARE, onMS, 1000, + BRIGHTNESS_MODE_USER); mColor = 0; mH.sendMessageDelayed(Message.obtain(mH, 1, this), onMS); } @@ -98,17 +96,23 @@ public class LightsService extends SystemService { } } - void enableLowPersistence() { - synchronized(this) { - setLightLocked(0, LIGHT_FLASH_NONE, 0, 0, BRIGHTNESS_MODE_LOW_PERSISTENCE); - mLocked = true; - } - } - - void disableLowPersistence() { - synchronized(this) { - mLocked = false; - setLightLocked(mLastColor, LIGHT_FLASH_NONE, 0, 0, mLastBrightnessMode); + @Override + public void setVrMode(boolean enabled) { + synchronized (this) { + if (mVrModeEnabled != enabled) { + mVrModeEnabled = enabled; + + mUseLowPersistenceForVR = + (getVrDisplayMode() == Settings.Secure.VR_DISPLAY_MODE_LOW_PERSISTENCE); + if (shouldBeInLowPersistenceMode()) { + mLastBrightnessMode = mBrightnessMode; + } + + // NOTE: We do not trigger a call to setLightLocked here. We do not know the + // current brightness or other values when leaving VR so we avoid any incorrect + // jumps. The code that calls this method will immediately issue a brightness + // update which is when the change will occur. + } } } @@ -119,7 +123,13 @@ public class LightsService extends SystemService { } private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) { - if (!mLocked && (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS || + if (shouldBeInLowPersistenceMode()) { + brightnessMode = BRIGHTNESS_MODE_LOW_PERSISTENCE; + } else if (brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE) { + brightnessMode = mLastBrightnessMode; + } + + if ((color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS || mBrightnessMode != brightnessMode)) { if (DEBUG) Slog.v(TAG, "setLight #" + mId + ": color=#" + Integer.toHexString(color) + ": brightnessMode=" + brightnessMode); @@ -128,7 +138,6 @@ public class LightsService extends SystemService { mMode = mode; mOnMS = onMS; mOffMS = offMS; - mLastBrightnessMode = mBrightnessMode; mBrightnessMode = brightnessMode; Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLight(" + mId + ", 0x" + Integer.toHexString(color) + ")"); @@ -140,6 +149,10 @@ public class LightsService extends SystemService { } } + private boolean shouldBeInLowPersistenceMode() { + return mVrModeEnabled && mUseLowPersistenceForVR; + } + private int mId; private int mColor; private int mMode; @@ -149,7 +162,8 @@ public class LightsService extends SystemService { private int mBrightnessMode; private int mLastBrightnessMode; private int mLastColor; - private boolean mLocked; + private boolean mVrModeEnabled; + private boolean mUseLowPersistenceForVR; } public LightsService(Context context) { @@ -169,17 +183,6 @@ public class LightsService extends SystemService { @Override public void onBootPhase(int phase) { - if (phase == PHASE_SYSTEM_SERVICES_READY) { - IVrManager vrManager = - (IVrManager) getBinderService(VrManagerService.VR_MANAGER_BINDER_SERVICE); - if (vrManager != null) { - try { - vrManager.registerListener(mVrStateCallbacks); - } catch (RemoteException e) { - Slog.e(TAG, "Failed to register VR mode state listener: " + e); - } - } - } } private int getVrDisplayMode() { @@ -190,30 +193,6 @@ public class LightsService extends SystemService { currentUser); } - private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() { - @Override - public void onVrStateChanged(boolean enabled) throws RemoteException { - LightImpl l = mLights[LightsManager.LIGHT_ID_BACKLIGHT]; - int vrDisplayMode = getVrDisplayMode(); - - // User leaves VR mode before altering display settings. - if (enabled && vrDisplayMode == Settings.Secure.VR_DISPLAY_MODE_LOW_PERSISTENCE) { - if (!mVrModeEnabled) { - if (DEBUG) - Slog.v(TAG, "VR mode enabled, setting brightness to low persistence"); - l.enableLowPersistence(); - mVrModeEnabled = true; - } - } else { - if (mVrModeEnabled) { - if (DEBUG) Slog.v(TAG, "VR mode disabled, resetting brightnes"); - l.disableLowPersistence(); - mVrModeEnabled = false; - } - } - } - }; - private final LightsManager mService = new LightsManager() { @Override public Light getLight(int id) { diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 554696d666c5..3f421ea20289 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -134,6 +134,8 @@ public final class PowerManagerService extends SystemService private static final int DIRTY_DOCK_STATE = 1 << 10; // Dirty bit: brightness boost changed private static final int DIRTY_SCREEN_BRIGHTNESS_BOOST = 1 << 11; + // Dirty bit: VR Mode enabled changed + private static final int DIRTY_VR_MODE_CHANGED = 1 << 12; // Summarizes the state of all active wakelocks. private static final int WAKE_LOCK_CPU = 1 << 0; @@ -409,11 +411,15 @@ public final class PowerManagerService extends SystemService private int mScreenBrightnessSettingMinimum; private int mScreenBrightnessSettingMaximum; private int mScreenBrightnessSettingDefault; + private int mScreenBrightnessForVrSettingDefault; // The screen brightness setting, from 0 to 255. // Use -1 if no value has been set. private int mScreenBrightnessSetting; + // The screen brightness setting, from 0 to 255, to be used while in VR Mode. + private int mScreenBrightnessForVrSetting; + // The screen auto-brightness adjustment setting, from -1 to 1. // Use 0 if there is no adjustment. private float mScreenAutoBrightnessAdjustmentSetting; @@ -501,6 +507,9 @@ public final class PowerManagerService extends SystemService // True if brightness should be affected by twilight. private boolean mBrightnessUseTwilight; + // True if we are currently in VR Mode. + private boolean mIsVrModeEnabled; + private native void nativeInit(); private static native void nativeAcquireSuspendBlocker(String name); @@ -582,6 +591,7 @@ public final class PowerManagerService extends SystemService mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting(); mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting(); mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting(); + mScreenBrightnessForVrSettingDefault = pm.getDefaultScreenBrightnessForVrSetting(); SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper()); @@ -647,6 +657,9 @@ public final class PowerManagerService extends SystemService Settings.System.SCREEN_BRIGHTNESS), false, mSettingsObserver, UserHandle.USER_ALL); resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.SCREEN_BRIGHTNESS_FOR_VR), + false, mSettingsObserver, UserHandle.USER_ALL); + resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.SCREEN_BRIGHTNESS_MODE), false, mSettingsObserver, UserHandle.USER_ALL); resolver.registerContentObserver(Settings.System.getUriFor( @@ -761,11 +774,17 @@ public final class PowerManagerService extends SystemService } } - final int oldScreenBrightnessSetting = mScreenBrightnessSetting; + final int oldScreenBrightnessSetting = getCurrentBrightnessSettingLocked(); + + mScreenBrightnessForVrSetting = Settings.System.getIntForUser(resolver, + Settings.System.SCREEN_BRIGHTNESS_FOR_VR, mScreenBrightnessForVrSettingDefault, + UserHandle.USER_CURRENT); + mScreenBrightnessSetting = Settings.System.getIntForUser(resolver, Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessSettingDefault, UserHandle.USER_CURRENT); - if (oldScreenBrightnessSetting != mScreenBrightnessSetting) { + + if (oldScreenBrightnessSetting != getCurrentBrightnessSettingLocked()) { mTemporaryScreenBrightnessSettingOverride = -1; } @@ -799,6 +818,10 @@ public final class PowerManagerService extends SystemService mDirty |= DIRTY_SETTINGS; } + private int getCurrentBrightnessSettingLocked() { + return mIsVrModeEnabled ? mScreenBrightnessForVrSetting : mScreenBrightnessSetting; + } + private void postAfterBootCompleted(Runnable r) { if (mBootCompleted) { BackgroundThread.getHandler().post(r); @@ -2035,6 +2058,7 @@ public final class PowerManagerService extends SystemService || !mDreamsSupportedConfig || !mDreamsEnabledSetting || !mDisplayPowerRequest.isBrightOrDim() + || !mDisplayPowerRequest.isVr() || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM | USER_ACTIVITY_SCREEN_DREAM)) == 0 || !mBootCompleted) { @@ -2079,7 +2103,7 @@ public final class PowerManagerService extends SystemService final boolean oldDisplayReady = mDisplayReady; if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED - | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST)) != 0) { + | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST | DIRTY_VR_MODE_CHANGED)) != 0) { mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked(); // Determine appropriate screen brightness and auto-brightness adjustments. @@ -2093,6 +2117,9 @@ public final class PowerManagerService extends SystemService // bootloader brightness and the default brightness to be identical. autoBrightness = false; brightnessSetByUser = false; + } else if (mIsVrModeEnabled) { + screenBrightness = mScreenBrightnessForVrSetting; + autoBrightness = false; } else if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) { screenBrightness = mScreenBrightnessOverrideFromWindowManager; autoBrightness = false; @@ -2126,7 +2153,7 @@ public final class PowerManagerService extends SystemService mDisplayPowerRequest.useAutoBrightness = autoBrightness; mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked(); mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled; - mDisplayPowerRequest.boostScreenBrightness = mScreenBrightnessBoostInProgress; + mDisplayPowerRequest.boostScreenBrightness = shouldBoostScreenBrightness(); mDisplayPowerRequest.useTwilight = mBrightnessUseTwilight; if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) { @@ -2153,6 +2180,7 @@ public final class PowerManagerService extends SystemService + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary) + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary) + ", mBootCompleted=" + mBootCompleted + + ", mIsVrModeEnabled= " + mIsVrModeEnabled + ", mScreenBrightnessBoostInProgress=" + mScreenBrightnessBoostInProgress); } @@ -2183,6 +2211,10 @@ public final class PowerManagerService extends SystemService } } + private boolean shouldBoostScreenBrightness() { + return !mIsVrModeEnabled && mScreenBrightnessBoostInProgress; + } + private static boolean isValidBrightness(int value) { return value >= 0 && value <= 255; } @@ -2193,6 +2225,10 @@ public final class PowerManagerService extends SystemService } private int getDesiredScreenPolicyLocked() { + if (mIsVrModeEnabled) { + return DisplayPowerRequest.POLICY_VR; + } + if (mWakefulness == WAKEFULNESS_ASLEEP) { return DisplayPowerRequest.POLICY_OFF; } @@ -2296,7 +2332,7 @@ public final class PowerManagerService extends SystemService }; private boolean shouldUseProximitySensorLocked() { - return (mWakeLockSummary & WAKE_LOCK_PROXIMITY_SCREEN_OFF) != 0; + return !mIsVrModeEnabled && (mWakeLockSummary & WAKE_LOCK_PROXIMITY_SCREEN_OFF) != 0; } /** @@ -2956,7 +2992,11 @@ public final class PowerManagerService extends SystemService pw.println(" mScreenBrightnessSettingMinimum=" + mScreenBrightnessSettingMinimum); pw.println(" mScreenBrightnessSettingMaximum=" + mScreenBrightnessSettingMaximum); pw.println(" mScreenBrightnessSettingDefault=" + mScreenBrightnessSettingDefault); + pw.println(" mScreenBrightnessForVrSettingDefault=" + + mScreenBrightnessForVrSettingDefault); + pw.println(" mScreenBrightnessForVrSetting=" + mScreenBrightnessForVrSetting); pw.println(" mDoubleTapWakeEnabled=" + mDoubleTapWakeEnabled); + pw.println(" mIsVrModeEnabled=" + mIsVrModeEnabled); final int sleepTimeout = getSleepTimeoutLocked(); final int screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout); @@ -3083,6 +3123,14 @@ public final class PowerManagerService extends SystemService @Override public void onVrStateChanged(boolean enabled) { powerHintInternal(POWER_HINT_VR_MODE, enabled ? 1 : 0); + + synchronized (mLock) { + if (mIsVrModeEnabled != enabled) { + mIsVrModeEnabled = enabled; + mDirty |= DIRTY_VR_MODE_CHANGED; + updatePowerStateLocked(); + } + } } }; @@ -3821,6 +3869,7 @@ public final class PowerManagerService extends SystemService case Display.STATE_DOZE: case Display.STATE_DOZE_SUSPEND: case Display.STATE_ON: + case Display.STATE_VR: break; default: screenState = Display.STATE_UNKNOWN; diff --git a/services/core/jni/com_android_server_lights_LightsService.cpp b/services/core/jni/com_android_server_lights_LightsService.cpp index c8e3946970e9..bf91fe3fd0b4 100644 --- a/services/core/jni/com_android_server_lights_LightsService.cpp +++ b/services/core/jni/com_android_server_lights_LightsService.cpp @@ -128,12 +128,12 @@ static void setLight_native(JNIEnv* /* env */, jobject /* clazz */, jlong ptr, } } else { // Only set non-brightness settings when not in low-persistence mode - state.color = colorARGB; state.flashMode = flashMode; state.flashOnMS = onMS; state.flashOffMS = offMS; } + state.color = colorARGB; state.brightnessMode = brightnessMode; { |