Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 69aab0df authored by Christine Franks's avatar Christine Franks Committed by Android (Google) Code Review
Browse files

Merge "Move color modes to ColorDisplayService"

parents 448a1d5c d154fe5d
Loading
Loading
Loading
Loading
+84 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -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.
     *
@@ -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();
@@ -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();
+3 −0
Original line number Diff line number Diff line
@@ -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
+3 −3
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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
+3 −147
Original line number Diff line number Diff line
@@ -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;
@@ -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;

/**
@@ -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;
@@ -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();
    }

    /**
@@ -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);
    }

    /**
@@ -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);
@@ -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;
            }
        }
    }
@@ -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);
            }
        }
    }
@@ -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) {}
    }
}
+126 −13
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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:");
@@ -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();
@@ -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