Loading core/java/android/provider/Settings.java +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading core/java/com/android/internal/app/NightDisplayController.java +61 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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. */ Loading Loading @@ -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; } } } Loading Loading @@ -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); } } } Loading Loading @@ -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) {} } } core/res/res/values/config.xml +12 −0 Original line number Diff line number Diff line Loading @@ -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> Loading core/res/res/values/symbols.xml +1 −0 Original line number Diff line number Diff line Loading @@ -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" /> Loading services/core/java/com/android/server/display/DisplayTransformManager.java +87 −2 Original line number Diff line number Diff line Loading @@ -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; /** Loading @@ -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. */ Loading @@ -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. */ Loading Loading @@ -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"); Loading @@ -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"); Loading @@ -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); } } } Loading
core/java/android/provider/Settings.java +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
core/java/com/android/internal/app/NightDisplayController.java +61 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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. */ Loading Loading @@ -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; } } } Loading Loading @@ -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); } } } Loading Loading @@ -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) {} } }
core/res/res/values/config.xml +12 −0 Original line number Diff line number Diff line Loading @@ -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> Loading
core/res/res/values/symbols.xml +1 −0 Original line number Diff line number Diff line Loading @@ -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" /> Loading
services/core/java/com/android/server/display/DisplayTransformManager.java +87 −2 Original line number Diff line number Diff line Loading @@ -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; /** Loading @@ -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. */ Loading @@ -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. */ Loading Loading @@ -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"); Loading @@ -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"); Loading @@ -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); } } }