Add accessibility display adjustments to Settings

This will be redesigned soon, but for now it allows access to quick
setting tiles for testing display adjustments.

BUG: 9057596
Change-Id: I4b760487b2fe0a336b188930306000e5dfc01951
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index ab31b8c..023c102 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1004,6 +1004,51 @@
                 android:resource="@id/accessibility_settings" />
         </activity>
 
+        <activity android:name="Settings$AccessibilityInversionSettingsActivity"
+                android:label="@string/accessibility_display_inversion_preference_title"
+                android:taskAffinity="com.android.settings"
+                android:parentActivityName="Settings$AccessibilitySettingsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <action android:name="com.android.settings.ACCESSIBILITY_INVERSION_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                android:value="com.android.settings.accessibility.ToggleInversionPreferenceFragment" />
+            <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
+                android:resource="@id/accessibility_settings" />
+        </activity>
+
+        <activity android:name="Settings$AccessibilityContrastSettingsActivity"
+                android:label="@string/accessibility_display_contrast_preference_title"
+                android:taskAffinity="com.android.settings"
+                android:parentActivityName="Settings$AccessibilitySettingsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <action android:name="com.android.settings.ACCESSIBILITY_CONTRAST_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                android:value="com.android.settings.accessibility.ToggleContrastPreferenceFragment" />
+            <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
+                android:resource="@id/accessibility_settings" />
+        </activity>
+
+        <activity android:name="Settings$AccessibilityDaltonizerSettingsActivity"
+                android:label="@string/accessibility_display_daltonizer_preference_title"
+                android:taskAffinity="com.android.settings"
+                android:parentActivityName="Settings$AccessibilitySettingsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <action android:name="com.android.settings.ACCESSIBILITY_COLOR_SPACE_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                android:value="com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment" />
+            <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
+                android:resource="@id/accessibility_settings" />
+        </activity>
+
         <activity android:name="Settings$CaptioningSettingsActivity"
                 android:label="@string/accessibility_captioning_title"
                 android:taskAffinity="com.android.settings"
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index a4de070..c5c4437 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1163,4 +1163,62 @@
         <item>critical</item>
     </string-array>
 
+    <!-- Display color inversion modes for accessibility -->
+    <string-array name="inversion_type_entries">
+        <item>Standard</item>
+        <item>Hue only</item>
+        <item>Value only</item>
+    </string-array>
+
+    <!-- Values for display color inversion modes -->
+    <string-array name="inversion_type_values" translatable="false">
+        <item>0</item>
+        <item>1</item>
+        <item>2</item>
+    </string-array>
+
+    <!-- Display color space adjustment modes for accessibility -->
+    <string-array name="daltonizer_type_entries" translatable="false">
+        <item>@string/daltonizer_mode_deuteranomaly</item>
+        <item>@string/daltonizer_mode_protanomaly</item>
+        <item>@string/daltonizer_mode_tritanomaly</item>
+        <item>@string/daltonizer_mode_deuteranopia</item>
+        <item>@string/daltonizer_mode_protanopia</item>
+        <item>@string/daltonizer_mode_tritanopia</item>
+    </string-array>
+
+    <!-- Values for display color space adjustment modes for accessibility -->
+    <string-array name="daltonizer_type_values" translatable="false">
+        <item>12</item>
+        <item>11</item>
+        <item>13</item>
+        <item>15</item>
+        <item>14</item>
+        <item>16</item>
+    </string-array>
+
+    <!-- Display color space adjustment modes for developers -->
+    <string-array name="simulate_color_space_entries" translatable="false">
+        <item>@string/daltonizer_mode_disabled</item>
+        <item>@string/daltonizer_mode_monochromacy</item>
+        <item>@string/daltonizer_mode_deuteranomaly</item>
+        <item>@string/daltonizer_mode_protanomaly</item>
+        <item>@string/daltonizer_mode_tritanomaly</item>
+        <item>@string/daltonizer_mode_deuteranopia</item>
+        <item>@string/daltonizer_mode_protanopia</item>
+        <item>@string/daltonizer_mode_tritanopia</item>
+    </string-array>
+
+    <!-- Values for display color space adjustment modes for developers -->
+    <string-array name="simulate_color_space_values" translatable="false">
+        <item>-1</item>
+        <item>0</item>
+        <item>2</item>
+        <item>1</item>
+        <item>3</item>
+        <item>5</item>
+        <item>4</item>
+        <item>6</item>
+    </string-array>
+
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9c5d039..c70405e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3278,6 +3278,8 @@
     <string name="accessibility_services_title">Services</string>
     <!-- Title for the accessibility preference category of system related preferences. [CHAR LIMIT=25] -->
     <string name="accessibility_system_title">System</string>
