2 * Copyright (C) 2013 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.server.accessibility;
19 import android.content.ContentResolver;
20 import android.content.Context;
21 import android.opengl.Matrix;
22 import android.os.IBinder;
23 import android.os.Parcel;
24 import android.os.RemoteException;
25 import android.os.ServiceManager;
26 import android.provider.Settings;
27 import android.util.Slog;
28 import android.view.accessibility.AccessibilityManager;
31 * Utility methods for performing accessibility display adjustments.
33 class DisplayAdjustmentUtils {
34 private static final String LOG_TAG = DisplayAdjustmentUtils.class.getSimpleName();
36 /** Matrix and offset used for converting color to gray-scale. */
37 private static final float[] GRAYSCALE_MATRIX = new float[] {
38 .2126f, .2126f, .2126f, 0,
39 .7152f, .7152f, .7152f, 0,
40 .0722f, .0722f, .0722f, 0,
44 /** Matrix and offset used for value-only display inversion. */
45 private static final float[] INVERSION_MATRIX_VALUE_ONLY = new float[] {
52 /** Default inversion mode for display color correction. */
53 private static final int DEFAULT_DISPLAY_DALTONIZER =
54 AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY;
57 * Returns whether the specified user with has any display color
60 public static boolean hasAdjustments(Context context, int userId) {
61 final ContentResolver cr = context.getContentResolver();
63 boolean hasColorTransform = Settings.Secure.getIntForUser(
64 cr, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, userId) == 1;
66 if (!hasColorTransform) {
67 hasColorTransform |= Settings.Secure.getIntForUser(
68 cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, userId) == 1;
71 return hasColorTransform;
75 * Applies the specified user's display color adjustments.
77 public static void applyAdjustments(Context context, int userId) {
78 final ContentResolver cr = context.getContentResolver();
79 float[] colorMatrix = new float[16];
80 float[] outputMatrix = new float[16];
81 boolean hasColorTransform = false;
83 Matrix.setIdentityM(colorMatrix, 0);
85 final boolean inversionEnabled = Settings.Secure.getIntForUser(
86 cr, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, userId) == 1;
87 if (inversionEnabled) {
88 final float[] inversionMatrix = INVERSION_MATRIX_VALUE_ONLY;
89 Matrix.multiplyMM(outputMatrix, 0, colorMatrix, 0, inversionMatrix, 0);
91 colorMatrix = outputMatrix;
92 outputMatrix = colorMatrix;
94 hasColorTransform = true;
97 final boolean daltonizerEnabled = Settings.Secure.getIntForUser(
98 cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, userId) != 0;
99 if (daltonizerEnabled) {
100 final int daltonizerMode = Settings.Secure.getIntForUser(cr,
101 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, DEFAULT_DISPLAY_DALTONIZER,
103 // Monochromacy isn't supported by the native Daltonizer.
104 if (daltonizerMode == AccessibilityManager.DALTONIZER_SIMULATE_MONOCHROMACY) {
105 Matrix.multiplyMM(outputMatrix, 0, colorMatrix, 0, GRAYSCALE_MATRIX, 0);
107 final float[] temp = colorMatrix;
108 colorMatrix = outputMatrix;
111 hasColorTransform = true;
112 nativeSetDaltonizerMode(AccessibilityManager.DALTONIZER_DISABLED);
114 nativeSetDaltonizerMode(daltonizerMode);
117 nativeSetDaltonizerMode(AccessibilityManager.DALTONIZER_DISABLED);
120 if (hasColorTransform) {
121 nativeSetColorTransform(colorMatrix);
123 nativeSetColorTransform(null);
128 * Sets the surface flinger's Daltonization mode. This adjusts the color
129 * space to correct for or simulate various types of color blindness.
131 * @param mode new Daltonization mode
133 private static void nativeSetDaltonizerMode(int mode) {
135 final IBinder flinger = ServiceManager.getService("SurfaceFlinger");
136 if (flinger != null) {
137 final Parcel data = Parcel.obtain();
138 data.writeInterfaceToken("android.ui.ISurfaceComposer");
140 flinger.transact(1014, data, null, 0);
143 } catch (RemoteException ex) {
144 Slog.e(LOG_TAG, "Failed to set Daltonizer mode", ex);
149 * Sets the surface flinger's color transformation as a 4x4 matrix. If the
150 * matrix is null, color transformations are disabled.
152 * @param m the float array that holds the transformation matrix, or null to
153 * disable transformation
155 private static void nativeSetColorTransform(float[] m) {
157 final IBinder flinger = ServiceManager.getService("SurfaceFlinger");
158 if (flinger != null) {
159 final Parcel data = Parcel.obtain();
160 data.writeInterfaceToken("android.ui.ISurfaceComposer");
163 for (int i = 0; i < 16; i++) {
164 data.writeFloat(m[i]);
169 flinger.transact(1015, data, null, 0);
172 } catch (RemoteException ex) {
173 Slog.e(LOG_TAG, "Failed to set color transform", ex);