1f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette/* 2f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette * Copyright (C) 2013 The Android Open Source Project 3f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette * 4f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette * Licensed under the Apache License, Version 2.0 (the "License"); 5f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette * you may not use this file except in compliance with the License. 6f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette * You may obtain a copy of the License at 7f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette * 8f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette * http://www.apache.org/licenses/LICENSE-2.0 9f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette * 10f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette * Unless required by applicable law or agreed to in writing, software 11f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette * distributed under the License is distributed on an "AS IS" BASIS, 12f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette * See the License for the specific language governing permissions and 14f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette * limitations under the License. 15f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette */ 16f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette 17f242659afc6539f9f1104833a88e37b5f9203417Alan Viverettepackage com.android.server.accessibility; 18f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette 19f242659afc6539f9f1104833a88e37b5f9203417Alan Viveretteimport android.content.ContentResolver; 20f242659afc6539f9f1104833a88e37b5f9203417Alan Viveretteimport android.content.Context; 21af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaverimport android.os.Binder; 2222eb19939d815856887f1329f41aa04b397505ffJustin Klaassenimport android.provider.Settings.Secure; 23f242659afc6539f9f1104833a88e37b5f9203417Alan Viveretteimport android.view.accessibility.AccessibilityManager; 24f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette 2522eb19939d815856887f1329f41aa04b397505ffJustin Klaassenimport com.android.server.LocalServices; 2622eb19939d815856887f1329f41aa04b397505ffJustin Klaassenimport com.android.server.display.DisplayTransformManager; 2722eb19939d815856887f1329f41aa04b397505ffJustin Klaassen 28f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette/** 29f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette * Utility methods for performing accessibility display adjustments. 30f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette */ 31f242659afc6539f9f1104833a88e37b5f9203417Alan Viveretteclass DisplayAdjustmentUtils { 3222eb19939d815856887f1329f41aa04b397505ffJustin Klaassen 3322eb19939d815856887f1329f41aa04b397505ffJustin Klaassen /** Default inversion mode for display color correction. */ 3422eb19939d815856887f1329f41aa04b397505ffJustin Klaassen private static final int DEFAULT_DISPLAY_DALTONIZER = 3522eb19939d815856887f1329f41aa04b397505ffJustin Klaassen AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY; 36f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette 37f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette /** Matrix and offset used for converting color to gray-scale. */ 3822eb19939d815856887f1329f41aa04b397505ffJustin Klaassen private static final float[] MATRIX_GRAYSCALE = new float[] { 39f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette .2126f, .2126f, .2126f, 0, 40f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette .7152f, .7152f, .7152f, 0, 41f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette .0722f, .0722f, .0722f, 0, 42f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette 0, 0, 0, 1 43f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette }; 44f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette 456437518061fc8718590e0272ed17ea64710d2299Alan Viverette /** 466437518061fc8718590e0272ed17ea64710d2299Alan Viverette * Matrix and offset used for luminance inversion. Represents a transform 476437518061fc8718590e0272ed17ea64710d2299Alan Viverette * from RGB to YIQ color space, rotation around the Y axis by 180 degrees, 486437518061fc8718590e0272ed17ea64710d2299Alan Viverette * transform back to RGB color space, and subtraction from 1. The last row 496437518061fc8718590e0272ed17ea64710d2299Alan Viverette * represents a non-multiplied addition, see surfaceflinger's ProgramCache 506437518061fc8718590e0272ed17ea64710d2299Alan Viverette * for full implementation details. 516437518061fc8718590e0272ed17ea64710d2299Alan Viverette */ 5222eb19939d815856887f1329f41aa04b397505ffJustin Klaassen private static final float[] MATRIX_INVERT_COLOR = new float[] { 536437518061fc8718590e0272ed17ea64710d2299Alan Viverette 0.402f, -0.598f, -0.599f, 0, 546437518061fc8718590e0272ed17ea64710d2299Alan Viverette -1.174f, -0.174f, -1.175f, 0, 556437518061fc8718590e0272ed17ea64710d2299Alan Viverette -0.228f, -0.228f, 0.772f, 0, 566437518061fc8718590e0272ed17ea64710d2299Alan Viverette 1, 1, 1, 1 57f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette }; 58f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette 5922eb19939d815856887f1329f41aa04b397505ffJustin Klaassen public static void applyDaltonizerSetting(Context context, int userId) { 60f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette final ContentResolver cr = context.getContentResolver(); 6122eb19939d815856887f1329f41aa04b397505ffJustin Klaassen final DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class); 62f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette 6322eb19939d815856887f1329f41aa04b397505ffJustin Klaassen int daltonizerMode = AccessibilityManager.DALTONIZER_DISABLED; 64af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaver long identity = Binder.clearCallingIdentity(); 65af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaver try { 66af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaver if (Secure.getIntForUser(cr, 67af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaver Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, userId) != 0) { 68af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaver daltonizerMode = Secure.getIntForUser(cr, 69af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaver Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, DEFAULT_DISPLAY_DALTONIZER, userId); 70af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaver } 71af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaver } finally { 72af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaver Binder.restoreCallingIdentity(identity); 738864415e2a29daf504b52afe911eb5c5a8b03fc0Jeff Brown } 74f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette 7522eb19939d815856887f1329f41aa04b397505ffJustin Klaassen float[] grayscaleMatrix = null; 7622eb19939d815856887f1329f41aa04b397505ffJustin Klaassen if (daltonizerMode == AccessibilityManager.DALTONIZER_SIMULATE_MONOCHROMACY) { 7722eb19939d815856887f1329f41aa04b397505ffJustin Klaassen // Monochromacy isn't supported by the native Daltonizer. 7822eb19939d815856887f1329f41aa04b397505ffJustin Klaassen grayscaleMatrix = MATRIX_GRAYSCALE; 7922eb19939d815856887f1329f41aa04b397505ffJustin Klaassen daltonizerMode = AccessibilityManager.DALTONIZER_DISABLED; 80f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette } 8122eb19939d815856887f1329f41aa04b397505ffJustin Klaassen dtm.setColorMatrix(DisplayTransformManager.LEVEL_COLOR_MATRIX_GRAYSCALE, grayscaleMatrix); 8222eb19939d815856887f1329f41aa04b397505ffJustin Klaassen dtm.setDaltonizerMode(daltonizerMode); 83f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette } 84f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette 85f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette /** 86f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette * Applies the specified user's display color adjustments. 87f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette */ 8822eb19939d815856887f1329f41aa04b397505ffJustin Klaassen public static void applyInversionSetting(Context context, int userId) { 89f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette final ContentResolver cr = context.getContentResolver(); 9022eb19939d815856887f1329f41aa04b397505ffJustin Klaassen final DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class); 9108e7fa9b6918f442669970aa0dc048625424c07bJason Monk 92af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaver long identity = Binder.clearCallingIdentity(); 93af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaver try { 94af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaver final boolean invertColors = Secure.getIntForUser(cr, 95af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaver Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, userId) != 0; 96af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaver dtm.setColorMatrix(DisplayTransformManager.LEVEL_COLOR_MATRIX_INVERT_COLOR, 97af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaver invertColors ? MATRIX_INVERT_COLOR : null); 98af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaver } finally { 99af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaver Binder.restoreCallingIdentity(identity); 100af5d0765dbcda5c9694d1c34ab38236a8160a2f4Phil Weaver } 101f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette } 102f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette} 103