+    <!-- Title for the accessibility preference category of display related preferences. [CHAR LIMIT=25] -->
+    <string name="accessibility_display_title">Display</string>
     <!-- Title for the accessibility preference screen to enable video captioning. [CHAR LIMIT=35] -->
     <string name="accessibility_captioning_title">Captions</string>
     <!-- Title for the accessibility preference screen to enable screen magnification. [CHAR LIMIT=35] -->
@@ -3308,6 +3310,42 @@
     <string name="accessibility_toggle_speak_password_preference_title">Speak passwords</string>
     <!-- Title for accessibility preference to choose long-press delay i.e. timeout before it is detected. [CHAR LIMIT=35] -->
     <string name="accessibility_long_press_timeout_preference_title">Touch &amp; hold delay</string>
+    <!-- Title for the accessibility preference to configure display contrast enhancement. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_display_contrast_preference_title">Contrast enhancement</string>
+    <!-- Title for the accessibility preference to configure display color inversion. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_display_inversion_preference_title">Color inversion</string>
+    <!-- Title for the accessibility preference to configure display color space correction. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_display_daltonizer_preference_title">Color space correction</string>
+
+    <!-- Title for the preference to show a tile for a particular feature in the Quick Settings pane. [CHAR LIMIT=NONE] -->
+    <string name="enable_quick_setting">Show in Quick Settings</string>
+    <!-- Title for the preference to configure contrast enhancement's brightness level. [CHAR LIMIT=NONE] -->
+    <string name="contrast_brightness">Brightness</string>
+    <!-- Title for the preference to configure contrast enhancement's contrast level. [CHAR LIMIT=NONE] -->
+    <string name="contrast_contrast">Contrast</string>
+    <!-- Title for the preference to configure the type of color inversion to apply. [CHAR LIMIT=NONE] -->
+    <string name="inversion_type">Inversion mode</string>
+    <!-- Title for the preference to configure the type of color space correction to apply. [CHAR LIMIT=NONE] -->
+    <string name="daltonizer_type">Correction mode</string>
+    <!-- Summary shown for color space correction preference when its value is overridden by another preference [CHAR LIMIT=35] -->
+    <string name="daltonizer_type_overridden">Overridden by <xliff:g id="title" example="Simulate color space">%1$s</xliff:g></string>
+
+    <!-- Label for disabling color space adjustment [CHAR LIMIT=35] -->
+    <string name="daltonizer_mode_disabled">Disabled</string>
+    <!-- Label for converting display colors to grayscale [CHAR LIMIT=35] -->
+    <string name="daltonizer_mode_monochromacy">Monochromacy</string>
+    <!-- Label for deuteranomaly (red-green color blindness) [CHAR LIMIT=35] -->
+    <string name="daltonizer_mode_deuteranomaly">Deuteranomaly (red-green)</string>
+    <!-- Label for protanomaly (red-green color blindness) [CHAR LIMIT=35] -->
+    <string name="daltonizer_mode_protanomaly">Protanomaly (red-green)</string>
+    <!-- Label for tritanomaly (blue-yellow color blindness) [CHAR LIMIT=35] -->
+    <string name="daltonizer_mode_tritanomaly">Tritanomaly (blue-yellow)</string>
+    <!-- Label for deuteranopia (green color blindness) [CHAR LIMIT=35] -->
+    <string name="daltonizer_mode_deuteranopia">Deuteranopia (green)</string>
+    <!-- Label for protanopia (red color blindness) [CHAR LIMIT=35] -->
+    <string name="daltonizer_mode_protanopia">Protanopia (red)</string>
+    <!-- Label for tritanopia (blue color blindness) [CHAR LIMIT=35] -->
+    <string name="daltonizer_mode_tritanopia">Tritanopia (blue)</string>
 
     <!-- Title for accessibility menu item to lauch a settings activity. [CHAR LIMIT=15] -->
     <string name="accessibility_menu_item_settings">Settings</string>
@@ -4310,6 +4348,9 @@
     <!-- UI debug setting: disable use of overlays summary [CHAR LIMIT=50] -->
     <string name="disable_overlays_summary">Always use GPU for screen compositing</string>
 
