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

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

Merge "Add tint controller for bright color reduction"

parents 25d41144 44a95593
Loading
Loading
Loading
Loading
+86 −16
Original line number Diff line number Diff line
@@ -77,7 +77,6 @@ import com.android.internal.util.DumpUtils;
import com.android.server.DisplayThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemService.TargetUser;
import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
import com.android.server.twilight.TwilightState;
@@ -119,6 +118,7 @@ public final class ColorDisplayService extends SystemService {
    private static final int MSG_APPLY_NIGHT_DISPLAY_ANIMATED = 3;
    private static final int MSG_APPLY_GLOBAL_SATURATION = 4;
    private static final int MSG_APPLY_DISPLAY_WHITE_BALANCE = 5;
    private static final int MSG_APPLY_REDUCE_BRIGHT_COLORS = 6;

    /**
     * Return value if a setting has not been set.
@@ -129,17 +129,6 @@ public final class ColorDisplayService extends SystemService {
     * Evaluator used to animate color matrix transitions.
     */
    private static final ColorMatrixEvaluator COLOR_MATRIX_EVALUATOR = new ColorMatrixEvaluator();

    private final NightDisplayTintController mNightDisplayTintController =
            new NightDisplayTintController();

    @VisibleForTesting
    final DisplayWhiteBalanceTintController mDisplayWhiteBalanceTintController =
            new DisplayWhiteBalanceTintController();

    private final TintController mGlobalSaturationTintController =
            new GlobalSaturationTintController();

    /**
     * Matrix and offset used for converting color to grayscale.
     */
@@ -163,6 +152,16 @@ public final class ColorDisplayService extends SystemService {
            1f, 1f, 1f, 1f
    };

    @VisibleForTesting
    final DisplayWhiteBalanceTintController mDisplayWhiteBalanceTintController =
            new DisplayWhiteBalanceTintController();
    private final NightDisplayTintController mNightDisplayTintController =
            new NightDisplayTintController();
    private final TintController mGlobalSaturationTintController =
            new GlobalSaturationTintController();
    private final ReduceBrightColorsTintController mReduceBrightColorsTintController =
            new ReduceBrightColorsTintController();

    private final Handler mHandler;

    private final AppSaturationController mAppSaturationController = new AppSaturationController();
@@ -354,6 +353,14 @@ public final class ColorDisplayService extends SystemService {
                            case Secure.DISPLAY_WHITE_BALANCE_ENABLED:
                                updateDisplayWhiteBalanceStatus();
                                break;
                            case Secure.REDUCE_BRIGHT_COLORS_ACTIVATED:
                                onReduceBrightColorsActivationChanged();
                                mHandler.sendEmptyMessage(MSG_APPLY_REDUCE_BRIGHT_COLORS);
                                break;
                            case Secure.REDUCE_BRIGHT_COLORS_LEVEL:
                                onReduceBrightColorsStrengthLevelChanged();
                                mHandler.sendEmptyMessage(MSG_APPLY_REDUCE_BRIGHT_COLORS);
                                break;
                        }
                    }
                }
@@ -372,17 +379,19 @@ public final class ColorDisplayService extends SystemService {
                false /* notifyForDescendants */, mContentObserver, mCurrentUser);
        cr.registerContentObserver(System.getUriFor(System.DISPLAY_COLOR_MODE),
                false /* notifyForDescendants */, mContentObserver, mCurrentUser);
        cr.registerContentObserver(
                Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED),
        cr.registerContentObserver(Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED),
                false /* notifyForDescendants */, mContentObserver, mCurrentUser);
        cr.registerContentObserver(
                Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED),
                false /* notifyForDescendants */, mContentObserver, mCurrentUser);
        cr.registerContentObserver(
                Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_DALTONIZER),
        cr.registerContentObserver(Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_DALTONIZER),
                false /* notifyForDescendants */, mContentObserver, mCurrentUser);
        cr.registerContentObserver(Secure.getUriFor(Secure.DISPLAY_WHITE_BALANCE_ENABLED),
                false /* notifyForDescendants */, mContentObserver, mCurrentUser);
        cr.registerContentObserver(Secure.getUriFor(Secure.REDUCE_BRIGHT_COLORS_ACTIVATED),
                false /* notifyForDescendants */, mContentObserver, mCurrentUser);
        cr.registerContentObserver(Secure.getUriFor(Secure.REDUCE_BRIGHT_COLORS_LEVEL),
                false /* notifyForDescendants */, mContentObserver, mCurrentUser);

        // Apply the accessibility settings first, since they override most other settings.
        onAccessibilityInversionChanged();
