Merge "Support native and srgb for night display"

This commit is contained in:
Christine Franks
2017-10-27 16:10:28 +00:00
committed by Android (Google) Code Review
6 changed files with 191 additions and 9 deletions

View File

@@ -3095,6 +3095,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

View File

@@ -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;
@@ -76,6 +77,29 @@ public final class NightDisplayController {
*/
public static final int AUTO_MODE_TWILIGHT = 2;
@Retention(RetentionPolicy.SOURCE)
@IntDef({ COLOR_MODE_NATURAL, COLOR_MODE_BOOSTED, COLOR_MODE_SATURATED })
public @interface ColorMode {}
/**
* 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;
@@ -305,6 +329,31 @@ public final class NightDisplayController {
Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, colorTemperature, mUserId);
}
/**
* 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) {
throw new IllegalArgumentException("Invalid colorMode: " + colorMode);
}
System.putIntForUser(mContext.getContentResolver(), System.DISPLAY_COLOR_MODE, colorMode,
mUserId);
}
/**
* Returns the minimum allowed color temperature (in Kelvin) to tint the display when activated.
*/
@@ -351,6 +400,9 @@ public final class NightDisplayController {
case Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE:
mCallback.onColorTemperatureChanged(getColorTemperature());
break;
case System.DISPLAY_COLOR_MODE:
mCallback.onDisplayColorModeChanged(getColorMode());
break;
}
}
}
@@ -379,6 +431,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);
}
}
}
@@ -425,5 +479,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) {}
}
}

View File

@@ -901,6 +901,18 @@
<!-- 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>

View File

@@ -2842,6 +2842,7 @@
<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" />

View File

@@ -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;
/**
@@ -34,6 +39,8 @@ public class DisplayTransformManager {
private static final String TAG = "DisplayTransformManager";
private static final String SURFACE_FLINGER = "SurfaceFlinger";
/**
* Color transform level used by Night display to tint the display red.
*/
@@ -50,6 +57,15 @@ public class DisplayTransformManager {
private static final int SURFACE_FLINGER_TRANSACTION_COLOR_MATRIX = 1015;
private static final int SURFACE_FLINGER_TRANSACTION_DALTONIZER = 1014;
private static final String PERSISTENT_PROPERTY_SATURATION = "persist.sys.sf.color_saturation";
private 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;
private static final float COLOR_SATURATION_NATURAL = 1.0f;
private static final float COLOR_SATURATION_BOOSTED = 1.1f;
/**
* Map of level -> color transformation matrix.
*/
@@ -161,7 +177,7 @@ public class DisplayTransformManager {
* Propagates the provided color transformation matrix to the SurfaceFlinger.
*/
private static void applyColorMatrix(float[] m) {
final IBinder flinger = ServiceManager.getService("SurfaceFlinger");
final IBinder flinger = ServiceManager.getService(SURFACE_FLINGER);
if (flinger != null) {
final Parcel data = Parcel.obtain();
data.writeInterfaceToken("android.ui.ISurfaceComposer");
@@ -187,7 +203,7 @@ public class DisplayTransformManager {
* Propagates the provided Daltonization mode to the SurfaceFlinger.
*/
private static void applyDaltonizerMode(int mode) {
final IBinder flinger = ServiceManager.getService("SurfaceFlinger");
final IBinder flinger = ServiceManager.getService(SURFACE_FLINGER);
if (flinger != null) {
final Parcel data = Parcel.obtain();
data.writeInterfaceToken("android.ui.ISurfaceComposer");
@@ -201,4 +217,73 @@ 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));
final IBinder flinger = ServiceManager.getService(SURFACE_FLINGER);
if (flinger != null) {
final Parcel data = Parcel.obtain();
data.writeInterfaceToken("android.ui.ISurfaceComposer");
data.writeFloat(saturation);
try {
flinger.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");
final IBinder flinger = ServiceManager.getService(SURFACE_FLINGER);
if (flinger != null) {
final Parcel data = Parcel.obtain();
data.writeInterfaceToken("android.ui.ISurfaceComposer");
data.writeInt(enabled ? 1 : 0);
try {
flinger.transact(SURFACE_FLINGER_TRANSACTION_NATIVE_MODE, data, null, 0);
} catch (RemoteException ex) {
Log.e(TAG, "Failed to set native mode", ex);
} finally {
data.recycle();
}
}
}
private void updateConfiguration() {
try {
ActivityManager.getService().updateConfiguration(null);
} catch (RemoteException e) {
Log.e(TAG, "Could not update configuration", e);
}
}
}

View File

@@ -52,7 +52,8 @@ import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.TimeZone;
import com.android.internal.R;
import static com.android.server.display.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY;
@@ -126,12 +127,6 @@ public final class NightDisplayService extends SystemService
public NightDisplayService(Context context) {
super(context);
mHandler = new Handler(Looper.getMainLooper());
final String[] coefficients = context.getResources().getStringArray(
com.android.internal.R.array.config_nightDisplayColorTemperatureCoefficients);
for (int i = 0; i < 9 && i < coefficients.length; i++) {
mColorTempCoefficients[i] = Float.parseFloat(coefficients[i]);
}
}
@Override
@@ -236,6 +231,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);
@@ -331,6 +328,26 @@ 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);
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.
*