+    <!-- UI debug setting: simulate color space anomalies. [CHAR LIMIT=25] -->
+    <string name="simulate_color_space">Simulate color space</string>
+
     <!-- UI debug setting: enable various types of OpenGL traces [CHAR LIMIT=25] -->
     <string name="enable_opengl_traces_title">Enable OpenGL traces</string>
 
diff --git a/res/xml/accessibility_contrast_settings.xml b/res/xml/accessibility_contrast_settings.xml
new file mode 100644
index 0000000..6d08932
--- /dev/null
+++ b/res/xml/accessibility_contrast_settings.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+    android:title="@string/accessibility_display_contrast_preference_title" >
+
+    <CheckBoxPreference
+        android:key="enable_quick_setting"
+        android:persistent="false"
+        android:title="@string/enable_quick_setting" />
+
+    <SeekBarPreference
+        android:key="contrast"
+        android:persistent="false"
+        android:title="@string/contrast_contrast" />
+    <SeekBarPreference
+        android:key="brightness"
+        android:persistent="false"
+        android:title="@string/contrast_brightness" />
+
+</PreferenceScreen>
diff --git a/res/xml/accessibility_daltonizer_settings.xml b/res/xml/accessibility_daltonizer_settings.xml
new file mode 100644
index 0000000..2e8ad34
--- /dev/null
+++ b/res/xml/accessibility_daltonizer_settings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+    android:title="@string/accessibility_display_daltonizer_preference_title" >
+
+    <CheckBoxPreference
+        android:key="enable_quick_setting"
+        android:persistent="false"
+        android:title="@string/enable_quick_setting" />
+
+    <ListPreference
+        android:entries="@array/daltonizer_type_entries"
+        android:entryValues="@array/daltonizer_type_values"
+        android:key="type"
+        android:persistent="false"
+        android:summary="%s"
+        android:title="@string/daltonizer_type" />
+
+</PreferenceScreen>
diff --git a/res/xml/accessibility_inversion_settings.xml b/res/xml/accessibility_inversion_settings.xml
new file mode 100644
index 0000000..a20c4db
--- /dev/null
+++ b/res/xml/accessibility_inversion_settings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+    android:title="@string/accessibility_display_inversion_preference_title" >
+
+    <CheckBoxPreference
+        android:key="enable_quick_setting"
+        android:persistent="false"
+        android:title="@string/enable_quick_setting" />
+
+    <ListPreference
+        android:entries="@array/inversion_type_entries"
+        android:entryValues="@array/inversion_type_values"
+        android:key="type"
+        android:persistent="false"
+        android:summary="%s"
+        android:title="@string/inversion_type" />
+
+</PreferenceScreen>
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index 7b599b8..49f2e56 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -74,4 +74,21 @@
 
     </PreferenceCategory>
 
+    <PreferenceCategory
+        android:key="display_category"
+        android:title="@string/accessibility_display_title" >
+        <PreferenceScreen
+            android:fragment="com.android.settings.accessibility.ToggleContrastPreferenceFragment"
+            android:key="contrast_preference_screen"
+            android:title="@string/accessibility_display_contrast_preference_title" />
+        <PreferenceScreen
+            android:fragment="com.android.settings.accessibility.ToggleInversionPreferenceFragment"
+            android:key="inversion_preference_screen"
+            android:title="@string/accessibility_display_inversion_preference_title" />
+        <PreferenceScreen
+            android:fragment="com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment"
+            android:key="daltonizer_preference_screen"
+            android:title="@string/accessibility_display_daltonizer_preference_title" />
+    </PreferenceCategory>
+
 </PreferenceScreen>
diff --git a/res/xml/development_prefs.xml b/res/xml/development_prefs.xml
index e8dbc03..f15cd14 100644
--- a/res/xml/development_prefs.xml
+++ b/res/xml/development_prefs.xml
@@ -212,6 +212,14 @@
                 android:title="@string/disable_overlays"
                 android:summary="@string/disable_overlays_summary"/>
 
+        <ListPreference
+                android:entries="@array/simulate_color_space_entries"
+                android:entryValues="@array/simulate_color_space_values"
+                android:key="simulate_color_space"
+                android:persistent="false"
+                android:summary="%s"
+                android:title="@string/simulate_color_space" />
+
     </PreferenceCategory>
 
     <PreferenceCategory android:key="debug_monitoring_category"
diff --git a/src/com/android/settings/DevelopmentSettings.java b/src/com/android/settings/DevelopmentSettings.java
index 52706a1..ed9a50b 100644
--- a/src/com/android/settings/DevelopmentSettings.java
+++ b/src/com/android/settings/DevelopmentSettings.java
@@ -59,6 +59,7 @@
 import android.view.HardwareRenderer;
 import android.view.IWindowManager;
 import android.view.View;