@@ -420,6 +429,17 @@ public final class ColorDisplayService extends SystemService {

            updateDisplayWhiteBalanceStatus();
        }

        if (mReduceBrightColorsTintController.isAvailable(getContext())) {
            mReduceBrightColorsTintController
                    .setUp(getContext(), DisplayTransformManager.needsLinearColorMatrix());
            onReduceBrightColorsStrengthLevelChanged();
            final boolean reset = resetReduceBrightColors();
            if (!reset) {
                onReduceBrightColorsActivationChanged();
                mHandler.sendEmptyMessage(MSG_APPLY_REDUCE_BRIGHT_COLORS);
            }
        }
    }

    private void tearDown() {
@@ -444,6 +464,27 @@ public final class ColorDisplayService extends SystemService {
        if (mGlobalSaturationTintController.isAvailable(getContext())) {
            mGlobalSaturationTintController.setActivated(null);
        }

        if (mReduceBrightColorsTintController.isAvailable(getContext())) {
            mReduceBrightColorsTintController.setActivated(null);
        }
    }

    private boolean resetReduceBrightColors() {
        if (mCurrentUser == UserHandle.USER_NULL) {
            return false;
        }

        final boolean isSettingActivated = Secure.getIntForUser(getContext().getContentResolver(),
                Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 0, mCurrentUser) == 1;
        final boolean shouldResetOnReboot = Secure.getIntForUser(getContext().getContentResolver(),
                Secure.REDUCE_BRIGHT_COLORS_PERSIST_ACROSS_REBOOTS, 0, mCurrentUser) == 0;
        if (isSettingActivated && mReduceBrightColorsTintController.isActivatedStateNotSet()
                && shouldResetOnReboot) {
            return Secure.putIntForUser(getContext().getContentResolver(),
                    Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 0, mCurrentUser);
        }
        return false;
    }

    private void onNightDisplayAutoModeChanged(int autoMode) {
@@ -572,6 +613,24 @@ public final class ColorDisplayService extends SystemService {
                isAccessiblityInversionEnabled() ? MATRIX_INVERT_COLOR : null);
    }

    private void onReduceBrightColorsActivationChanged() {
        if (mCurrentUser == UserHandle.USER_NULL) {
            return;
        }
        mReduceBrightColorsTintController.setActivated(
                Secure.getIntForUser(getContext().getContentResolver(),
                        Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 0, mCurrentUser) == 1);
    }

    private void onReduceBrightColorsStrengthLevelChanged() {
        if (mCurrentUser == UserHandle.USER_NULL) {
            return;
        }
        mReduceBrightColorsTintController.setMatrix(
                Secure.getIntForUser(getContext().getContentResolver(),
                        Secure.REDUCE_BRIGHT_COLORS_LEVEL, 0, mCurrentUser));
    }

    /**
     * Applies current color temperature matrix, or removes it if deactivated.
     *
@@ -937,6 +996,14 @@ public final class ColorDisplayService extends SystemService {
            pw.println("    Not available");
        }

        pw.println("Reduce bright colors:");
        if (mReduceBrightColorsTintController.isAvailable(getContext())) {
            pw.println("    Activated: " + mReduceBrightColorsTintController.isActivated());
            mReduceBrightColorsTintController.dump(pw);
        } else {
            pw.println("    Not available");
        }

        pw.println("Color mode: " + getColorModeInternal());
    }

@@ -1438,6 +1505,9 @@ public final class ColorDisplayService extends SystemService {
                    mGlobalSaturationTintController.setMatrix(msg.arg1);
                    applyTint(mGlobalSaturationTintController, false);
                    break;
                case MSG_APPLY_REDUCE_BRIGHT_COLORS:
                    applyTint(mReduceBrightColorsTintController, true);
                    break;
                case MSG_APPLY_NIGHT_DISPLAY_IMMEDIATE:
                    applyTint(mNightDisplayTintController, true);
                    break;
+5 −1
Original line number Diff line number Diff line
@@ -58,6 +58,10 @@ public class DisplayTransformManager {
     * Color transform level used by A11y services to make the display monochromatic.
     */
    public static final int LEVEL_COLOR_MATRIX_GRAYSCALE = 200;
    /**
     * Color transform level used by A11y services to reduce bright colors.
     */
    public static final int LEVEL_COLOR_MATRIX_REDUCE_BRIGHT_COLORS = 250;
    /**
     * Color transform level used by A11y services to invert the display colors.
     */
@@ -97,7 +101,7 @@ public class DisplayTransformManager {
     * Map of level -> color transformation matrix.
     */
    @GuardedBy("mColorMatrix")
    private final SparseArray<float[]> mColorMatrix = new SparseArray<>(5);
    private final SparseArray<float[]> mColorMatrix = new SparseArray<>(6);
    /**
     * Temporary matrix used internally by {@link #computeColorMatrixLocked()}.
     */
+113 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.server.display.color;

import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_REDUCE_BRIGHT_COLORS;

import android.content.Context;
import android.hardware.display.ColorDisplayManager;
import android.opengl.Matrix;
import android.util.Slog;

import com.android.internal.R;

import java.io.PrintWriter;
import java.util.Arrays;

/**
 * Control the color transform for bright color reduction.
 */
public class ReduceBrightColorsTintController extends TintController {

    private final float[] mMatrix = new float[16];
    private final float[] mCoefficients = new float[9];

    private int mStrength;

    @Override
    public void setUp(Context context, boolean needsLinear) {
        final String[] coefficients = context.getResources().getStringArray(
                needsLinear ? R.array.config_reduceBrightColorsCoefficients
                        : R.array.config_reduceBrightColorsCoefficientsNative);
        for (int i = 0; i < 9 && i < coefficients.length; i++) {
            mCoefficients[i] = Float.parseFloat(coefficients[i]);
        }
    }

    @Override
    public float[] getMatrix() {
        return isActivated() ? Arrays.copyOf(mMatrix, mMatrix.length)
                : ColorDisplayService.MATRIX_IDENTITY;
    }

    @Override
    public void setMatrix(int strengthLevel) {
        // Clamp to valid range.
        if (strengthLevel < 0) {
            strengthLevel = 0;
        } else if (strengthLevel > 100) {
            strengthLevel = 100;
        }
        Slog.d(ColorDisplayService.TAG, "Setting bright color reduction level: " + strengthLevel);
        mStrength = strengthLevel;

        Matrix.setIdentityM(mMatrix, 0);

        final float percentageStrength = strengthLevel / 100f;
        final float squaredPercentageStrength = percentageStrength * percentageStrength;
        final float red =
                squaredPercentageStrength * mCoefficients[0] + percentageStrength * mCoefficients[1]
                        + mCoefficients[2];
        final float green =
                squaredPercentageStrength * mCoefficients[3] + percentageStrength * mCoefficients[4]
                        + mCoefficients[5];
        final float blue =
                squaredPercentageStrength * mCoefficients[6] + percentageStrength * mCoefficients[7]
                        + mCoefficients[8];
        mMatrix[0] = clamp(red);
        mMatrix[5] = clamp(green);
        mMatrix[10] = clamp(blue);
    }

    private float clamp(float value) {
        if (value > 1f) {
            return 1f;
        } else if (value < 0f) {
            return 0f;
        }
        return value;
    }

    @Override
    public void dump(PrintWriter pw) {
        pw.println("    mStrength = " + mStrength);
    }

    @Override
    public int getLevel() {
        return LEVEL_COLOR_MATRIX_REDUCE_BRIGHT_COLORS;
    }

    @Override
    public boolean isAvailable(Context context) {
        return ColorDisplayManager.isColorTransformAccelerated(context);
    }

    public int getStrength() {
        return mStrength;
    }
}