summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-10-27 03:23:07 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-10-27 03:23:07 +0000
commit485f313c6e57f5fdc8d4b04194043f03ee36def1 (patch)
tree5280cb8796b3e0e0a53b464316cfbbdcda1ad807
parent6b5e5773b793e4419d28609c4b08da0240109e2d (diff)
parent297e118dcc9c0d5f59230026b16c87bfd5870d61 (diff)
downloadbase-oreo-dr3-release.tar.gz
Merge cherrypicks of [3131626, 3131642, 3132434, 3132437, 3132440, 3132443, 3132445, 3132448, 3132494, 3132495, 3132496, 3132498, 3132500, 3132034] into oc-dr3-releaseandroid-8.0.0_r34oreo-dr3-release
Change-Id: I0a2caaa19a99cc28c087a022f4815ce0e0404062
-rwxr-xr-xcore/java/android/provider/Settings.java6
-rw-r--r--core/java/com/android/internal/app/NightDisplayController.java64
-rw-r--r--core/res/res/values/config.xml24
-rw-r--r--core/res/res/values/symbols.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/Dependency.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java48
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java71
-rw-r--r--proto/src/metrics_constants.proto5
-rw-r--r--services/core/java/com/android/server/display/DisplayTransformManager.java92
-rw-r--r--services/core/java/com/android/server/display/NightDisplayService.java50
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java3
14 files changed, 377 insertions, 37 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 2d8ed7adab55..49e30375ca62 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3047,6 +3047,12 @@ public final class Settings {
private static final Validator DIM_SCREEN_VALIDATOR = sBooleanValidator;
/**
+ * The display color mode.
+ * @hide
+ */
+ public static final String DISPLAY_COLOR_MODE = "display_color_mode";
+
+ /**
* The amount of time in milliseconds before the device goes to sleep or begins
* to dream after a period of inactivity. This value is also known as the
* user activity timeout period since the screen isn't necessarily turned off
diff --git a/core/java/com/android/internal/app/NightDisplayController.java b/core/java/com/android/internal/app/NightDisplayController.java
index 860c5c4c3d3b..78a8b17ee5fa 100644
--- a/core/java/com/android/internal/app/NightDisplayController.java
+++ b/core/java/com/android/internal/app/NightDisplayController.java
@@ -26,6 +26,7 @@ import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings.Secure;
+import android.provider.Settings.System;
import android.util.Slog;
import com.android.internal.R;
@@ -50,6 +51,10 @@ public final class NightDisplayController {
@IntDef({ AUTO_MODE_DISABLED, AUTO_MODE_CUSTOM, AUTO_MODE_TWILIGHT })
public @interface AutoMode {}
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({ COLOR_MODE_NATURAL, COLOR_MODE_BOOSTED, COLOR_MODE_SATURATED })
+ public @interface ColorMode {}
+
/**
* Auto mode value to prevent Night display from being automatically activated. It can still
* be activated manually via {@link #setActivated(boolean)}.
@@ -72,6 +77,25 @@ public final class NightDisplayController {
*/
public static final int AUTO_MODE_TWILIGHT = 2;
+ /**
+ * Color mode with natural colors.
+ *
+ * @see #setColorMode(int)
+ */
+ public static final int COLOR_MODE_NATURAL = 0;
+ /**
+ * Color mode with boosted colors.
+ *
+ * @see #setColorMode(int)
+ */
+ public static final int COLOR_MODE_BOOSTED = 1;
+ /**
+ * Color mode with saturated colors.
+ *
+ * @see #setColorMode(int)
+ */
+ public static final int COLOR_MODE_SATURATED = 2;
+
private final Context mContext;
private final int mUserId;
@@ -117,7 +141,8 @@ public final class NightDisplayController {
public boolean setActivated(boolean activated) {
if (isActivated() != activated) {
Secure.putLongForUser(mContext.getContentResolver(),
- Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, System.currentTimeMillis(),
+ Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
+ java.lang.System.currentTimeMillis(),
mUserId);
}
return Secure.putIntForUser(mContext.getContentResolver(),
@@ -294,6 +319,31 @@ public final class NightDisplayController {
}
/**
+ * Get the current color mode.
+ */
+ public int getColorMode() {
+ final int colorMode = System.getIntForUser(mContext.getContentResolver(),
+ System.DISPLAY_COLOR_MODE, COLOR_MODE_BOOSTED, mUserId);
+ if (colorMode < COLOR_MODE_NATURAL || colorMode > COLOR_MODE_SATURATED) {
+ return COLOR_MODE_BOOSTED;
+ }
+ return colorMode;
+ }
+
+ /**
+ * Set the current color mode.
+ *
+ * @param colorMode the color mode
+ */
+ public void setColorMode(@ColorMode int colorMode) {
+ if (colorMode < COLOR_MODE_NATURAL || colorMode > COLOR_MODE_SATURATED) {
+ return;
+ }
+ System.putIntForUser(mContext.getContentResolver(), System.DISPLAY_COLOR_MODE, colorMode,
+ mUserId);
+ }
+
+ /**
* Returns the minimum allowed color temperature (in Kelvin) to tint the display when activated.
*/
public int getMinimumColorTemperature() {
@@ -339,6 +389,9 @@ public final class NightDisplayController {
case Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE:
mCallback.onColorTemperatureChanged(getColorTemperature());
break;
+ case System.DISPLAY_COLOR_MODE:
+ mCallback.onDisplayColorModeChanged(getColorMode());
+ break;
}
}
}
@@ -367,6 +420,8 @@ public final class NightDisplayController {
false /* notifyForDescendants */, mContentObserver, mUserId);
cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE),
false /* notifyForDescendants */, mContentObserver, mUserId);
+ cr.registerContentObserver(System.getUriFor(System.DISPLAY_COLOR_MODE),
+ false /* notifyForDecendants */, mContentObserver, mUserId);
}
}
}
@@ -513,5 +568,12 @@ public final class NightDisplayController {
* @param colorTemperature the color temperature to tint the screen
*/
default void onColorTemperatureChanged(int colorTemperature) {}
+
+ /**
+ * Callback invoked when the color mode changes.
+ *
+ * @param displayColorMode the color mode
+ */
+ default void onDisplayColorModeChanged(int displayColorMode) {}
}
}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d1b3fec451db..bffab8bf2ca2 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -844,6 +844,30 @@
<!-- Maximum color temperature, in Kelvin, supported by Night display. -->
<integer name="config_nightDisplayColorTemperatureMax">4082</integer>
+ <string-array name="config_nightDisplayColorTemperatureCoefficientsNative">
+ <!-- R a-coefficient --> <item>0.0</item>
+ <!-- R b-coefficient --> <item>0.0</item>
+ <!-- R y-intercept --> <item>1.0</item>
+ <!-- G a-coefficient --> <item>-0.00000000962353339</item>
+ <!-- G b-coefficient --> <item>0.000153045476</item>
+ <!-- G y-intercept --> <item>0.390782778</item>
+ <!-- B a-coefficient --> <item>-0.0000000189359041</item>
+ <!-- B b-coefficient --> <item>0.000302412211</item>
+ <!-- B y-intercept --> <item>-0.198650895</item>
+ </string-array>
+
+ <string-array name="config_nightDisplayColorTemperatureCoefficients">
+ <!-- R a-coefficient --> <item>0.0</item>
+ <!-- R b-coefficient --> <item>0.0</item>
+ <!-- R y-intercept --> <item>1.0</item>
+ <!-- G a-coefficient --> <item>-0.00000000962353339</item>
+ <!-- G b-coefficient --> <item>0.000153045476</item>
+ <!-- G y-intercept --> <item>0.390782778</item>
+ <!-- B a-coefficient --> <item>-0.0000000189359041</item>
+ <!-- B b-coefficient --> <item>0.000302412211</item>
+ <!-- B y-intercept --> <item>-0.198650895</item>
+ </string-array>
+
<!-- Indicate whether to allow the device to suspend when the screen is off
due to the proximity sensor. This resource should only be set to true
if the sensor HAL correctly handles the proximity sensor as a wake-up source.
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 975737b71220..6209830b4ed1 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2815,6 +2815,8 @@
<java-symbol type="integer" name="config_nightDisplayColorTemperatureDefault" />
<java-symbol type="integer" name="config_nightDisplayColorTemperatureMin" />
<java-symbol type="integer" name="config_nightDisplayColorTemperatureMax" />
+ <java-symbol type="array" name="config_nightDisplayColorTemperatureCoefficients" />
+ <java-symbol type="array" name="config_nightDisplayColorTemperatureCoefficientsNative" />
<!-- Default first user restrictions -->
<java-symbol type="array" name="config_defaultFirstUserRestrictions" />
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index ecc211136667..c2467c630017 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -22,6 +22,8 @@ import android.os.HandlerThread;
import android.os.Looper;
import android.os.Process;
import android.util.ArrayMap;
+import android.view.IWindowManager;
+import android.view.WindowManagerGlobal;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.NightDisplayController;
@@ -300,6 +302,8 @@ public class Dependency extends SystemUI {
mProviders.put(PowerUI.WarningsUI.class, () -> new PowerNotificationWarnings(mContext));
+ mProviders.put(IWindowManager.class, () -> WindowManagerGlobal.getWindowManagerService());
+
// Put all dependencies above here so the factory can override them if it wants.
SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
index f3c2bc56b409..3daaf59a3817 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
@@ -52,7 +52,7 @@ public class BarTransitions {
public static final int MODE_LIGHTS_OUT_TRANSPARENT = 6;
public static final int LIGHTS_IN_DURATION = 250;
- public static final int LIGHTS_OUT_DURATION = 750;
+ public static final int LIGHTS_OUT_DURATION = 1500;
public static final int BACKGROUND_DURATION = 200;
private final String mTag;
@@ -75,6 +75,10 @@ public class BarTransitions {
return mMode;
}
+ public void setAutoDim(boolean autoDim) {
+ // Default is don't care.
+ }
+
/**
* @param alwaysOpaque if {@code true}, the bar's background will always be opaque, regardless
* of what mode it is currently set to.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
index cb925d5f7e16..c9500363e9d8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
@@ -17,12 +17,19 @@
package com.android.systemui.statusbar.phone;
import android.content.Context;
+import android.os.Handler;
+import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.SparseArray;
+import android.view.Display;
+import android.view.IWallpaperVisibilityListener;
+import android.view.IWindowManager;
import android.view.MotionEvent;
import android.view.View;
+import android.view.WindowManagerGlobal;
import com.android.internal.statusbar.IStatusBarService;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
public final class NavigationBarTransitions extends BarTransitions {
@@ -30,8 +37,10 @@ public final class NavigationBarTransitions extends BarTransitions {
private final NavigationBarView mView;
private final IStatusBarService mBarService;
private final LightBarTransitionsController mLightTransitionsController;
+ private boolean mWallpaperVisible;
private boolean mLightsOut;
+ private boolean mAutoDim;
public NavigationBarTransitions(NavigationBarView view) {
super(view, R.drawable.nav_background);
@@ -40,11 +49,38 @@ public final class NavigationBarTransitions extends BarTransitions {
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
mLightTransitionsController = new LightBarTransitionsController(view.getContext(),
this::applyDarkIntensity);
+
+ IWindowManager windowManagerService = Dependency.get(IWindowManager.class);
+ Handler handler = Handler.getMain();
+ try {
+ mWallpaperVisible = windowManagerService.registerWallpaperVisibilityListener(
+ new IWallpaperVisibilityListener.Stub() {
+ @Override
+ public void onWallpaperVisibilityChanged(boolean newVisibility,
+ int displayId) throws RemoteException {
+ mWallpaperVisible = newVisibility;
+ handler.post(() -> applyLightsOut(true, false));
+ }
+ }, Display.DEFAULT_DISPLAY);
+ } catch (RemoteException e) {
+ }
}
public void init() {
applyModeBackground(-1, getMode(), false /*animate*/);
- applyMode(getMode(), false /*animate*/, true /*force*/);
+ applyLightsOut(false /*animate*/, true /*force*/);
+ }
+
+ @Override
+ public void setAutoDim(boolean autoDim) {
+ if (mAutoDim == autoDim) return;
+ mAutoDim = autoDim;
+ applyLightsOut(true, false);
+ }
+
+ @Override
+ protected boolean isLightsOut(int mode) {
+ return super.isLightsOut(mode) || (mAutoDim && !mWallpaperVisible);
}
public LightBarTransitionsController getLightTransitionsController() {
@@ -54,13 +90,12 @@ public final class NavigationBarTransitions extends BarTransitions {
@Override
protected void onTransition(int oldMode, int newMode, boolean animate) {
super.onTransition(oldMode, newMode, animate);
- applyMode(newMode, animate, false /*force*/);
+ applyLightsOut(animate, false /*force*/);
}
- private void applyMode(int mode, boolean animate, boolean force) {
-
+ private void applyLightsOut(boolean animate, boolean force) {
// apply to lights out
- applyLightsOut(isLightsOut(mode), animate, force);
+ applyLightsOut(isLightsOut(getMode()), animate, force);
}
private void applyLightsOut(boolean lightsOut, boolean animate, boolean force) {
@@ -73,7 +108,7 @@ public final class NavigationBarTransitions extends BarTransitions {
// ok, everyone, stop it right there
navButtons.animate().cancel();
- final float navButtonsAlpha = lightsOut ? 0.5f : 1f;
+ final float navButtonsAlpha = lightsOut ? 0.6f : 1f;
if (!animate) {
navButtons.setAlpha(navButtonsAlpha);
@@ -86,7 +121,6 @@ public final class NavigationBarTransitions extends BarTransitions {
}
}
-
public void reapplyDarkIntensity() {
applyDarkIntensity(mLightTransitionsController.getCurrentDarkIntensity());
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index ada98b7a2ca3..80aca2880723 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -340,7 +340,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private static final int STATUS_OR_NAV_TRANSIENT =
View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
- private static final long AUTOHIDE_TIMEOUT_MS = 3000;
+ private static final long AUTOHIDE_TIMEOUT_MS = 2250;
/** The minimum delay in ms between reports of notification visibility. */
private static final int VISIBILITY_REPORT_MIN_DELAY_MS = 500;
@@ -560,14 +560,12 @@ public class StatusBar extends SystemUI implements DemoMode,
protected DozeScrimController mDozeScrimController;
private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
- private final Runnable mAutohide = new Runnable() {
- @Override
- public void run() {
- int requested = mSystemUiVisibility & ~STATUS_OR_NAV_TRANSIENT;
- if (mSystemUiVisibility != requested) {
- notifyUiVisibilityChanged(requested);
- }
- }};
+ private final Runnable mAutohide = () -> {
+ int requested = mSystemUiVisibility & ~STATUS_OR_NAV_TRANSIENT;
+ if (mSystemUiVisibility != requested) {
+ notifyUiVisibilityChanged(requested);
+ }
+ };
private boolean mWaitingForKeyguardExit;
protected boolean mDozing;
@@ -3351,6 +3349,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
// manually dismiss the volume panel when interacting with the nav bar
if (changing && interacting && barWindow == StatusBarManager.WINDOW_NAVIGATION_BAR) {
+ touchAutoDim();
dismissVolumeDialog();
}
checkBarModes();
@@ -3385,6 +3384,16 @@ public class StatusBar extends SystemUI implements DemoMode,
mHandler.postDelayed(mAutohide, AUTOHIDE_TIMEOUT_MS);
}
+ public void touchAutoDim() {
+ if (mNavigationBar != null) {
+ mNavigationBar.getBarTransitions().setAutoDim(false);
+ }
+ mHandler.removeCallbacks(mAutoDim);
+ if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED) {
+ mHandler.postDelayed(mAutoDim, AUTOHIDE_TIMEOUT_MS);
+ }
+ }
+
void checkUserAutohide(View v, MotionEvent event) {
if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0 // a transient bar is revealed
&& event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar
@@ -4791,6 +4800,7 @@ public class StatusBar extends SystemUI implements DemoMode,
updateReportRejectedTouchVisibility();
updateDozing();
updateTheme();
+ touchAutoDim();
mNotificationShelf.setStatusBarState(state);
}
@@ -7466,4 +7476,10 @@ public class StatusBar extends SystemUI implements DemoMode,
}
}
// End Extra BaseStatusBarMethods.
+
+ private final Runnable mAutoDim = () -> {
+ if (mNavigationBar != null) {
+ mNavigationBar.getBarTransitions().setAutoDim(true);
+ }
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
index 13ee23fb7af9..06040e2b0bcc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
@@ -28,6 +28,8 @@ import android.view.Surface;
import android.view.View;
import com.android.systemui.R;
+import com.android.systemui.SysUiServiceProvider;
+import com.android.systemui.statusbar.phone.StatusBar;
/**
* The "dead zone" consumes unintentional taps along the top edge of the navigation bar.
@@ -44,6 +46,7 @@ public class DeadZone extends View {
public static final int VERTICAL = 1; // Consume taps along the left edge.
private static final boolean CHATTY = true; // print to logcat when we eat a click
+ private final StatusBar mStatusBar;
private boolean mShouldFlash;
private float mFlashFrac = 0f;
@@ -88,6 +91,7 @@ public class DeadZone extends View {
+ (mVertical ? " vertical" : " horizontal"));
setFlashOnTouchCapture(context.getResources().getBoolean(R.bool.config_dead_zone_flash));
+ mStatusBar = SysUiServiceProvider.getComponent(context, StatusBar.class);
}
static float lerp(float a, float b, float f) {
@@ -132,6 +136,7 @@ public class DeadZone extends View {
if (DEBUG) {
Slog.v(TAG, this + " ACTION_DOWN: " + event.getX() + "," + event.getY());
}
+ if (mStatusBar != null) mStatusBar.touchAutoDim();
int size = (int) getSize(event.getEventTime());
// In the vertical orientation consume taps along the left edge.
// In horizontal orientation consume taps along the top edge.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java
new file mode 100644
index 000000000000..76f57f049561
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.IWindowManager;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.CommandQueue;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+@SmallTest
+public class NavigationBarTransitionsTest extends SysuiTestCase {
+
+ private NavigationBarTransitions mTransitions;
+
+ @Before
+ public void setup() {
+ mDependency.injectMockDependency(IWindowManager.class);
+ mContext.putComponent(CommandQueue.class, mock(CommandQueue.class));
+ NavigationBarView navBar = spy(new NavigationBarView(mContext, null));
+ when(navBar.getCurrentView()).thenReturn(navBar);
+ when(navBar.findViewById(anyInt())).thenReturn(navBar);
+ mTransitions = new NavigationBarTransitions(navBar);
+ }
+
+ @Test
+ public void setIsLightsOut_NoAutoDim() {
+ mTransitions.setAutoDim(false);
+
+ assertFalse(mTransitions.isLightsOut(BarTransitions.MODE_OPAQUE));
+
+ assertTrue(mTransitions.isLightsOut(BarTransitions.MODE_LIGHTS_OUT));
+ }
+
+ @Test
+ public void setIsLightsOut_AutoDim() {
+ mTransitions.setAutoDim(true);
+
+ assertTrue(mTransitions.isLightsOut(BarTransitions.MODE_OPAQUE));
+
+ assertTrue(mTransitions.isLightsOut(BarTransitions.MODE_LIGHTS_OUT));
+ }
+
+} \ No newline at end of file
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index a4849fcd1ca0..c9acdc1b4cc5 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -4219,6 +4219,11 @@ message MetricsEvent {
// OS: O DR
TRAMPOLINE_SETTINGS_EVENT = 1033;
+ // OPEN: Settings > Display > Colors
+ // CATEGORY: SETTINGS
+ // OS: O MR (backported for O DR)
+ COLOR_MODE_SETTINGS = 1143;
+
// ---- End O-DR1 Constants, all O-DR1 constants go above this line ----
// Add new aosp constants above this line.
diff --git a/services/core/java/com/android/server/display/DisplayTransformManager.java b/services/core/java/com/android/server/display/DisplayTransformManager.java
index dbbb318db63b..2aba871f521e 100644
--- a/services/core/java/com/android/server/display/DisplayTransformManager.java
+++ b/services/core/java/com/android/server/display/DisplayTransformManager.java
@@ -16,15 +16,20 @@
package com.android.server.display;
+import android.app.ActivityManager;
+import android.app.IActivityManager;
import android.opengl.Matrix;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.app.NightDisplayController;
import java.util.Arrays;
/**
@@ -50,6 +55,17 @@ public class DisplayTransformManager {
private static final int SURFACE_FLINGER_TRANSACTION_COLOR_MATRIX = 1015;
private static final int SURFACE_FLINGER_TRANSACTION_DALTONIZER = 1014;
+ static final String PERSISTENT_PROPERTY_SATURATION = "persist.sys.sf.color_saturation";
+
+ static final String PERSISTENT_PROPERTY_NATIVE_MODE = "persist.sys.sf.native_mode";
+
+ private static final int SURFACE_FLINGER_TRANSACTION_SATURATION = 1022;
+ private static final int SURFACE_FLINGER_TRANSACTION_NATIVE_MODE = 1023;
+
+ static final float COLOR_SATURATION_NATURAL = 1.0f;
+
+ static final float COLOR_SATURATION_BOOSTED = 1.1f;
+
/**
* Map of level -> color transformation matrix.
*/
@@ -68,9 +84,18 @@ public class DisplayTransformManager {
@GuardedBy("mDaltonizerModeLock")
private int mDaltonizerMode = -1;
+ private IBinder mSurfaceFlinger;
+
/* package */ DisplayTransformManager() {
}
+ public IBinder getSurfaceFlinger() {
+ if (mSurfaceFlinger == null) {
+ mSurfaceFlinger = ServiceManager.getService("SurfaceFlinger");
+ }
+ return mSurfaceFlinger;
+ }
+
/**
* Returns a copy of the color transform matrix set for a given level.
*/
@@ -201,4 +226,71 @@ public class DisplayTransformManager {
}
}
}
+
+ public static boolean isNativeModeEnabled() {
+ return SystemProperties.getBoolean(PERSISTENT_PROPERTY_NATIVE_MODE, false);
+ }
+
+ public boolean setColorMode(int colorMode) {
+ if (colorMode == NightDisplayController.COLOR_MODE_NATURAL) {
+ applySaturation(COLOR_SATURATION_NATURAL);
+ setNativeMode(false);
+ } else if (colorMode == NightDisplayController.COLOR_MODE_BOOSTED) {
+ applySaturation(COLOR_SATURATION_BOOSTED);
+ setNativeMode(false);
+ } else if (colorMode == NightDisplayController.COLOR_MODE_SATURATED) {
+ applySaturation(COLOR_SATURATION_NATURAL);
+ setNativeMode(true);
+ }
+
+ updateConfiguration();
+
+ return true;
+ }
+
+ /**
+ * Propagates the provided saturation to the SurfaceFlinger.
+ */
+ private void applySaturation(float saturation) {
+ SystemProperties.set(PERSISTENT_PROPERTY_SATURATION, Float.toString(saturation));
+ if (getSurfaceFlinger() != null) {
+ final Parcel data = Parcel.obtain();
+ data.writeInterfaceToken("android.ui.ISurfaceComposer");
+ data.writeFloat(saturation);
+ try {
+ getSurfaceFlinger().transact(SURFACE_FLINGER_TRANSACTION_SATURATION, data, null, 0);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "Failed to set saturation", ex);
+ } finally {
+ data.recycle();
+ }
+ }
+ }
+
+ /**
+ * Toggles native mode on/off in SurfaceFlinger.
+ */
+ private void setNativeMode(boolean enabled) {
+ SystemProperties.set(PERSISTENT_PROPERTY_NATIVE_MODE, enabled ? "1" : "0");
+ if (getSurfaceFlinger() != null) {
+ final Parcel data = Parcel.obtain();
+ data.writeInterfaceToken("android.ui.ISurfaceComposer");
+ data.writeInt(enabled ? 1 : 0);
+ try {
+ getSurfaceFlinger().transact(SURFACE_FLINGER_TRANSACTION_NATIVE_MODE, data, null, 0);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "Failed to set native mode", ex);
+ } finally {
+ data.recycle();
+ }
+ }
+ }
+
+ void updateConfiguration() {
+ try {
+ ActivityManager.getService().updateConfiguration(null);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not update configuration", e);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/display/NightDisplayService.java b/services/core/java/com/android/server/display/NightDisplayService.java
index 026921deea55..eeee76863003 100644
--- a/services/core/java/com/android/server/display/NightDisplayService.java
+++ b/services/core/java/com/android/server/display/NightDisplayService.java
@@ -52,6 +52,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.Calendar;
import java.util.TimeZone;
+import com.android.internal.R;
+
import static com.android.server.display.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY;
/**
@@ -110,19 +112,7 @@ public final class NightDisplayService extends SystemService
private float[] mMatrixNight = new float[16];
- /**
- * The 3x3 color transformation matrix is formatted like so:
- * <table>
- * <tr><td>R: a coefficient</td><td>G: a coefficient</td><td>B: a coefficient</td></tr>
- * <tr><td>R: b coefficient</td><td>G: b coefficient</td><td>B: b coefficient</td></tr>
- * <tr><td>R: y-intercept</td><td>G: y-intercept</td><td>B: y-intercept</td></tr>
- * </table>
- */
- private static final float[] mColorTempCoefficients = new float[] {
- 0.0f, -0.000000014365268757f, -0.000000000910931179f,
- 0.0f, 0.000255092801250106f, 0.000207598323269139f,
- 1.0f, -0.064156942434907716f, -0.349361641294833436f
- };
+ private final float[] mColorTempCoefficients = new float[9];
private int mCurrentUser = UserHandle.USER_NULL;
private ContentObserver mUserSetupObserver;
@@ -240,6 +230,8 @@ public final class NightDisplayService extends SystemService
mController = new NightDisplayController(getContext(), mCurrentUser);
mController.setListener(this);
+ setCoefficientMatrix(getContext());
+
// Prepare color transformation matrix.
setMatrix(mController.getColorTemperature(), mMatrixNight);
@@ -335,6 +327,28 @@ public final class NightDisplayService extends SystemService
applyTint(true);
}
+ @Override
+ public void onDisplayColorModeChanged(int colorMode) {
+ final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
+ dtm.setColorMode(colorMode);
+
+ setCoefficientMatrix(getContext());
+ setMatrix(mController.getColorTemperature(), mMatrixNight);
+ if (mController.isActivated()) {
+ applyTint(true);
+ }
+ }
+
+ private void setCoefficientMatrix(Context context) {
+ final boolean isNative = DisplayTransformManager.isNativeModeEnabled();
+ final String[] coefficients = context.getResources().getStringArray(isNative ?
+ R.array.config_nightDisplayColorTemperatureCoefficientsNative
+ : R.array.config_nightDisplayColorTemperatureCoefficients);
+ for (int i = 0; i < 9 && i < coefficients.length; i++) {
+ mColorTempCoefficients[i] = Float.parseFloat(coefficients[i]);
+ }
+ }
+
/**
* Applies current color temperature matrix, or removes it if deactivated.
*
@@ -410,11 +424,11 @@ public final class NightDisplayService extends SystemService
final float squareTemperature = colorTemperature * colorTemperature;
final float red = squareTemperature * mColorTempCoefficients[0]
- + colorTemperature * mColorTempCoefficients[3] + mColorTempCoefficients[6];
- final float green = squareTemperature * mColorTempCoefficients[1]
- + colorTemperature * mColorTempCoefficients[4] + mColorTempCoefficients[7];
- final float blue = squareTemperature * mColorTempCoefficients[2]
- + colorTemperature * mColorTempCoefficients[5] + mColorTempCoefficients[8];
+ + colorTemperature * mColorTempCoefficients[1] + mColorTempCoefficients[2];
+ final float green = squareTemperature * mColorTempCoefficients[3]
+ + colorTemperature * mColorTempCoefficients[4] + mColorTempCoefficients[5];
+ final float blue = squareTemperature * mColorTempCoefficients[6]
+ + colorTemperature * mColorTempCoefficients[7] + mColorTempCoefficients[8];
outTemp[0] = red;
outTemp[5] = green;
outTemp[10] = blue;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 765dc23b48a0..3e1c201d13d9 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7670,7 +7670,8 @@ public class WindowManagerService extends IWindowManager.Stub
}
boolean hasWideColorGamutSupport() {
- return mHasWideColorGamutSupport;
+ return mHasWideColorGamutSupport &&
+ !SystemProperties.getBoolean("persist.sys.sf.native_mode", false);
}
void updateNonSystemOverlayWindowsVisibilityIfNeeded(WindowState win, boolean surfaceShown) {