+import android.view.accessibility.AccessibilityManager;
 import android.webkit.WebViewFactory;
 import android.widget.CompoundButton;
 import android.widget.Switch;
@@ -114,6 +115,7 @@
     private static final String SHOW_TOUCHES_KEY = "show_touches";
     private static final String SHOW_SCREEN_UPDATES_KEY = "show_screen_updates";
     private static final String DISABLE_OVERLAYS_KEY = "disable_overlays";
+    private static final String SIMULATE_COLOR_SPACE = "simulate_color_space";
     private static final String SHOW_CPU_USAGE_KEY = "show_cpu_usage";
     private static final String FORCE_HARDWARE_UI_KEY = "force_hw_ui";
     private static final String FORCE_MSAA_KEY = "force_msaa";
@@ -195,6 +197,7 @@
     private ListPreference mAnimatorDurationScale;
     private ListPreference mOverlayDisplayDevices;
     private ListPreference mOpenGLTraces;
+    private ListPreference mSimulateColorSpace;
 
     private CheckBoxPreference mImmediatelyDestroyActivities;
     private ListPreference mAppProcessLimit;
@@ -300,6 +303,7 @@
         mAnimatorDurationScale = addListPreference(ANIMATOR_DURATION_SCALE_KEY);
         mOverlayDisplayDevices = addListPreference(OVERLAY_DISPLAY_DEVICES_KEY);
         mOpenGLTraces = addListPreference(OPENGL_TRACES_KEY);
+        mSimulateColorSpace = addListPreference(SIMULATE_COLOR_SPACE);
 
         mImmediatelyDestroyActivities = (CheckBoxPreference) findPreference(
                 IMMEDIATELY_DESTROY_ACTIVITIES_KEY);
@@ -513,6 +517,7 @@
         updateBugreportOptions();
         updateForceRtlOptions();
         updateWifiDisplayCertificationOptions();
+        updateSimulateColorSpace();
     }
 
     private void resetDangerousOptions() {
@@ -949,6 +954,40 @@
         pokeSystemProperties();
     }
 
+    private void updateSimulateColorSpace() {
+        final ContentResolver cr = getContentResolver();
+        final boolean enabled = Settings.Secure.getInt(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0) != 0;
+        if (enabled) {
+            final String mode = Integer.toString(Settings.Secure.getInt(
+                    cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
+                    AccessibilityManager.DALTONIZER_DISABLED));
+            mSimulateColorSpace.setValue(mode);
+            final int index = mSimulateColorSpace.findIndexOfValue(mode);
+            if (index < 0) {
+                // We're using a mode controlled by accessibility preferences.
+                mSimulateColorSpace.setSummary(getString(R.string.daltonizer_type_overridden,
+                        getString(R.string.accessibility_display_daltonizer_preference_title)));
+            } else {
+                mSimulateColorSpace.setSummary("%s");
+            }
+        } else {
+            mSimulateColorSpace.setValue(
+                    Integer.toString(AccessibilityManager.DALTONIZER_DISABLED));
+        }
+    }
+
+    private void writeSimulateColorSpace(Object value) {
+        final ContentResolver cr = getContentResolver();
+        final int newMode = Integer.parseInt(value.toString());
+        if (newMode < 0) {
+            Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0);
+        } else {
+            Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 1);
+            Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, newMode);
+        }
+    }
+
     private void updateForceRtlOptions() {
         updateCheckBox(mForceRtlLayout, Settings.Global.getInt(getActivity().getContentResolver(),
                 Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0);
@@ -1350,6 +1389,9 @@
         } else if (preference == mAppProcessLimit) {
             writeAppProcessLimitOptions(newValue);
             return true;
+        } else if (preference == mSimulateColorSpace) {
+            writeSimulateColorSpace(newValue);
+            return true;
         }
         return false;
     }
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 87d34c6..8de80ca 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -325,6 +325,9 @@
         DeviceAdminSettings.class.getName(),
         AccessibilitySettings.class.getName(),
         ToggleCaptioningPreferenceFragment.class.getName(),
+        com.android.settings.accessibility.ToggleInversionPreferenceFragment.class.getName(),
+        com.android.settings.accessibility.ToggleContrastPreferenceFragment.class.getName(),
+        com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment.class.getName(),
         TextToSpeechSettings.class.getName(),
         Memory.class.getName(),
         DevelopmentSettings.class.getName(),
