Loading core/java/android/hardware/display/ColorDisplayManager.java +84 −0 Original line number Diff line number Diff line Loading @@ -23,12 +23,14 @@ import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.content.ContentResolver; import android.content.Context; import android.metrics.LogMaker; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.provider.Settings.Secure; import com.android.internal.R; import com.android.internal.logging.MetricsLogger; Loading Loading @@ -123,6 +125,42 @@ public final class ColorDisplayManager { @SystemApi public static final int AUTO_MODE_TWILIGHT = 2; /** * @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef({COLOR_MODE_NATURAL, COLOR_MODE_BOOSTED, COLOR_MODE_SATURATED, COLOR_MODE_AUTOMATIC}) public @interface ColorMode {} /** * Color mode with natural colors. * * @hide * @see #setColorMode(int) */ public static final int COLOR_MODE_NATURAL = 0; /** * Color mode with boosted colors. * * @hide * @see #setColorMode(int) */ public static final int COLOR_MODE_BOOSTED = 1; /** * Color mode with saturated colors. * * @hide * @see #setColorMode(int) */ public static final int COLOR_MODE_SATURATED = 2; /** * Color mode with automatic colors. * * @hide * @see #setColorMode(int) */ public static final int COLOR_MODE_AUTOMATIC = 3; private final ColorDisplayManagerInternal mManager; private MetricsLogger mMetricsLogger; Loading Loading @@ -285,6 +323,24 @@ public final class ColorDisplayManager { return mManager.setNightDisplayCustomEndTime(new Time(endTime)); } /** * Sets the current display color mode. * * @hide */ public void setColorMode(int colorMode) { mManager.setColorMode(colorMode); } /** * Gets the current display color mode. * * @hide */ public int getColorMode() { return mManager.getColorMode(); } /** * Returns whether the device has a wide color gamut display. * Loading Loading @@ -384,6 +440,18 @@ public final class ColorDisplayManager { return mManager.getTransformCapabilities(); } /** * Returns whether accessibility transforms are currently enabled, which determines whether * color modes are currently configurable for this device. * * @hide */ public static boolean areAccessibilityTransformsEnabled(Context context) { final ContentResolver cr = context.getContentResolver(); return Secure.getInt(cr, Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0) == 1 || Secure.getInt(cr, Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0) == 1; } private MetricsLogger getMetricsLogger() { if (mMetricsLogger == null) { mMetricsLogger = new MetricsLogger(); Loading Loading @@ -528,6 +596,22 @@ public final class ColorDisplayManager { } } int getColorMode() { try { return mCdm.getColorMode(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } void setColorMode(int colorMode) { try { mCdm.setColorMode(colorMode); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } int getTransformCapabilities() { try { return mCdm.getTransformCapabilities(); Loading core/java/android/hardware/display/IColorDisplayManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -38,4 +38,7 @@ interface IColorDisplayManager { boolean setNightDisplayCustomStartTime(in Time time); Time getNightDisplayCustomEndTime(); boolean setNightDisplayCustomEndTime(in Time time); int getColorMode(); void setColorMode(int colorMode); } No newline at end of file core/java/android/provider/Settings.java +3 −3 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.database.Cursor; import android.database.SQLException; import android.hardware.display.ColorDisplayManager; import android.location.LocationManager; import android.media.AudioFormat; import android.net.ConnectivityManager; Loading Loading @@ -89,7 +90,6 @@ import android.util.MemoryIntArray; import android.view.inputmethod.InputMethodSystemProperty; import com.android.internal.annotations.GuardedBy; import com.android.internal.app.ColorDisplayController; import com.android.internal.widget.ILockSettings; import java.io.IOException; Loading Loading @@ -3239,8 +3239,8 @@ public final class Settings { private static final Validator DISPLAY_COLOR_MODE_VALIDATOR = new SettingsValidators.InclusiveIntegerRangeValidator( ColorDisplayController.COLOR_MODE_NATURAL, ColorDisplayController.COLOR_MODE_AUTOMATIC); ColorDisplayManager.COLOR_MODE_NATURAL, ColorDisplayManager.COLOR_MODE_AUTOMATIC); /** * The amount of time in milliseconds before the device goes to sleep or begins Loading core/java/com/android/internal/app/ColorDisplayController.java +3 −147 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.internal.app; import android.annotation.IntDef; import android.annotation.NonNull; import android.app.ActivityManager; import android.content.ContentResolver; Loading @@ -24,18 +23,13 @@ import android.content.Context; import android.database.ContentObserver; import android.hardware.display.ColorDisplayManager; import android.hardware.display.ColorDisplayManager.AutoMode; import android.hardware.display.ColorDisplayManager.ColorMode; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.SystemProperties; import android.provider.Settings.Secure; import android.provider.Settings.System; import android.util.Slog; import com.android.internal.R; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.time.LocalTime; /** Loading @@ -49,35 +43,6 @@ public final class ColorDisplayController { private static final String TAG = "ColorDisplayController"; private static final boolean DEBUG = false; @Retention(RetentionPolicy.SOURCE) @IntDef({COLOR_MODE_NATURAL, COLOR_MODE_BOOSTED, COLOR_MODE_SATURATED, COLOR_MODE_AUTOMATIC}) 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; /** * Color mode with automatic colors. * * @see #setColorMode(int) */ public static final int COLOR_MODE_AUTOMATIC = 3; private final Context mContext; private final int mUserId; private final ColorDisplayManager mColorDisplayManager; Loading Loading @@ -196,75 +161,11 @@ public final class ColorDisplayController { return mColorDisplayManager.setNightDisplayColorTemperature(colorTemperature); } /** * Get the current color mode from system properties, or return -1. * * See com.android.server.display.DisplayTransformManager. */ private @ColorMode int getCurrentColorModeFromSystemProperties() { final int displayColorSetting = SystemProperties.getInt("persist.sys.sf.native_mode", 0); if (displayColorSetting == 0) { return "1.0".equals(SystemProperties.get("persist.sys.sf.color_saturation")) ? COLOR_MODE_NATURAL : COLOR_MODE_BOOSTED; } else if (displayColorSetting == 1) { return COLOR_MODE_SATURATED; } else if (displayColorSetting == 2) { return COLOR_MODE_AUTOMATIC; } else { return -1; } } private boolean isColorModeAvailable(@ColorMode int colorMode) { final int[] availableColorModes = mContext.getResources().getIntArray( R.array.config_availableColorModes); if (availableColorModes != null) { for (int mode : availableColorModes) { if (mode == colorMode) { return true; } } } return false; } /** * Get the current color mode. */ public int getColorMode() { if (getAccessibilityTransformActivated()) { if (isColorModeAvailable(COLOR_MODE_SATURATED)) { return COLOR_MODE_SATURATED; } else if (isColorModeAvailable(COLOR_MODE_AUTOMATIC)) { return COLOR_MODE_AUTOMATIC; } } int colorMode = System.getIntForUser(mContext.getContentResolver(), System.DISPLAY_COLOR_MODE, -1, mUserId); if (colorMode == -1) { // There might be a system property controlling color mode that we need to respect; if // not, this will set a suitable default. colorMode = getCurrentColorModeFromSystemProperties(); } // This happens when a color mode is no longer available (e.g., after system update or B&R) // or the device does not support any color mode. if (!isColorModeAvailable(colorMode)) { if (colorMode == COLOR_MODE_BOOSTED && isColorModeAvailable(COLOR_MODE_NATURAL)) { colorMode = COLOR_MODE_NATURAL; } else if (colorMode == COLOR_MODE_SATURATED && isColorModeAvailable(COLOR_MODE_AUTOMATIC)) { colorMode = COLOR_MODE_AUTOMATIC; } else if (colorMode == COLOR_MODE_AUTOMATIC && isColorModeAvailable(COLOR_MODE_SATURATED)) { colorMode = COLOR_MODE_SATURATED; } else { colorMode = -1; } } return colorMode; return mColorDisplayManager.getColorMode(); } /** Loading @@ -273,11 +174,7 @@ public final class ColorDisplayController { * @param colorMode the color mode */ public void setColorMode(@ColorMode int colorMode) { if (!isColorModeAvailable(colorMode)) { throw new IllegalArgumentException("Invalid colorMode: " + colorMode); } System.putIntForUser(mContext.getContentResolver(), System.DISPLAY_COLOR_MODE, colorMode, mUserId); mColorDisplayManager.setColorMode(colorMode); } /** Loading @@ -294,18 +191,6 @@ public final class ColorDisplayController { return ColorDisplayManager.getMaximumColorTemperature(mContext); } /** * Returns true if any Accessibility color transforms are enabled. */ public boolean getAccessibilityTransformActivated() { final ContentResolver cr = mContext.getContentResolver(); return Secure.getIntForUser(cr, Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, mUserId) == 1 || Secure.getIntForUser(cr, Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, mUserId) == 1; } private void onSettingChanged(@NonNull String setting) { if (DEBUG) { Slog.d(TAG, "onSettingChanged: " + setting); Loading @@ -328,13 +213,6 @@ public final class ColorDisplayController { case Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE: mCallback.onColorTemperatureChanged(getColorTemperature()); break; case System.DISPLAY_COLOR_MODE: mCallback.onDisplayColorModeChanged(getColorMode()); break; case Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED: case Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED: mCallback.onAccessibilityTransformChanged(getAccessibilityTransformActivated()); break; } } } Loading Loading @@ -377,14 +255,6 @@ public final class ColorDisplayController { 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); cr.registerContentObserver( Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED), false /* notifyForDecendants */, mContentObserver, mUserId); cr.registerContentObserver( Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED), false /* notifyForDecendants */, mContentObserver, mUserId); } } } Loading Loading @@ -424,19 +294,5 @@ public final class ColorDisplayController { * @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) {} /** * Callback invoked when Accessibility color transforms change. * * @param state the state Accessibility color transforms (true of active) */ default void onAccessibilityTransformChanged(boolean state) {} } } services/core/java/com/android/server/display/ColorDisplayService.java +126 −13 Original line number Diff line number Diff line Loading @@ -19,7 +19,10 @@ package com.android.server.display; import static android.hardware.display.ColorDisplayManager.AUTO_MODE_CUSTOM_TIME; import static android.hardware.display.ColorDisplayManager.AUTO_MODE_DISABLED; import static android.hardware.display.ColorDisplayManager.AUTO_MODE_TWILIGHT; import static android.hardware.display.ColorDisplayManager.COLOR_MODE_AUTOMATIC; import static android.hardware.display.ColorDisplayManager.COLOR_MODE_BOOSTED; import static android.hardware.display.ColorDisplayManager.COLOR_MODE_NATURAL; import static android.hardware.display.ColorDisplayManager.COLOR_MODE_SATURATED; import static com.android.server.display.DisplayTransformManager.LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE; import static com.android.server.display.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY; import static com.android.server.display.DisplayTransformManager.LEVEL_COLOR_MATRIX_SATURATION; Loading @@ -45,6 +48,7 @@ import android.database.ContentObserver; import android.graphics.ColorSpace; import android.hardware.display.ColorDisplayManager; import android.hardware.display.ColorDisplayManager.AutoMode; import android.hardware.display.ColorDisplayManager.ColorMode; import android.hardware.display.IColorDisplayManager; import android.hardware.display.Time; import android.net.Uri; Loading @@ -53,6 +57,7 @@ import android.os.Binder; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings.Secure; import android.provider.Settings.System; Loading @@ -61,7 +66,6 @@ import android.util.Slog; import android.view.SurfaceControl; import android.view.accessibility.AccessibilityManager; import android.view.animation.AnimationUtils; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.ColorDisplayController; Loading @@ -71,7 +75,6 @@ import com.android.server.SystemService; import com.android.server.twilight.TwilightListener; import com.android.server.twilight.TwilightManager; import com.android.server.twilight.TwilightState; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.ref.WeakReference; Loading Loading @@ -944,6 +947,89 @@ public final class ColorDisplayService extends SystemService { .setSaturationLevel(packageName, mCurrentUser, saturationLevel); } private void setColorModeInternal(@ColorMode int colorMode) { if (!isColorModeAvailable(colorMode)) { throw new IllegalArgumentException("Invalid colorMode: " + colorMode); } System.putIntForUser(getContext().getContentResolver(), System.DISPLAY_COLOR_MODE, colorMode, mCurrentUser); } private @ColorMode int getColorModeInternal() { final ContentResolver cr = getContext().getContentResolver(); if (Secure.getIntForUser(cr, Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, mCurrentUser) == 1 || Secure.getIntForUser(cr, Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, mCurrentUser) == 1) { // There are restrictions on the available color modes combined with a11y transforms. if (isColorModeAvailable(COLOR_MODE_SATURATED)) { return COLOR_MODE_SATURATED; } else if (isColorModeAvailable(COLOR_MODE_AUTOMATIC)) { return COLOR_MODE_AUTOMATIC; } } int colorMode = System.getIntForUser(cr, System.DISPLAY_COLOR_MODE, -1, mCurrentUser); if (colorMode == -1) { // There might be a system property controlling color mode that we need to respect; if // not, this will set a suitable default. colorMode = getCurrentColorModeFromSystemProperties(); } // This happens when a color mode is no longer available (e.g., after system update or B&R) // or the device does not support any color mode. if (!isColorModeAvailable(colorMode)) { if (colorMode == COLOR_MODE_BOOSTED && isColorModeAvailable(COLOR_MODE_NATURAL)) { colorMode = COLOR_MODE_NATURAL; } else if (colorMode == COLOR_MODE_SATURATED && isColorModeAvailable(COLOR_MODE_AUTOMATIC)) { colorMode = COLOR_MODE_AUTOMATIC; } else if (colorMode == COLOR_MODE_AUTOMATIC && isColorModeAvailable(COLOR_MODE_SATURATED)) { colorMode = COLOR_MODE_SATURATED; } else { colorMode = -1; } } return colorMode; } /** * Get the current color mode from system properties, or return -1 if invalid. * * See {@link com.android.server.display.DisplayTransformManager} */ private @ColorMode int getCurrentColorModeFromSystemProperties() { final int displayColorSetting = SystemProperties.getInt("persist.sys.sf.native_mode", 0); if (displayColorSetting == 0) { return "1.0".equals(SystemProperties.get("persist.sys.sf.color_saturation")) ? COLOR_MODE_NATURAL : COLOR_MODE_BOOSTED; } else if (displayColorSetting == 1) { return COLOR_MODE_SATURATED; } else if (displayColorSetting == 2) { return COLOR_MODE_AUTOMATIC; } else { return -1; } } private boolean isColorModeAvailable(@ColorMode int colorMode) { final int[] availableColorModes = getContext().getResources().getIntArray( R.array.config_availableColorModes); if (availableColorModes != null) { for (int mode : availableColorModes) { if (mode == colorMode) { return true; } } } return false; } private void dumpInternal(PrintWriter pw) { pw.println("COLOR DISPLAY MANAGER dumpsys (color_display)"); pw.println("Night Display:"); Loading Loading @@ -1445,13 +1531,38 @@ public final class ColorDisplayService extends SystemService { */ public interface ColorTransformController { /** Apply the given saturation (grayscale) matrix to the associated AppWindow. */ /** * Apply the given saturation (grayscale) matrix to the associated AppWindow. */ void applyAppSaturation(@Size(9) float[] matrix, @Size(3) float[] translation); } @VisibleForTesting final class BinderService extends IColorDisplayManager.Stub { @Override public void setColorMode(int colorMode) { getContext().enforceCallingOrSelfPermission( Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS, "Permission required to set display color mode"); final long token = Binder.clearCallingIdentity(); try { setColorModeInternal(colorMode); } finally { Binder.restoreCallingIdentity(token); } } @Override public int getColorMode() { final long token = Binder.clearCallingIdentity(); try { return getColorModeInternal(); } finally { Binder.restoreCallingIdentity(token); } } @Override public boolean isDeviceColorManaged() { final long token = Binder.clearCallingIdentity(); Loading Loading @@ -1640,7 +1751,9 @@ public final class ColorDisplayService extends SystemService { @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return; if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) { return; } final long token = Binder.clearCallingIdentity(); try { Loading Loading
core/java/android/hardware/display/ColorDisplayManager.java +84 −0 Original line number Diff line number Diff line Loading @@ -23,12 +23,14 @@ import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.content.ContentResolver; import android.content.Context; import android.metrics.LogMaker; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.provider.Settings.Secure; import com.android.internal.R; import com.android.internal.logging.MetricsLogger; Loading Loading @@ -123,6 +125,42 @@ public final class ColorDisplayManager { @SystemApi public static final int AUTO_MODE_TWILIGHT = 2; /** * @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef({COLOR_MODE_NATURAL, COLOR_MODE_BOOSTED, COLOR_MODE_SATURATED, COLOR_MODE_AUTOMATIC}) public @interface ColorMode {} /** * Color mode with natural colors. * * @hide * @see #setColorMode(int) */ public static final int COLOR_MODE_NATURAL = 0; /** * Color mode with boosted colors. * * @hide * @see #setColorMode(int) */ public static final int COLOR_MODE_BOOSTED = 1; /** * Color mode with saturated colors. * * @hide * @see #setColorMode(int) */ public static final int COLOR_MODE_SATURATED = 2; /** * Color mode with automatic colors. * * @hide * @see #setColorMode(int) */ public static final int COLOR_MODE_AUTOMATIC = 3; private final ColorDisplayManagerInternal mManager; private MetricsLogger mMetricsLogger; Loading Loading @@ -285,6 +323,24 @@ public final class ColorDisplayManager { return mManager.setNightDisplayCustomEndTime(new Time(endTime)); } /** * Sets the current display color mode. * * @hide */ public void setColorMode(int colorMode) { mManager.setColorMode(colorMode); } /** * Gets the current display color mode. * * @hide */ public int getColorMode() { return mManager.getColorMode(); } /** * Returns whether the device has a wide color gamut display. * Loading Loading @@ -384,6 +440,18 @@ public final class ColorDisplayManager { return mManager.getTransformCapabilities(); } /** * Returns whether accessibility transforms are currently enabled, which determines whether * color modes are currently configurable for this device. * * @hide */ public static boolean areAccessibilityTransformsEnabled(Context context) { final ContentResolver cr = context.getContentResolver(); return Secure.getInt(cr, Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0) == 1 || Secure.getInt(cr, Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0) == 1; } private MetricsLogger getMetricsLogger() { if (mMetricsLogger == null) { mMetricsLogger = new MetricsLogger(); Loading Loading @@ -528,6 +596,22 @@ public final class ColorDisplayManager { } } int getColorMode() { try { return mCdm.getColorMode(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } void setColorMode(int colorMode) { try { mCdm.setColorMode(colorMode); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } int getTransformCapabilities() { try { return mCdm.getTransformCapabilities(); Loading
core/java/android/hardware/display/IColorDisplayManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -38,4 +38,7 @@ interface IColorDisplayManager { boolean setNightDisplayCustomStartTime(in Time time); Time getNightDisplayCustomEndTime(); boolean setNightDisplayCustomEndTime(in Time time); int getColorMode(); void setColorMode(int colorMode); } No newline at end of file
core/java/android/provider/Settings.java +3 −3 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.database.Cursor; import android.database.SQLException; import android.hardware.display.ColorDisplayManager; import android.location.LocationManager; import android.media.AudioFormat; import android.net.ConnectivityManager; Loading Loading @@ -89,7 +90,6 @@ import android.util.MemoryIntArray; import android.view.inputmethod.InputMethodSystemProperty; import com.android.internal.annotations.GuardedBy; import com.android.internal.app.ColorDisplayController; import com.android.internal.widget.ILockSettings; import java.io.IOException; Loading Loading @@ -3239,8 +3239,8 @@ public final class Settings { private static final Validator DISPLAY_COLOR_MODE_VALIDATOR = new SettingsValidators.InclusiveIntegerRangeValidator( ColorDisplayController.COLOR_MODE_NATURAL, ColorDisplayController.COLOR_MODE_AUTOMATIC); ColorDisplayManager.COLOR_MODE_NATURAL, ColorDisplayManager.COLOR_MODE_AUTOMATIC); /** * The amount of time in milliseconds before the device goes to sleep or begins Loading
core/java/com/android/internal/app/ColorDisplayController.java +3 −147 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.internal.app; import android.annotation.IntDef; import android.annotation.NonNull; import android.app.ActivityManager; import android.content.ContentResolver; Loading @@ -24,18 +23,13 @@ import android.content.Context; import android.database.ContentObserver; import android.hardware.display.ColorDisplayManager; import android.hardware.display.ColorDisplayManager.AutoMode; import android.hardware.display.ColorDisplayManager.ColorMode; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.SystemProperties; import android.provider.Settings.Secure; import android.provider.Settings.System; import android.util.Slog; import com.android.internal.R; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.time.LocalTime; /** Loading @@ -49,35 +43,6 @@ public final class ColorDisplayController { private static final String TAG = "ColorDisplayController"; private static final boolean DEBUG = false; @Retention(RetentionPolicy.SOURCE) @IntDef({COLOR_MODE_NATURAL, COLOR_MODE_BOOSTED, COLOR_MODE_SATURATED, COLOR_MODE_AUTOMATIC}) 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; /** * Color mode with automatic colors. * * @see #setColorMode(int) */ public static final int COLOR_MODE_AUTOMATIC = 3; private final Context mContext; private final int mUserId; private final ColorDisplayManager mColorDisplayManager; Loading Loading @@ -196,75 +161,11 @@ public final class ColorDisplayController { return mColorDisplayManager.setNightDisplayColorTemperature(colorTemperature); } /** * Get the current color mode from system properties, or return -1. * * See com.android.server.display.DisplayTransformManager. */ private @ColorMode int getCurrentColorModeFromSystemProperties() { final int displayColorSetting = SystemProperties.getInt("persist.sys.sf.native_mode", 0); if (displayColorSetting == 0) { return "1.0".equals(SystemProperties.get("persist.sys.sf.color_saturation")) ? COLOR_MODE_NATURAL : COLOR_MODE_BOOSTED; } else if (displayColorSetting == 1) { return COLOR_MODE_SATURATED; } else if (displayColorSetting == 2) { return COLOR_MODE_AUTOMATIC; } else { return -1; } } private boolean isColorModeAvailable(@ColorMode int colorMode) { final int[] availableColorModes = mContext.getResources().getIntArray( R.array.config_availableColorModes); if (availableColorModes != null) { for (int mode : availableColorModes) { if (mode == colorMode) { return true; } } } return false; } /** * Get the current color mode. */ public int getColorMode() { if (getAccessibilityTransformActivated()) { if (isColorModeAvailable(COLOR_MODE_SATURATED)) { return COLOR_MODE_SATURATED; } else if (isColorModeAvailable(COLOR_MODE_AUTOMATIC)) { return COLOR_MODE_AUTOMATIC; } } int colorMode = System.getIntForUser(mContext.getContentResolver(), System.DISPLAY_COLOR_MODE, -1, mUserId); if (colorMode == -1) { // There might be a system property controlling color mode that we need to respect; if // not, this will set a suitable default. colorMode = getCurrentColorModeFromSystemProperties(); } // This happens when a color mode is no longer available (e.g., after system update or B&R) // or the device does not support any color mode. if (!isColorModeAvailable(colorMode)) { if (colorMode == COLOR_MODE_BOOSTED && isColorModeAvailable(COLOR_MODE_NATURAL)) { colorMode = COLOR_MODE_NATURAL; } else if (colorMode == COLOR_MODE_SATURATED && isColorModeAvailable(COLOR_MODE_AUTOMATIC)) { colorMode = COLOR_MODE_AUTOMATIC; } else if (colorMode == COLOR_MODE_AUTOMATIC && isColorModeAvailable(COLOR_MODE_SATURATED)) { colorMode = COLOR_MODE_SATURATED; } else { colorMode = -1; } } return colorMode; return mColorDisplayManager.getColorMode(); } /** Loading @@ -273,11 +174,7 @@ public final class ColorDisplayController { * @param colorMode the color mode */ public void setColorMode(@ColorMode int colorMode) { if (!isColorModeAvailable(colorMode)) { throw new IllegalArgumentException("Invalid colorMode: " + colorMode); } System.putIntForUser(mContext.getContentResolver(), System.DISPLAY_COLOR_MODE, colorMode, mUserId); mColorDisplayManager.setColorMode(colorMode); } /** Loading @@ -294,18 +191,6 @@ public final class ColorDisplayController { return ColorDisplayManager.getMaximumColorTemperature(mContext); } /** * Returns true if any Accessibility color transforms are enabled. */ public boolean getAccessibilityTransformActivated() { final ContentResolver cr = mContext.getContentResolver(); return Secure.getIntForUser(cr, Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, mUserId) == 1 || Secure.getIntForUser(cr, Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, mUserId) == 1; } private void onSettingChanged(@NonNull String setting) { if (DEBUG) { Slog.d(TAG, "onSettingChanged: " + setting); Loading @@ -328,13 +213,6 @@ public final class ColorDisplayController { case Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE: mCallback.onColorTemperatureChanged(getColorTemperature()); break; case System.DISPLAY_COLOR_MODE: mCallback.onDisplayColorModeChanged(getColorMode()); break; case Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED: case Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED: mCallback.onAccessibilityTransformChanged(getAccessibilityTransformActivated()); break; } } } Loading Loading @@ -377,14 +255,6 @@ public final class ColorDisplayController { 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); cr.registerContentObserver( Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED), false /* notifyForDecendants */, mContentObserver, mUserId); cr.registerContentObserver( Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED), false /* notifyForDecendants */, mContentObserver, mUserId); } } } Loading Loading @@ -424,19 +294,5 @@ public final class ColorDisplayController { * @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) {} /** * Callback invoked when Accessibility color transforms change. * * @param state the state Accessibility color transforms (true of active) */ default void onAccessibilityTransformChanged(boolean state) {} } }
services/core/java/com/android/server/display/ColorDisplayService.java +126 −13 Original line number Diff line number Diff line Loading @@ -19,7 +19,10 @@ package com.android.server.display; import static android.hardware.display.ColorDisplayManager.AUTO_MODE_CUSTOM_TIME; import static android.hardware.display.ColorDisplayManager.AUTO_MODE_DISABLED; import static android.hardware.display.ColorDisplayManager.AUTO_MODE_TWILIGHT; import static android.hardware.display.ColorDisplayManager.COLOR_MODE_AUTOMATIC; import static android.hardware.display.ColorDisplayManager.COLOR_MODE_BOOSTED; import static android.hardware.display.ColorDisplayManager.COLOR_MODE_NATURAL; import static android.hardware.display.ColorDisplayManager.COLOR_MODE_SATURATED; import static com.android.server.display.DisplayTransformManager.LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE; import static com.android.server.display.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY; import static com.android.server.display.DisplayTransformManager.LEVEL_COLOR_MATRIX_SATURATION; Loading @@ -45,6 +48,7 @@ import android.database.ContentObserver; import android.graphics.ColorSpace; import android.hardware.display.ColorDisplayManager; import android.hardware.display.ColorDisplayManager.AutoMode; import android.hardware.display.ColorDisplayManager.ColorMode; import android.hardware.display.IColorDisplayManager; import android.hardware.display.Time; import android.net.Uri; Loading @@ -53,6 +57,7 @@ import android.os.Binder; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings.Secure; import android.provider.Settings.System; Loading @@ -61,7 +66,6 @@ import android.util.Slog; import android.view.SurfaceControl; import android.view.accessibility.AccessibilityManager; import android.view.animation.AnimationUtils; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.ColorDisplayController; Loading @@ -71,7 +75,6 @@ import com.android.server.SystemService; import com.android.server.twilight.TwilightListener; import com.android.server.twilight.TwilightManager; import com.android.server.twilight.TwilightState; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.ref.WeakReference; Loading Loading @@ -944,6 +947,89 @@ public final class ColorDisplayService extends SystemService { .setSaturationLevel(packageName, mCurrentUser, saturationLevel); } private void setColorModeInternal(@ColorMode int colorMode) { if (!isColorModeAvailable(colorMode)) { throw new IllegalArgumentException("Invalid colorMode: " + colorMode); } System.putIntForUser(getContext().getContentResolver(), System.DISPLAY_COLOR_MODE, colorMode, mCurrentUser); } private @ColorMode int getColorModeInternal() { final ContentResolver cr = getContext().getContentResolver(); if (Secure.getIntForUser(cr, Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, mCurrentUser) == 1 || Secure.getIntForUser(cr, Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, mCurrentUser) == 1) { // There are restrictions on the available color modes combined with a11y transforms. if (isColorModeAvailable(COLOR_MODE_SATURATED)) { return COLOR_MODE_SATURATED; } else if (isColorModeAvailable(COLOR_MODE_AUTOMATIC)) { return COLOR_MODE_AUTOMATIC; } } int colorMode = System.getIntForUser(cr, System.DISPLAY_COLOR_MODE, -1, mCurrentUser); if (colorMode == -1) { // There might be a system property controlling color mode that we need to respect; if // not, this will set a suitable default. colorMode = getCurrentColorModeFromSystemProperties(); } // This happens when a color mode is no longer available (e.g., after system update or B&R) // or the device does not support any color mode. if (!isColorModeAvailable(colorMode)) { if (colorMode == COLOR_MODE_BOOSTED && isColorModeAvailable(COLOR_MODE_NATURAL)) { colorMode = COLOR_MODE_NATURAL; } else if (colorMode == COLOR_MODE_SATURATED && isColorModeAvailable(COLOR_MODE_AUTOMATIC)) { colorMode = COLOR_MODE_AUTOMATIC; } else if (colorMode == COLOR_MODE_AUTOMATIC && isColorModeAvailable(COLOR_MODE_SATURATED)) { colorMode = COLOR_MODE_SATURATED; } else { colorMode = -1; } } return colorMode; } /** * Get the current color mode from system properties, or return -1 if invalid. * * See {@link com.android.server.display.DisplayTransformManager} */ private @ColorMode int getCurrentColorModeFromSystemProperties() { final int displayColorSetting = SystemProperties.getInt("persist.sys.sf.native_mode", 0); if (displayColorSetting == 0) { return "1.0".equals(SystemProperties.get("persist.sys.sf.color_saturation")) ? COLOR_MODE_NATURAL : COLOR_MODE_BOOSTED; } else if (displayColorSetting == 1) { return COLOR_MODE_SATURATED; } else if (displayColorSetting == 2) { return COLOR_MODE_AUTOMATIC; } else { return -1; } } private boolean isColorModeAvailable(@ColorMode int colorMode) { final int[] availableColorModes = getContext().getResources().getIntArray( R.array.config_availableColorModes); if (availableColorModes != null) { for (int mode : availableColorModes) { if (mode == colorMode) { return true; } } } return false; } private void dumpInternal(PrintWriter pw) { pw.println("COLOR DISPLAY MANAGER dumpsys (color_display)"); pw.println("Night Display:"); Loading Loading @@ -1445,13 +1531,38 @@ public final class ColorDisplayService extends SystemService { */ public interface ColorTransformController { /** Apply the given saturation (grayscale) matrix to the associated AppWindow. */ /** * Apply the given saturation (grayscale) matrix to the associated AppWindow. */ void applyAppSaturation(@Size(9) float[] matrix, @Size(3) float[] translation); } @VisibleForTesting final class BinderService extends IColorDisplayManager.Stub { @Override public void setColorMode(int colorMode) { getContext().enforceCallingOrSelfPermission( Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS, "Permission required to set display color mode"); final long token = Binder.clearCallingIdentity(); try { setColorModeInternal(colorMode); } finally { Binder.restoreCallingIdentity(token); } } @Override public int getColorMode() { final long token = Binder.clearCallingIdentity(); try { return getColorModeInternal(); } finally { Binder.restoreCallingIdentity(token); } } @Override public boolean isDeviceColorManaged() { final long token = Binder.clearCallingIdentity(); Loading Loading @@ -1640,7 +1751,9 @@ public final class ColorDisplayService extends SystemService { @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return; if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) { return; } final long token = Binder.clearCallingIdentity(); try { Loading