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

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

Merge "Move a11y color transforms to ColorDisplayService"

parents 2ba0d6ff 9114f46d
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -104,6 +104,16 @@ public final class ColorDisplayManager {
        return context.getResources().getBoolean(R.bool.config_displayWhiteBalanceAvailable);
    }

    /**
     * Check if the color transforms are color accelerated. Some transforms are experimental only
     * on non-accelerated platforms due to the performance implications.
     *
     * @hide
     */
    public static boolean isColorTransformAccelerated(Context context) {
        return context.getResources().getBoolean(R.bool.config_setColorTransformAccelerated);
    }

    private static class ColorDisplayManagerInternal {

        private static ColorDisplayManagerInternal sInstance;
+8 −37
Original line number Diff line number Diff line
@@ -16,6 +16,11 @@

package com.android.server.accessibility;

import static android.accessibilityservice.AccessibilityService.SHOW_MODE_AUTO;
import static android.accessibilityservice.AccessibilityService.SHOW_MODE_HARD_KEYBOARD_ORIGINAL_VALUE;
import static android.accessibilityservice.AccessibilityService.SHOW_MODE_HARD_KEYBOARD_OVERRIDDEN;
import static android.accessibilityservice.AccessibilityService.SHOW_MODE_HIDDEN;
import static android.accessibilityservice.AccessibilityService.SHOW_MODE_IGNORE_HARD_KEYBOARD;
import static android.accessibilityservice.AccessibilityService.SHOW_MODE_MASK;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
import static android.view.accessibility.AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED;
@@ -23,13 +28,9 @@ import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBIL
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;

import static com.android.internal.util.FunctionalUtils.ignoreRemoteException;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import static android.accessibilityservice.AccessibilityService.SHOW_MODE_AUTO;
import static android.accessibilityservice.AccessibilityService.SHOW_MODE_HIDDEN;
import static android.accessibilityservice.AccessibilityService.SHOW_MODE_IGNORE_HARD_KEYBOARD;
import static android.accessibilityservice.AccessibilityService.SHOW_MODE_HARD_KEYBOARD_ORIGINAL_VALUE;
import static android.accessibilityservice.AccessibilityService.SHOW_MODE_HARD_KEYBOARD_OVERRIDDEN;

import android.Manifest;
import android.accessibilityservice.AccessibilityService;
@@ -121,6 +122,8 @@ import com.android.server.SystemService;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowManagerInternal;

import libcore.util.EmptyArray;

import org.xmlpull.v1.XmlPullParserException;

import java.io.FileDescriptor;
@@ -139,8 +142,6 @@ import java.util.Set;
import java.util.function.Consumer;
import java.util.function.IntSupplier;

import libcore.util.EmptyArray;

/**
 * This class is instantiated by the system as a system level service and can be
 * accessed only by the system. The task of this service is to be a centralized
@@ -1827,8 +1828,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
        updateFilterKeyEventsLocked(userState);
        updateTouchExplorationLocked(userState);
        updatePerformGesturesLocked(userState);
        updateDisplayDaltonizerLocked(userState);
        updateDisplayInversionLocked(userState);
        updateMagnificationLocked(userState);
        scheduleUpdateFingerprintGestureHandling(userState);
        scheduleUpdateInputFilter(userState);
@@ -2187,14 +2186,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
        return false;
    }

    private void updateDisplayDaltonizerLocked(UserState userState) {
        DisplayAdjustmentUtils.applyDaltonizerSetting(mContext, userState.mUserId);
    }

    private void updateDisplayInversionLocked(UserState userState) {
        DisplayAdjustmentUtils.applyInversionSetting(mContext, userState.mUserId);
    }

    private void updateMagnificationLocked(UserState userState) {
        if (userState.mUserId != mCurrentUserId) {
            return;
@@ -4104,15 +4095,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
        private final Uri mTouchExplorationGrantedAccessibilityServicesUri = Settings.Secure
                .getUriFor(Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES);

        private final Uri mDisplayInversionEnabledUri = Settings.Secure.getUriFor(
                Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);

        private final Uri mDisplayDaltonizerEnabledUri = Settings.Secure.getUriFor(
                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED);

        private final Uri mDisplayDaltonizerUri = Settings.Secure.getUriFor(
                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER);

        private final Uri mHighTextContrastUri = Settings.Secure.getUriFor(
                Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED);

@@ -4152,12 +4134,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
            contentResolver.registerContentObserver(
                    mTouchExplorationGrantedAccessibilityServicesUri,
                    false, this, UserHandle.USER_ALL);
            contentResolver.registerContentObserver(
                    mDisplayInversionEnabledUri, false, this, UserHandle.USER_ALL);
            contentResolver.registerContentObserver(
                    mDisplayDaltonizerEnabledUri, false, this, UserHandle.USER_ALL);
            contentResolver.registerContentObserver(
                    mDisplayDaltonizerUri, false, this, UserHandle.USER_ALL);
            contentResolver.registerContentObserver(
                    mHighTextContrastUri, false, this, UserHandle.USER_ALL);
            contentResolver.registerContentObserver(
@@ -4202,11 +4178,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
                    if (readTouchExplorationGrantedAccessibilityServicesLocked(userState)) {
                        onUserStateChangedLocked(userState);
                    }
                } else if (mDisplayDaltonizerEnabledUri.equals(uri)
                        || mDisplayDaltonizerUri.equals(uri)) {
                    updateDisplayDaltonizerLocked(userState);
                } else if (mDisplayInversionEnabledUri.equals(uri)) {
                    updateDisplayInversionLocked(userState);
                } else if (mHighTextContrastUri.equals(uri)) {
                    if (readHighTextContrastEnabledSettingLocked(userState)) {
                        onUserStateChangedLocked(userState);
+0 −102
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 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.accessibility;

import android.content.ContentResolver;
import android.content.Context;
import android.os.Binder;
import android.provider.Settings.Secure;
import android.view.accessibility.AccessibilityManager;

import com.android.server.LocalServices;
import com.android.server.display.DisplayTransformManager;

/**
 * Utility methods for performing accessibility display adjustments.
 */
class DisplayAdjustmentUtils {

    /** Default inversion mode for display color correction. */
    private static final int DEFAULT_DISPLAY_DALTONIZER =
            AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY;

    /** Matrix and offset used for converting color to gray-scale. */
    private static final float[] MATRIX_GRAYSCALE = new float[] {
        .2126f, .2126f, .2126f, 0,
        .7152f, .7152f, .7152f, 0,
        .0722f, .0722f, .0722f, 0,
             0,      0,      0, 1
    };

    /**
     * Matrix and offset used for luminance inversion. Represents a transform
     * from RGB to YIQ color space, rotation around the Y axis by 180 degrees,
     * transform back to RGB color space, and subtraction from 1. The last row
     * represents a non-multiplied addition, see surfaceflinger's ProgramCache
     * for full implementation details.
     */
    private static final float[] MATRIX_INVERT_COLOR = new float[] {
        0.402f, -0.598f, -0.599f, 0,
       -1.174f, -0.174f, -1.175f, 0,
       -0.228f, -0.228f,  0.772f, 0,
             1,       1,       1, 1
    };

    public static void applyDaltonizerSetting(Context context, int userId) {
        final ContentResolver cr = context.getContentResolver();
        final DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class);

        int daltonizerMode = AccessibilityManager.DALTONIZER_DISABLED;
        long identity = Binder.clearCallingIdentity();
        try {
            if (Secure.getIntForUser(cr,
                    Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, userId) != 0) {
                daltonizerMode = Secure.getIntForUser(cr,
                        Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, DEFAULT_DISPLAY_DALTONIZER, userId);
            }
        } finally {
            Binder.restoreCallingIdentity(identity);
        }

        float[] grayscaleMatrix = null;
        if (daltonizerMode == AccessibilityManager.DALTONIZER_SIMULATE_MONOCHROMACY) {
            // Monochromacy isn't supported by the native Daltonizer.
            grayscaleMatrix = MATRIX_GRAYSCALE;
            daltonizerMode = AccessibilityManager.DALTONIZER_DISABLED;
        }
        dtm.setColorMatrix(DisplayTransformManager.LEVEL_COLOR_MATRIX_GRAYSCALE, grayscaleMatrix);
        dtm.setDaltonizerMode(daltonizerMode);
    }

    /**
     * Applies the specified user's display color adjustments.
     */
    public static void applyInversionSetting(Context context, int userId) {
        final ContentResolver cr = context.getContentResolver();
        final DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class);

        long identity = Binder.clearCallingIdentity();
        try {
            final boolean invertColors = Secure.getIntForUser(cr,
                    Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, userId) != 0;
            dtm.setColorMatrix(DisplayTransformManager.LEVEL_COLOR_MATRIX_INVERT_COLOR,
                    invertColors ? MATRIX_INVERT_COLOR : null);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }
}
+70 −3
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import android.provider.Settings.Secure;
import android.provider.Settings.System;
import android.util.MathUtils;
import android.util.Slog;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.AnimationUtils;