@@ -1039,6 +1042,9 @@
     public static class DevelopmentSettingsActivity extends Settings { /* empty */ }
     public static class AccessibilitySettingsActivity extends Settings { /* empty */ }
     public static class CaptioningSettingsActivity extends Settings { /* empty */ }
+    public static class AccessibilityInversionSettingsActivity extends Settings { /* empty */ }
+    public static class AccessibilityContrastSettingsActivity extends Settings { /* empty */ }
+    public static class AccessibilityDaltonizerSettingsActivity extends Settings { /* empty */ }
     public static class SecuritySettingsActivity extends Settings { /* empty */ }
     public static class LocationSettingsActivity extends Settings { /* empty */ }
     public static class PrivacySettingsActivity extends Settings { /* empty */ }
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index 4d24d09..8f46574 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -103,6 +103,12 @@
             "captioning_preference_screen";
     private static final String DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN =
             "screen_magnification_preference_screen";
+    private static final String DISPLAY_CONTRAST_PREFERENCE_SCREEN =
+            "contrast_preference_screen";
+    private static final String DISPLAY_INVERSION_PREFERENCE_SCREEN =
+            "inversion_preference_screen";
+    private static final String DISPLAY_DALTONIZER_PREFERENCE_SCREEN =
+            "daltonizer_preference_screen";
 
     // Extras passed to sub-fragments.
     static final String EXTRA_PREFERENCE_KEY = "preference_key";
@@ -198,6 +204,9 @@
     private PreferenceScreen mCaptioningPreferenceScreen;
     private PreferenceScreen mDisplayMagnificationPreferenceScreen;
     private PreferenceScreen mGlobalGesturePreferenceScreen;
+    private PreferenceScreen mDisplayInversionPreferenceScreen;
+    private PreferenceScreen mDisplayContrastPreferenceScreen;
+    private PreferenceScreen mDisplayDaltonizerPreferenceScreen;
 
     private int mLongPressTimeoutDefault;
 
@@ -375,6 +384,14 @@
         mDisplayMagnificationPreferenceScreen = (PreferenceScreen) findPreference(
                 DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN);
 
+        // Display color adjustments.
+        mDisplayContrastPreferenceScreen = (PreferenceScreen) findPreference(
+                DISPLAY_CONTRAST_PREFERENCE_SCREEN);
+        mDisplayInversionPreferenceScreen = (PreferenceScreen) findPreference(
+                DISPLAY_INVERSION_PREFERENCE_SCREEN);
+        mDisplayDaltonizerPreferenceScreen = (PreferenceScreen) findPreference(
+                DISPLAY_DALTONIZER_PREFERENCE_SCREEN);
+
         // Global gesture.
         mGlobalGesturePreferenceScreen =
                 (PreferenceScreen) findPreference(ENABLE_ACCESSIBILITY_GESTURE_PREFERENCE_SCREEN);
@@ -518,25 +535,16 @@
         mSelectLongPressTimeoutPreference.setValue(value);
         mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValuetoTitleMap.get(value));
 
-        // Captioning.
-        final boolean captioningEnabled = Settings.Secure.getInt(getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, 0) == 1;
-        if (captioningEnabled) {
-            mCaptioningPreferenceScreen.setSummary(R.string.accessibility_feature_state_on);
-        } else {
-            mCaptioningPreferenceScreen.setSummary(R.string.accessibility_feature_state_off);
-        }
-
-        // Screen magnification.
-        final boolean magnificationEnabled = Settings.Secure.getInt(getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 1;
-        if (magnificationEnabled) {
-            mDisplayMagnificationPreferenceScreen.setSummary(
-                    R.string.accessibility_feature_state_on);
-        } else {
-            mDisplayMagnificationPreferenceScreen.setSummary(
-                    R.string.accessibility_feature_state_off);
-        }
+        updateFeatureSummary(Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED,
+                mCaptioningPreferenceScreen);
+        updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
+                mDisplayMagnificationPreferenceScreen);
+        updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED,
+                mDisplayInversionPreferenceScreen);
+        updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED,
+                mDisplayContrastPreferenceScreen);
+        updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
+                mDisplayDaltonizerPreferenceScreen);
 
         // Global gesture
         final boolean globalGestureEnabled = Settings.Global.getInt(getContentResolver(),
@@ -550,6 +558,12 @@
         }
     }
 
