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

Commit a9097fed authored by Isaac Chai's avatar Isaac Chai
Browse files

Add feature flag, and support for new secure settings in framework

The secure setting is only updated and guarded with feature flag.
Reason for single update rather than 2 separate API to update level vs
mode : In Daltonizer.cpp either of the change requires re-calculation of
all matrices (current implementation). We can optimize further later
once we have basic functionality implemented and working.

Test: Locally tested
Bug: 322829049
Flag: com.android.server.accessibility.enable_color_correction_saturation

Change-Id: Ic919c7f01ce4723ecf933b7bdc25a530e372f5ae
parent 8662d824
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -183,3 +183,10 @@ flag {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "enable_color_correction_saturation"
    namespace: "accessibility"
    description: "Feature allows users to change color correction saturation for daltonizer."
    bug: "322829049"
}
 No newline at end of file
+26 −5
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ 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.accessibility.Flags;
import com.android.server.display.feature.DisplayManagerFlags;
import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
@@ -356,6 +357,11 @@ public final class ColorDisplayService extends SystemService {
                            case Secure.ACCESSIBILITY_DISPLAY_DALTONIZER:
                                onAccessibilityDaltonizerChanged();
                                break;
                            case Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_SATURATION_LEVEL:
                                if (Flags.enableColorCorrectionSaturation()) {
                                    onAccessibilityDaltonizerChanged();
                                }
                                break;
                            case Secure.DISPLAY_WHITE_BALANCE_ENABLED:
                                updateDisplayWhiteBalanceStatus();
                                break;
@@ -398,6 +404,11 @@ public final class ColorDisplayService extends SystemService {
                false /* notifyForDescendants */, mContentObserver, mCurrentUser);
        cr.registerContentObserver(Secure.getUriFor(Secure.REDUCE_BRIGHT_COLORS_LEVEL),
                false /* notifyForDescendants */, mContentObserver, mCurrentUser);
        if (Flags.enableColorCorrectionSaturation()) {
            cr.registerContentObserver(
                    Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_SATURATION_LEVEL),
                    false /* notifyForDescendants */, mContentObserver, mCurrentUser);
        }

        // Apply the accessibility settings first, since they override most other settings.
        onAccessibilityInversionChanged();
@@ -597,21 +608,31 @@ public final class ColorDisplayService extends SystemService {
        if (mCurrentUser == UserHandle.USER_NULL) {
            return;
        }
        var contentResolver = getContext().getContentResolver();
        final int daltonizerMode = isAccessiblityDaltonizerEnabled()
                ? Secure.getIntForUser(getContext().getContentResolver(),
                ? Secure.getIntForUser(contentResolver,
                Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
                AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY, mCurrentUser)
                : AccessibilityManager.DALTONIZER_DISABLED;

        int saturation = NOT_SET;
        if (Flags.enableColorCorrectionSaturation()) {
            saturation = Secure.getIntForUser(
                    contentResolver,
                    Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_SATURATION_LEVEL,
                    NOT_SET,
                    mCurrentUser);
        }

        final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
        if (daltonizerMode == AccessibilityManager.DALTONIZER_SIMULATE_MONOCHROMACY) {
            // Monochromacy isn't supported by the native Daltonizer implementation; use grayscale.
            dtm.setColorMatrix(DisplayTransformManager.LEVEL_COLOR_MATRIX_GRAYSCALE,
                    MATRIX_GRAYSCALE);
            dtm.setDaltonizerMode(AccessibilityManager.DALTONIZER_DISABLED);
            dtm.setDaltonizerMode(AccessibilityManager.DALTONIZER_DISABLED, saturation);
        } else {
            dtm.setColorMatrix(DisplayTransformManager.LEVEL_COLOR_MATRIX_GRAYSCALE, null);
            dtm.setDaltonizerMode(daltonizerMode);
            dtm.setDaltonizerMode(daltonizerMode, saturation);
        }
    }

+17 −6
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.display.color;

import android.annotation.IntRange;
import android.app.ActivityTaskManager;
import android.hardware.display.ColorDisplayManager;
import android.opengl.Matrix;
@@ -111,9 +112,15 @@ public class DisplayTransformManager {
    /**
     * Lock used for synchronize access to {@link #mDaltonizerMode}.
     */
    private final Object mDaltonizerModeLock = new Object();
    @VisibleForTesting
    final Object mDaltonizerModeLock = new Object();
    @VisibleForTesting
    @GuardedBy("mDaltonizerModeLock")
    int mDaltonizerMode = -1;

    @VisibleForTesting
    @GuardedBy("mDaltonizerModeLock")
    private int mDaltonizerMode = -1;
    int mDaltonizerLevel = -1;

    private static final IBinder sFlinger = ServiceManager.getService(SURFACE_FLINGER);

@@ -168,12 +175,15 @@ public class DisplayTransformManager {
     * various types of color blindness.
     *
     * @param mode the new Daltonization mode, or -1 to disable
     * @param level the level of saturation for color correction [-1,10] inclusive. -1 for when
     *              it is not set.
     */
    public void setDaltonizerMode(int mode) {
    public void setDaltonizerMode(int mode, @IntRange(from = -1, to = 10) int level) {
        synchronized (mDaltonizerModeLock) {
            if (mDaltonizerMode != mode) {
            if (mDaltonizerMode != mode || mDaltonizerLevel != level) {
                mDaltonizerMode = mode;
                applyDaltonizerMode(mode);
                mDaltonizerLevel = level;
                applyDaltonizerMode(mode, level);
            }
        }
    }
@@ -223,10 +233,11 @@ public class DisplayTransformManager {
    /**
     * Propagates the provided Daltonization mode to the SurfaceFlinger.
     */
    private static void applyDaltonizerMode(int mode) {
    private static void applyDaltonizerMode(int mode, int level) {
        final Parcel data = Parcel.obtain();
        data.writeInterfaceToken("android.ui.ISurfaceComposer");
        data.writeInt(mode);
        data.writeInt(level);
        try {
            sFlinger.transact(SURFACE_FLINGER_TRANSACTION_DALTONIZER, data, null, 0);
        } catch (RemoteException ex) {
+16 −0
Original line number Diff line number Diff line
@@ -161,4 +161,20 @@ public class DisplayTransformManagerTest {
                .isEqualTo(Integer.toString(testPropertyValue));
    }

    @Test
    public void daltonizer_defaultValues() {
        synchronized (mDtm.mDaltonizerModeLock) {
            assertThat(mDtm.mDaltonizerMode).isEqualTo(-1);
            assertThat(mDtm.mDaltonizerLevel).isEqualTo(-1);
        }
    }

    @Test
    public void setDaltonizerMode_newValues_valuesUpdated() {
        mDtm.setDaltonizerMode(0, 0);
        synchronized (mDtm.mDaltonizerModeLock) {
            assertThat(mDtm.mDaltonizerMode).isEqualTo(0);
            assertThat(mDtm.mDaltonizerLevel).isEqualTo(0);
        }
    }
}