import com.android.internal.R;
@@ -402,6 +403,29 @@ public final class ColorDisplayService extends SystemService {
        }
    };

    /**
     * Matrix and offset used for converting color to grayscale.
     */
    private static final float[] MATRIX_GRAYSCALE = new float[]{
            .2126f, .2126f, .2126f, 0f,
            .7152f, .7152f, .7152f, 0f,
            .0722f, .0722f, .0722f, 0f,
            0f, 0f, 0f, 1f
    };

    /**
     * Matrix and offset used for luminance inversion. Represents a transform from RGB to YIQ color
     * space, rotation around the Y axis by 180 degrees, transform back to RGB color space, and
     * subtraction from 1. The last row represents a non-multiplied addition, see surfaceflinger's
     * ProgramCache for full implementation details.
     */
    private static final float[] MATRIX_INVERT_COLOR = new float[] {
            0.402f, -0.598f, -0.599f, 0f,
            -1.174f, -0.174f, -1.175f, 0f,
            -0.228f, -0.228f, 0.772f, 0f,
            1f, 1f, 1f, 1f
    };

    private final Handler mHandler;

    private final AppSaturationController mAppSaturationController = new AppSaturationController();
@@ -543,9 +567,16 @@ public final class ColorDisplayService extends SystemService {
                            case System.DISPLAY_COLOR_MODE:
                                onDisplayColorModeChanged(mNightDisplayController.getColorMode());
                                break;
                            case Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED:
                            case Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED:
                                onAccessibilityTransformChanged();
                                onAccessibilityInversionChanged();
                                onAccessibilityActivated();
                                break;
                            case Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED:
                                onAccessibilityDaltonizerChanged();
                                onAccessibilityActivated();
                                break;
                            case Secure.ACCESSIBILITY_DISPLAY_DALTONIZER:
                                onAccessibilityDaltonizerChanged();
                                break;
                            case Secure.DISPLAY_WHITE_BALANCE_ENABLED:
                                updateDisplayWhiteBalanceStatus();
@@ -574,6 +605,9 @@ public final class ColorDisplayService extends SystemService {
        cr.registerContentObserver(
                Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED),
                false /* notifyForDescendants */, mContentObserver, mCurrentUser);
        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);