+    private void updateFeatureSummary(String prefKey, Preference pref) {
+        final boolean enabled = Settings.Secure.getInt(getContentResolver(), prefKey, 0) == 1;
+        pref.setSummary(enabled ? R.string.accessibility_feature_state_on
+                : R.string.accessibility_feature_state_off);
+    }
+
     private void updateLockScreenRotationCheckbox() {
         Context context = getActivity();
         if (context != null) {
diff --git a/src/com/android/settings/accessibility/ToggleContrastPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleContrastPreferenceFragment.java
new file mode 100644
index 0000000..d1e30f8
--- /dev/null
+++ b/src/com/android/settings/accessibility/ToggleContrastPreferenceFragment.java
@@ -0,0 +1,121 @@
+/*
+ * 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.settings.accessibility;
+
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.PreferenceScreen;
+import android.preference.SeekBarPreference;
+import android.provider.Settings;
+import android.view.View;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+
+import com.android.settings.R;
+import com.android.settings.accessibility.ToggleSwitch.OnBeforeCheckedChangeListener;
+
+public class ToggleContrastPreferenceFragment extends ToggleFeaturePreferenceFragment
+        implements Preference.OnPreferenceChangeListener {
+    private static final String ENABLED = Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED;
+    private static final String QUICK_SETTING_ENABLED =
+            Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_QUICK_SETTING_ENABLED;
+
+    private CheckBoxPreference mEnableQuickSetting;
+    private SeekBarPreference mBrightness;
+    private SeekBarPreference mContrast;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        addPreferencesFromResource(R.xml.accessibility_contrast_settings);
+
+        mEnableQuickSetting = (CheckBoxPreference) findPreference("enable_quick_setting");
+        mBrightness = (SeekBarPreference) findPreference("brightness");
+        mBrightness.setMax(1000);
+        mContrast = (SeekBarPreference) findPreference("contrast");
+        mContrast.setMax(1000);
+
+        initPreferences();
+    }
+
+    @Override
+    protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
+        Settings.Secure.putInt(getContentResolver(), ENABLED, enabled ? 1 : 0);
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if (preference == mEnableQuickSetting) {
+            Settings.Secure.putInt(
+                    getContentResolver(), QUICK_SETTING_ENABLED, ((Boolean) newValue) ? 1 : 0);
+        } else if (preference == mBrightness) {
+            final int progress = (Integer) newValue;
+            final float value = progress / 1000f - 0.5f;
+            Settings.Secure.putFloat(
+                    getContentResolver(), Settings.Secure.ACCESSIBILITY_DISPLAY_BRIGHTNESS, value);
+        } else if (preference == mContrast) {
+            final int progress = (Integer) newValue;
+            final float value = progress / 1000f * 10f + 1f;
+            Settings.Secure.putFloat(
+                    getContentResolver(), Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST, value);
+        }
+
+        return true;
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+
+        setTitle(getString(R.string.accessibility_display_contrast_preference_title));
+    }
+
+    @Override
+    protected void onInstallActionBarToggleSwitch() {
+        super.onInstallActionBarToggleSwitch();
+
+        mToggleSwitch.setCheckedInternal(
+                Settings.Secure.getInt(getContentResolver(), ENABLED, 0) == 1);
+        mToggleSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(CompoundButton button, boolean checked) {
+                onPreferenceToggled(mPreferenceKey, checked);
+            }
+        });
+    }
+
+    private void initPreferences() {
+        mEnableQuickSetting.setChecked(
+                Settings.Secure.getInt(getContentResolver(), QUICK_SETTING_ENABLED, 0) == 1);
+        mEnableQuickSetting.setOnPreferenceChangeListener(this);
+
+        final float brightness = Settings.Secure.getFloat(
+                getContentResolver(), Settings.Secure.ACCESSIBILITY_DISPLAY_BRIGHTNESS, 0);
+        final float contrast = Settings.Secure.getFloat(
+                getContentResolver(), Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST, 2);
+
+        // Available brightness range is -0.5 to 0.5.
+        mBrightness.setProgress((int) (1000 * (brightness + 0.5f)));
+        mBrightness.setOnPreferenceChangeListener(this);
+
+        // Available contrast range is 1 to 10.
+        mContrast.setProgress((int) (1000 * (contrast - 1f) / 10f));
+        mContrast.setOnPreferenceChangeListener(this);
+    }
+}
diff --git a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
new file mode 100644
index 0000000..384aafc
--- /dev/null
+++ b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
@@ -0,0 +1,114 @@
+/*
+ * 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.settings.accessibility;
+
+import android.accessibilityservice.AccessibilityService;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.PreferenceScreen;
+import android.preference.SeekBarPreference;
+import android.provider.Settings;
+import android.view.View;
+import android.view.accessibility.AccessibilityManager;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+
+import com.android.settings.R;
+import com.android.settings.accessibility.ToggleSwitch.OnBeforeCheckedChangeListener;
+
+public class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePreferenceFragment
+        implements Preference.OnPreferenceChangeListener {
+    private static final String ENABLED = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED;
+    private static final String TYPE = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER;
+    private static final String QUICK_SETTING_ENABLED =
+            Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_QUICK_SETTING_ENABLED;
+    private static final int DEFAULT_TYPE = AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY;
+
+    private CheckBoxPreference mEnableQuickSetting;
+    private ListPreference mType;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        addPreferencesFromResource(R.xml.accessibility_daltonizer_settings);
+
+        mEnableQuickSetting = (CheckBoxPreference) findPreference("enable_quick_setting");
+        mType = (ListPreference) findPreference("type");
+
+        initPreferences();
+    }
+
+    @Override
+    protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
+        Settings.Secure.putInt(getContentResolver(), ENABLED, enabled ? 1 : 0);
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if (preference == mEnableQuickSetting) {
+            Settings.Secure.putInt(
+                    getContentResolver(), QUICK_SETTING_ENABLED, ((Boolean) newValue) ? 1 : 0);
+        } else if (preference == mType) {
+            Settings.Secure.putInt(getContentResolver(), TYPE, Integer.parseInt((String) newValue));
+            preference.setSummary("%s");
+        }
+
+        return true;
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+
+        setTitle(getString(R.string.accessibility_display_daltonizer_preference_title));
+    }
+
+    @Override
+    protected void onInstallActionBarToggleSwitch() {
+        super.onInstallActionBarToggleSwitch();
+
+        mToggleSwitch.setCheckedInternal(
+                Settings.Secure.getInt(getContentResolver(), ENABLED, 0) == 1);
+        mToggleSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(CompoundButton button, boolean checked) {
+                onPreferenceToggled(mPreferenceKey, checked);
+            }
+        });
+    }
+
+    private void initPreferences() {
+        mEnableQuickSetting.setChecked(
+                Settings.Secure.getInt(getContentResolver(), QUICK_SETTING_ENABLED, 0) == 1);
+        mEnableQuickSetting.setOnPreferenceChangeListener(this);
+
+        final String value = Integer.toString(
+                Settings.Secure.getInt(getContentResolver(), TYPE, DEFAULT_TYPE));
+        mType.setValue(value);
+        mType.setOnPreferenceChangeListener(this);
+        final int index = mType.findIndexOfValue(value);
+        if (index < 0) {
+            // We're using a mode controlled by developer preferences.
+            mType.setSummary(getString(R.string.daltonizer_type_overridden,
+                    getString(R.string.simulate_color_space)));
+        }
+    }
+}
diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
index 171b1ac..6024327 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -92,9 +92,6 @@
         super.onViewCreated(view, savedInstanceState);
         onInstallActionBarToggleSwitch();
         onProcessArguments(getArguments());
-        // Set a transparent drawable to prevent use of the default one.
-        getListView().setSelector(new ColorDrawable(Color.TRANSPARENT));
-        getListView().setDivider(null);
     }
 
     @Override
@@ -135,21 +132,45 @@
         return toggleSwitch;
     }
 
-    protected void onProcessArguments(Bundle arguments) {
-        // Key.
-        mPreferenceKey = arguments.getString(AccessibilitySettings.EXTRA_PREFERENCE_KEY);
-        // Enabled.
-        final boolean enabled = arguments.getBoolean(AccessibilitySettings.EXTRA_CHECKED);
-        mToggleSwitch.setCheckedInternal(enabled);
-        // Title.
-        PreferenceActivity activity = (PreferenceActivity) getActivity();
+    public void setTitle(String title) {
+        final PreferenceActivity activity = (PreferenceActivity) getActivity();
         if (!activity.onIsMultiPane() || activity.onIsHidingHeaders()) {
             mOldActivityTitle = getActivity().getTitle();
-            String title = arguments.getString(AccessibilitySettings.EXTRA_TITLE);
             getActivity().getActionBar().setTitle(title);
         }
+    }
+
+    protected void onProcessArguments(Bundle arguments) {
+        if (arguments == null) {
+            getPreferenceScreen().removePreference(mSummaryPreference);
+            return;
+        }
+
+        // Key.
+        mPreferenceKey = arguments.getString(AccessibilitySettings.EXTRA_PREFERENCE_KEY);
+
+        // Enabled.
+        if (arguments.containsKey(AccessibilitySettings.EXTRA_CHECKED)) {
+            final boolean enabled = arguments.getBoolean(AccessibilitySettings.EXTRA_CHECKED);
+            mToggleSwitch.setCheckedInternal(enabled);
+        }
+
+        // Title.
+        if (arguments.containsKey(AccessibilitySettings.EXTRA_TITLE)) {
+            setTitle(arguments.getString(AccessibilitySettings.EXTRA_TITLE));
+        }
+
         // Summary.
-        CharSequence summary = arguments.getCharSequence(AccessibilitySettings.EXTRA_SUMMARY);
-        mSummaryPreference.setSummary(summary);
+        if (arguments.containsKey(AccessibilitySettings.EXTRA_SUMMARY)) {
+            final CharSequence summary = arguments.getCharSequence(
+                    AccessibilitySettings.EXTRA_SUMMARY);
+            mSummaryPreference.setSummary(summary);
+
+            // Set a transparent drawable to prevent use of the default one.
+            getListView().setSelector(new ColorDrawable(Color.TRANSPARENT));
+            getListView().setDivider(null);
+        } else {
+            getPreferenceScreen().removePreference(mSummaryPreference);
+        }
     }
 }
diff --git a/src/com/android/settings/accessibility/ToggleInversionPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleInversionPreferenceFragment.java
new file mode 100644
index 0000000..bfb2500
--- /dev/null
+++ b/src/com/android/settings/accessibility/ToggleInversionPreferenceFragment.java
@@ -0,0 +1,105 @@
+/*
+ * 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.settings.accessibility;
+
+import android.accessibilityservice.AccessibilityService;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceScreen;
+import android.preference.SeekBarPreference;
+import android.provider.Settings;
+import android.view.View;
+import android.view.accessibility.AccessibilityManager;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+
+import com.android.settings.R;
+import com.android.settings.accessibility.ToggleSwitch.OnBeforeCheckedChangeListener;
+
+public class ToggleInversionPreferenceFragment extends ToggleFeaturePreferenceFragment
+        implements Preference.OnPreferenceChangeListener {
+    private static final String ENABLED = Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED;
+    private static final String TYPE = Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION;
+    private static final String QUICK_SETTING_ENABLED =
+            Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_QUICK_SETTING_ENABLED;
+    private static final int DEFAULT_TYPE = AccessibilityManager.INVERSION_STANDARD;
+
+    private CheckBoxPreference mEnableQuickSetting;
+    private ListPreference mType;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        addPreferencesFromResource(R.xml.accessibility_inversion_settings);
+
+        mEnableQuickSetting = (CheckBoxPreference) findPreference("enable_quick_setting");
+        mType = (ListPreference) findPreference("type");
+
+        initPreferences();
+    }
+
+    @Override
+    protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
+        Settings.Secure.putInt(getContentResolver(), ENABLED, enabled ? 1 : 0);
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if (preference == mEnableQuickSetting) {
+            Settings.Secure.putInt(
+                    getContentResolver(), QUICK_SETTING_ENABLED, ((Boolean) newValue) ? 1 : 0);
+        } else if (preference == mType) {
+            Settings.Secure.putInt(getContentResolver(), TYPE, Integer.parseInt((String) newValue));
+        }
+
+        return true;
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+
+        setTitle(getString(R.string.accessibility_display_inversion_preference_title));
+    }
+
+    @Override
+    protected void onInstallActionBarToggleSwitch() {
+        super.onInstallActionBarToggleSwitch();
+
+        mToggleSwitch.setCheckedInternal(
+                Settings.Secure.getInt(getContentResolver(), ENABLED, 0) == 1);
+        mToggleSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(CompoundButton button, boolean checked) {
+                onPreferenceToggled(mPreferenceKey, checked);
+            }
+        });
+    }
+
+    private void initPreferences() {
+        mEnableQuickSetting.setChecked(
+                Settings.Secure.getInt(getContentResolver(), QUICK_SETTING_ENABLED, 0) == 1);
+        mEnableQuickSetting.setOnPreferenceChangeListener(this);
+
+        mType.setValue(
+                Integer.toString(Settings.Secure.getInt(getContentResolver(), TYPE, DEFAULT_TYPE)));
+        mType.setOnPreferenceChangeListener(this);
+    }
+}