@@ -704,10 +738,43 @@ public final class ColorDisplayService extends SystemService {
        dtm.setColorMode(mode, mNightDisplayTintController.getMatrix());
    }

    private void onAccessibilityTransformChanged() {
    private void onAccessibilityActivated() {
        onDisplayColorModeChanged(mNightDisplayController.getColorMode());
    }

    /**
     * Apply the accessibility daltonizer transform based on the settings value.
     */
    private void onAccessibilityDaltonizerChanged() {
        final boolean enabled = Secure.getIntForUser(getContext().getContentResolver(),
                Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, mCurrentUser) != 0;
        final int daltonizerMode = enabled ? Secure.getIntForUser(getContext().getContentResolver(),
                Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
                AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY, mCurrentUser)
                : AccessibilityManager.DALTONIZER_DISABLED;

        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);
        } else {
            dtm.setColorMatrix(DisplayTransformManager.LEVEL_COLOR_MATRIX_GRAYSCALE, null);
            dtm.setDaltonizerMode(daltonizerMode);
        }
    }

    /**
     * Apply the accessibility inversion transform based on the settings value.
     */
    private void onAccessibilityInversionChanged() {
        final boolean enabled = Secure.getIntForUser(getContext().getContentResolver(),
                Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, mCurrentUser) != 0;
        final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
        dtm.setColorMatrix(DisplayTransformManager.LEVEL_COLOR_MATRIX_INVERT_COLOR,
                enabled ? MATRIX_INVERT_COLOR : null);
    }

    /**
     * Applies current color temperature matrix, or removes it if deactivated.