Merge "Settings for the screen magnification feature." into jb-mr1-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3805932..fd00184 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2976,30 +2976,52 @@
     <string name="accessibility_settings">Accessibility</string>
     <!-- Settings title for accessibility settings screen -->
     <string name="accessibility_settings_title">Accessibility settings</string>
-
     <!--  Title for the accessibility preference category of accessibility services. [CHAR LIMIT=25] -->
     <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 screen to enable screen magnification. [CHAR LIMIT=35] -->
+    <string name="accessibility_screen_magnification_title">Screen magnification</string>
+    <!-- Summary for the accessibility preference screen to enable screen magnification. [CHAR LIMIT=35] -->
+    <string name="accessibility_screen_magnification_summary">
+        When screen magnification is on, you can:\n
+        \n
+        Temporary zoom-in: Triple-tap &amp; hold.\n
+        Toggle permanent zoom state: Triple-tap &amp; release.\n
+        \n
+        Adjust zoomed area: Triple-tap &amp; hold to zoom, then drag your finger across the screen.\n
+        Pan when zoomed-in: Drag two or more fingers across the screen.\n
+        \n
+        Adjust zoom level when zoomed-out: Triple-tap &amp; hold to zoom, then drag one or more fingers.\n
+        Adjust zoom level when zoomed-in: Pinch with two or more fingers.\n
+    </string>
+
     <!-- Title for the accessibility preference to enable large text. [CHAR LIMIT=35] -->
-    <string name="accessibility_toggle_large_text_title">Large text</string>
+    <string name="accessibility_toggle_large_text_preference_title">Large text</string>
+    <!-- Title for the accessibility preference to enable screen magnification. [CHAR LIMIT=35] -->
+    <string name="accessibility_toggle_screen_magnification_preference_title">Screen magnification</string>
+    <!-- Title for the accessibility preference to auto update screen magnification. [CHAR LIMIT=35] -->
+    <string name="accessibility_toggle_screen_magnification_auto_update_preference_title">Auto
+        update screen magnification</string>
+    <!-- Summary for the accessibility preference to auto update screen magnification. [CHAR LIMIT=50] -->
+    <string name="accessibility_toggle_screen_magnification_auto_update_preference_summary">Update
+        screen magnification on app transitions</string>
     <!-- Title for the accessibility preference to power button to end a call. [CHAR LIMIT=35] -->
-    <string name="accessibility_power_button_ends_call_title">Power button ends call</string>
+    <string name="accessibility_power_button_ends_call_prerefence_title">Power button ends call</string>
     <!-- Title for the accessibility preference to speak passwords. [CHAR LIMIT=35] -->
-    <string name="accessibility_speak_password_title">Speak passwords</string>
+    <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_title">Touch &amp; hold delay</string>
+    <string name="accessibility_long_press_timeout_preference_title">Touch &amp; hold delay</string>
     <!-- Title for accessibility preference to install accessibility scripts from Google. [CHAR LIMIT=35] -->
-    <string name="accessibility_script_injection_title">Enhance web accessibility</string>
+    <string name="accessibility_toggle_script_injection_preference_title">Enhance web accessibility</string>
 
     <!-- Title for accessibility menu item to lauch a settings activity. [CHAR LIMIT=15] -->
     <string name="accessibility_menu_item_settings">Settings</string>
 
-    <!-- Summary for the enabled state of an accessiblity serivce. [CHAR LIMIT=10] -->
-    <string name="accessibility_service_state_on">On</string>
-    <!-- Summary for the disabled state of an accessiblity serivce. [CHAR LIMIT=10] -->
-    <string name="accessibility_service_state_off">Off</string>
+    <!-- Summary for the enabled state of an accessiblity feature. [CHAR LIMIT=10] -->
+    <string name="accessibility_feature_state_on">On</string>
+    <!-- Summary for the disabled state of an accessiblity feature. [CHAR LIMIT=10] -->
+    <string name="accessibility_feature_state_off">Off</string>
 
     <!-- Summary for the allowed state of script injection. [CHAR LIMIT=15] -->
     <string name="accessibility_script_injection_allowed">Allowed</string>
@@ -3855,6 +3877,15 @@
     <string name="show_all_anrs_summary">Show App Not Responding dialog
         for background apps</string>
 
+    <!-- Preference category for accessibility debugging development settings. [CHAR LIMIT=25] -->
+    <string name="debug_accessibility_category">Accessibility</string>
+
+    <!-- Accessibility debug setting: automatically update magnification state [CHAR LIMIT=50] -->
+    <string name="display_magnification_auto_update">Auto update magnification</string>
+    <!-- Accessibility debug setting: automatically update magnification state summary [CHAR LIMIT=100] -->
+    <string name="display_magnification_auto_update_summary">Zoom out on rotation or activity
+        start and pan to popped up windows.</string>
+
     <!-- Activity title for network data usage summary. [CHAR LIMIT=25] -->
     <string name="data_usage_summary_title">Data usage</string>
     <!-- Title for option to pick visible time range from a list available usage periods. [CHAR LIMIT=25] -->
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index bf93eb5..e86dff6 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -27,14 +27,19 @@
             android:key="system_category"
             android:title="@string/accessibility_system_title">
 
+        <PreferenceScreen
+            android:fragment="com.android.settings.AccessibilitySettings$ToggleScreenMagnificationPreferenceFragment"
+            android:key="screen_magnification_preference_screen"
+            android:title="@string/accessibility_screen_magnification_title"/>
+
         <CheckBoxPreference
                 android:key="toggle_large_text_preference"
-                android:title="@string/accessibility_toggle_large_text_title"
+                android:title="@string/accessibility_toggle_large_text_preference_title"
                 android:persistent="false"/>
 
         <CheckBoxPreference
                 android:key="toggle_power_button_ends_call_preference"
-                android:title="@string/accessibility_power_button_ends_call_title"
+                android:title="@string/accessibility_power_button_ends_call_prerefence_title"
                 android:persistent="false"/>
 
         <CheckBoxPreference
@@ -44,15 +49,15 @@
 
         <CheckBoxPreference
                 android:key="toggle_speak_password_preference"
-                android:title="@string/accessibility_speak_password_title"
+                android:title="@string/accessibility_toggle_speak_password_preference_title"
                 android:persistent="false"/>
 
-        <PreferenceScreen android:key="tts_settings"
+        <PreferenceScreen android:key="tts_settings_preference"
                 android:fragment="com.android.settings.tts.TextToSpeechSettings"
-                android:title="@string/tts_settings_title" />
+                android:title="@string/tts_settings_title"/>
 
         <ListPreference android:key="select_long_press_timeout_preference"
-                android:title="@string/accessibility_long_press_timeout_title"
+                android:title="@string/accessibility_long_press_timeout_preference_title"
                 android:entries="@array/long_press_timeout_selector_titles"
                 android:entryValues="@array/long_press_timeout_selector_values"
                 android:persistent="false"/>
@@ -60,7 +65,7 @@
         <!-- We want a dialog with no title, so use an empty string to avoid a fall back to the preference title. -->
         <com.android.settings.AccessibilityEnableScriptInjectionPreference
                 android:key="toggle_script_injection_preference"
-                android:title="@string/accessibility_script_injection_title"
+                android:title="@string/accessibility_toggle_script_injection_preference_title"
                 android:dialogTitle=""
                 android:dialogIcon="@android:drawable/ic_dialog_alert"
                 android:dialogMessage="@string/accessibility_script_injection_security_warning_summary"
diff --git a/res/xml/development_prefs.xml b/res/xml/development_prefs.xml
index 34c0ae3..575f802 100644
--- a/res/xml/development_prefs.xml
+++ b/res/xml/development_prefs.xml
@@ -202,4 +202,14 @@
 
     </PreferenceCategory>
 
+        <PreferenceCategory android:key="debug_accessibility_category"
+            android:title="@string/debug_accessibility_category">
+
+        <CheckBoxPreference
+            android:key="accessibility_display_magnification_auto_update"
+            android:title="@string/display_magnification_auto_update"
+            android:summary="@string/display_magnification_auto_update_summary"/>
+
+    </PreferenceCategory>
+
 </PreferenceScreen>
diff --git a/src/com/android/settings/AccessibilitySettings.java b/src/com/android/settings/AccessibilitySettings.java
index 4047555..592706c 100644
--- a/src/com/android/settings/AccessibilitySettings.java
+++ b/src/com/android/settings/AccessibilitySettings.java
@@ -30,7 +30,6 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.res.Configuration;
-import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
@@ -75,38 +74,42 @@
 public class AccessibilitySettings extends SettingsPreferenceFragment implements DialogCreatable,
         Preference.OnPreferenceChangeListener {
     private static final String DEFAULT_SCREENREADER_MARKET_LINK =
-        "market://search?q=pname:com.google.android.marvin.talkback";
+            "market://search?q=pname:com.google.android.marvin.talkback";
 
     private static final float LARGE_FONT_SCALE = 1.3f;
 
     private static final String SYSTEM_PROPERTY_MARKET_URL = "ro.screenreader.market";
 
     // Timeout before we update the services if packages are added/removed since
-    // the AccessibilityManagerService has to do that processing first to generate
+    // the AccessibilityManagerService has to do that processing first to
+    // generate
     // the AccessibilityServiceInfo we need for proper presentation.
     private static final long DELAY_UPDATE_SERVICES_MILLIS = 1000;
 
     private static final char ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR = ':';
 
     private static final String KEY_INSTALL_ACCESSIBILITY_SERVICE_OFFERED_ONCE =
-        "key_install_accessibility_service_offered_once";
+            "key_install_accessibility_service_offered_once";
 
     // Preference categories
     private static final String SERVICES_CATEGORY = "services_category";
     private static final String SYSTEM_CATEGORY = "system_category";
 
     // Preferences
-    private static final String TOGGLE_LARGE_TEXT_PREFERENCE = "toggle_large_text_preference";
+    private static final String TOGGLE_LARGE_TEXT_PREFERENCE =
+            "toggle_large_text_preference";
     private static final String TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE =
-        "toggle_power_button_ends_call_preference";
+            "toggle_power_button_ends_call_preference";
     private static final String TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE =
-        "toggle_lock_screen_rotation_preference";
+            "toggle_lock_screen_rotation_preference";
     private static final String TOGGLE_SPEAK_PASSWORD_PREFERENCE =
-        "toggle_speak_password_preference";
+            "toggle_speak_password_preference";
     private static final String SELECT_LONG_PRESS_TIMEOUT_PREFERENCE =
-        "select_long_press_timeout_preference";
+            "select_long_press_timeout_preference";
     private static final String TOGGLE_SCRIPT_INJECTION_PREFERENCE =
-        "toggle_script_injection_preference";
+            "toggle_script_injection_preference";
+    private static final String DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN =
+            "screen_magnification_preference_screen";
 
     // Extras passed to sub-fragments.
     private static final String EXTRA_PREFERENCE_KEY = "preference_key";
@@ -125,12 +128,12 @@
 
     // Auxiliary members.
     private final static SimpleStringSplitter sStringColonSplitter =
-        new SimpleStringSplitter(ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR);
+            new SimpleStringSplitter(ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR);
 
     private static final Set<ComponentName> sInstalledServices = new HashSet<ComponentName>();
 
     private final Map<String, String> mLongPressTimeoutValuetoTitleMap =
-        new HashMap<String, String>();
+            new HashMap<String, String>();
 
     private final Configuration mCurConfig = new Configuration();
 
@@ -147,11 +150,11 @@
 
     private final RotationPolicy.RotationPolicyListener mRotationPolicyListener =
             new RotationPolicy.RotationPolicyListener() {
-        @Override
-        public void onChange() {
-            updateLockScreenRotationCheckbox();
-        }
-    };
+                @Override
+                public void onChange() {
+                    updateLockScreenRotationCheckbox();
+                }
+            };
 
     // Preference controls.
     private PreferenceCategory mServicesCategory;
@@ -164,6 +167,7 @@
     private ListPreference mSelectLongPressTimeoutPreference;
     private AccessibilityEnableScriptInjectionPreference mToggleScriptInjectionPreference;
     private Preference mNoServicesMessagePreference;
+    private PreferenceScreen mDisplayMagnificationPreferenceScreen;
 
     private int mLongPressTimeoutDefault;
 
@@ -207,6 +211,12 @@
         return false;
     }
 
+
+    
+    
+    
+    
+    
     @Override
     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
         if (mToggleLargeTextPreference == preference) {
@@ -220,6 +230,10 @@
             return true;
         } else if (mToggleSpeakPasswordPreference == preference) {
             handleToggleSpeakPasswordPreferenceClick();
+            return true;
+        } else if (mDisplayMagnificationPreferenceScreen == preference) {
+            handleDisplayMagnificationPreferenceScreenClick();
+            return true;
         }
         return super.onPreferenceTreeClick(preferenceScreen, preference);
     }
@@ -252,17 +266,29 @@
                 mToggleSpeakPasswordPreference.isChecked() ? 1 : 0);
     }
 
+    private void handleDisplayMagnificationPreferenceScreenClick() {
+        Bundle extras = mDisplayMagnificationPreferenceScreen.getExtras();
+        extras.putString(EXTRA_TITLE, getString(
+                R.string.accessibility_screen_magnification_title));
+        extras.putString(EXTRA_SUMMARY, getString(
+                R.string.accessibility_screen_magnification_summary));
+        extras.putBoolean(EXTRA_CHECKED, Settings.Secure.getInt(getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 1);
+        super.onPreferenceTreeClick(mDisplayMagnificationPreferenceScreen,
+                mDisplayMagnificationPreferenceScreen);
+    }
+
     private void initializeAllPreferences() {
         mServicesCategory = (PreferenceCategory) findPreference(SERVICES_CATEGORY);
         mSystemsCategory = (PreferenceCategory) findPreference(SYSTEM_CATEGORY);
 
         // Large text.
         mToggleLargeTextPreference =
-            (CheckBoxPreference) findPreference(TOGGLE_LARGE_TEXT_PREFERENCE);
+                (CheckBoxPreference) findPreference(TOGGLE_LARGE_TEXT_PREFERENCE);
 
         // Power button ends calls.
         mTogglePowerButtonEndsCallPreference =
-            (CheckBoxPreference) findPreference(TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE);
+                (CheckBoxPreference) findPreference(TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE);
         if (!KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
                 || !Utils.isVoiceCapable(getActivity())) {
             mSystemsCategory.removePreference(mTogglePowerButtonEndsCallPreference);
@@ -270,15 +296,15 @@
 
         // Lock screen rotation.
         mToggleLockScreenRotationPreference =
-            (CheckBoxPreference) findPreference(TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE);
+                (CheckBoxPreference) findPreference(TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE);
 
         // Speak passwords.
         mToggleSpeakPasswordPreference =
-            (CheckBoxPreference) findPreference(TOGGLE_SPEAK_PASSWORD_PREFERENCE);
+                (CheckBoxPreference) findPreference(TOGGLE_SPEAK_PASSWORD_PREFERENCE);
 
         // Long press timeout.
         mSelectLongPressTimeoutPreference =
-            (ListPreference) findPreference(SELECT_LONG_PRESS_TIMEOUT_PREFERENCE);
+                (ListPreference) findPreference(SELECT_LONG_PRESS_TIMEOUT_PREFERENCE);
         mSelectLongPressTimeoutPreference.setOnPreferenceChangeListener(this);
         if (mLongPressTimeoutValuetoTitleMap.size() == 0) {
             String[] timeoutValues = getResources().getStringArray(
@@ -288,13 +314,17 @@
                     R.array.long_press_timeout_selector_titles);
             final int timeoutValueCount = timeoutValues.length;
             for (int i = 0; i < timeoutValueCount; i++) {
-               mLongPressTimeoutValuetoTitleMap.put(timeoutValues[i], timeoutTitles[i]);
+                mLongPressTimeoutValuetoTitleMap.put(timeoutValues[i], timeoutTitles[i]);
             }
         }
 
         // Script injection.
         mToggleScriptInjectionPreference = (AccessibilityEnableScriptInjectionPreference)
-            findPreference(TOGGLE_SCRIPT_INJECTION_PREFERENCE);
+                findPreference(TOGGLE_SCRIPT_INJECTION_PREFERENCE);
+
+        // Display magnification.
+        mDisplayMagnificationPreferenceScreen = (PreferenceScreen) findPreference(
+                DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN);
     }
 
     private void updateAllPreferences() {
@@ -313,7 +343,7 @@
         AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(getActivity());
 
         List<AccessibilityServiceInfo> installedServices =
-            accessibilityManager.getInstalledAccessibilityServiceList();
+                accessibilityManager.getInstalledAccessibilityServiceList();
         Set<ComponentName> enabledServices = getEnabledServicesFromSettings(getActivity());
 
         final boolean accessibilityEnabled = Settings.Secure.getInt(getContentResolver(),
@@ -334,11 +364,11 @@
 
             preference.setTitle(title);
             final boolean serviceEnabled = accessibilityEnabled
-                && enabledServices.contains(componentName);
+                    && enabledServices.contains(componentName);
             if (serviceEnabled) {
-                preference.setSummary(getString(R.string.accessibility_service_state_on));
+                preference.setSummary(getString(R.string.accessibility_feature_state_on));
             } else {
-                preference.setSummary(getString(R.string.accessibility_service_state_off));
+                preference.setSummary(getString(R.string.accessibility_feature_state_off));
             }
 
             preference.setOrder(i);
@@ -390,7 +420,7 @@
                         super.onBindView(view);
 
                         LinearLayout containerView =
-                            (LinearLayout) view.findViewById(R.id.message_container);
+                                (LinearLayout) view.findViewById(R.id.message_container);
                         containerView.setGravity(Gravity.CENTER);
 
                         TextView summaryView = (TextView) view.findViewById(R.id.summary);
@@ -423,7 +453,7 @@
                     Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
                     Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT);
             final boolean powerButtonEndsCall =
-                (incallPowerBehavior == Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP);
+                    (incallPowerBehavior == Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP);
             mTogglePowerButtonEndsCallPreference.setChecked(powerButtonEndsCall);
         }
 
@@ -443,9 +473,20 @@
         mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValuetoTitleMap.get(value));
 
         // Script injection.
-        final boolean  scriptInjectionAllowed = (Settings.Secure.getInt(getContentResolver(),
+        final boolean scriptInjectionAllowed = (Settings.Secure.getInt(getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0) == 1);
         mToggleScriptInjectionPreference.setInjectionAllowed(scriptInjectionAllowed);
+
+        // 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);
+        }
     }
 
     private void updateLockScreenRotationCheckbox() {
@@ -489,25 +530,28 @@
         switch (dialogId) {
             case DIALOG_ID_NO_ACCESSIBILITY_SERVICES:
                 return new AlertDialog.Builder(getActivity())
-                    .setTitle(R.string.accessibility_service_no_apps_title)
-                    .setMessage(R.string.accessibility_service_no_apps_message)
-                    .setPositiveButton(android.R.string.ok,
-                        new DialogInterface.OnClickListener() {
-                            public void onClick(DialogInterface dialog, int which) {
-                                // dismiss the dialog before launching the activity otherwise
-                                // the dialog removal occurs after onSaveInstanceState which
-                                // triggers an exception
-                                removeDialog(DIALOG_ID_NO_ACCESSIBILITY_SERVICES);
-                                String screenreaderMarketLink = SystemProperties.get(
-                                        SYSTEM_PROPERTY_MARKET_URL,
-                                        DEFAULT_SCREENREADER_MARKET_LINK);
-                                Uri marketUri = Uri.parse(screenreaderMarketLink);
-                                Intent marketIntent = new Intent(Intent.ACTION_VIEW, marketUri);
-                                startActivity(marketIntent);
-                            }
-                    })
-                    .setNegativeButton(android.R.string.cancel, null)
-                    .create();
+                        .setTitle(R.string.accessibility_service_no_apps_title)
+                        .setMessage(R.string.accessibility_service_no_apps_message)
+                        .setPositiveButton(android.R.string.ok,
+                                new DialogInterface.OnClickListener() {
+                                    public void onClick(DialogInterface dialog, int which) {
+                                        // dismiss the dialog before launching
+                                        // the activity otherwise
+                                        // the dialog removal occurs after
+                                        // onSaveInstanceState which
+                                        // triggers an exception
+                                        removeDialog(DIALOG_ID_NO_ACCESSIBILITY_SERVICES);
+                                        String screenreaderMarketLink = SystemProperties.get(
+                                                SYSTEM_PROPERTY_MARKET_URL,
+                                                DEFAULT_SCREENREADER_MARKET_LINK);
+                                        Uri marketUri = Uri.parse(screenreaderMarketLink);
+                                        Intent marketIntent = new Intent(Intent.ACTION_VIEW,
+                                                marketUri);
+                                        startActivity(marketIntent);
+                                    }
+                                })
+                        .setNegativeButton(android.R.string.cancel, null)
+                        .create();
             default:
                 return null;
         }
@@ -515,8 +559,8 @@
 
     private void loadInstalledServices() {
         List<AccessibilityServiceInfo> installedServiceInfos =
-            AccessibilityManager.getInstance(getActivity())
-                .getInstalledAccessibilityServiceList();
+                AccessibilityManager.getInstance(getActivity())
+                        .getInstalledAccessibilityServiceList();
         Set<ComponentName> installedServices = sInstalledServices;
         installedServices.clear();
         final int installedServiceInfoCount = installedServiceInfos.size();
@@ -576,20 +620,6 @@
         }
     }
 
-    private static ToggleSwitch createAndAddActionBarToggleSwitch(Activity activity) {
-        ToggleSwitch toggleSwitch = new ToggleSwitch(activity);
-        final int padding = activity.getResources().getDimensionPixelSize(
-                R.dimen.action_bar_switch_padding);
-        toggleSwitch.setPadding(0, 0, padding, 0);
-        activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
-                ActionBar.DISPLAY_SHOW_CUSTOM);
-        activity.getActionBar().setCustomView(toggleSwitch,
-                new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT,
-                        ActionBar.LayoutParams.WRAP_CONTENT,
-                        Gravity.CENTER_VERTICAL | Gravity.END));
-        return toggleSwitch;
-    }
-
     public static class ToggleSwitch extends Switch {
 
         private OnBeforeCheckedChangeListener mOnBeforeListener;
@@ -621,87 +651,21 @@
     }
 
     public static class ToggleAccessibilityServicePreferenceFragment
-            extends SettingsPreferenceFragment implements DialogInterface.OnClickListener {
+            extends ToggleFeaturePreferenceFragment implements DialogInterface.OnClickListener {
 
         private static final int DIALOG_ID_ENABLE_WARNING = 1;
         private static final int DIALOG_ID_DISABLE_WARNING = 2;
 
-        private String mPreferenceKey;
-
-        private ToggleSwitch mToggleSwitch;
-
         private CharSequence mEnableWarningTitle;
         private CharSequence mEnableWarningMessage;
         private CharSequence mDisableWarningTitle;
         private CharSequence mDisableWarningMessage;
 
-        private Preference mSummaryPreference;
-
-        private CharSequence mSettingsTitle;
-        private Intent mSettingsIntent;
-
         private int mShownDialogId;
 
-        // TODO: Showing sub-sub fragment does not handle the activity title
-        //       so we do it but this is wrong. Do a real fix when there is time.
-        private CharSequence mOldActivityTitle;
-
         @Override
-        public void onCreate(Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(
-                    getActivity());
-            setPreferenceScreen(preferenceScreen);
-            mSummaryPreference = new Preference(getActivity()) {
-                @Override
-                protected void onBindView(View view) {
-                    super.onBindView(view);
-                    TextView summaryView = (TextView) view.findViewById(R.id.summary);
-                    summaryView.setText(getSummary());
-                    sendAccessibilityEvent(summaryView);
-                }
-
-                private void sendAccessibilityEvent(View view) {
-                    // Since the view is still not attached we create, populate,
-                    // and send the event directly since we do not know when it
-                    // will be attached and posting commands is not as clean.
-                    AccessibilityManager accessibilityManager =
-                        AccessibilityManager.getInstance(getActivity());
-                    if (accessibilityManager.isEnabled()) {
-                        AccessibilityEvent event = AccessibilityEvent.obtain();
-                        event.setEventType(AccessibilityEvent.TYPE_VIEW_FOCUSED);
-                        view.onInitializeAccessibilityEvent(event);
-                        view.dispatchPopulateAccessibilityEvent(event);
-                        accessibilityManager.sendAccessibilityEvent(event);
-                    }
-                }
-            };
-            mSummaryPreference.setPersistent(false);
-            mSummaryPreference.setLayoutResource(R.layout.text_description_preference);
-            preferenceScreen.addPreference(mSummaryPreference);
-        }
-
-        @Override
-        public void onViewCreated(View view, Bundle savedInstanceState) {
-            super.onViewCreated(view, savedInstanceState);
-            installActionBarToggleSwitch();
-            processArguments();
-            getListView().setDivider(null);
-            getListView().setEnabled(false);
-        }
-
-        @Override
-        public void onDestroyView() {
-            getActivity().getActionBar().setCustomView(null);
-            if (mOldActivityTitle != null) {
-                getActivity().getActionBar().setTitle(mOldActivityTitle);
-            }
-            mToggleSwitch.setOnBeforeCheckedChangeListener(null);
-            super.onDestroyView();
-        }
-
         public void onPreferenceToggled(String preferenceKey, boolean enabled) {
-             // Parse the enabled services.
+            // Parse the enabled services.
             Set<ComponentName> enabledServices = getEnabledServicesFromSettings(getActivity());
 
             // Determine enabled services and accessibility state.
@@ -722,16 +686,17 @@
                 }
                 // Disabling the last service disables accessibility.
                 accessibilityEnabled = enabledAndInstalledServiceCount > 1
-                    || (enabledAndInstalledServiceCount == 1
-                            && !installedServices.contains(toggledService));
+                        || (enabledAndInstalledServiceCount == 1
+                        && !installedServices.contains(toggledService));
                 enabledServices.remove(toggledService);
             }
 
             // Update the enabled services setting.
             StringBuilder enabledServicesBuilder = new StringBuilder();
-            // Keep the enabled services even if they are not installed since we have
-            // no way to know whether the application restore process has completed.
-            // In general the system should be responsible for the clean up not settings.
+            // Keep the enabled services even if they are not installed since we
+            // have no way to know whether the application restore process has
+            // completed. In general the system should be responsible for the
+            // clean up not settings.
             for (ComponentName enabledService : enabledServices) {
                 enabledServicesBuilder.append(enabledService.flattenToString());
                 enabledServicesBuilder.append(ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR);
@@ -750,14 +715,6 @@
         }
 
         @Override
-        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-            super.onCreateOptionsMenu(menu, inflater);
-            MenuItem menuItem = menu.add(mSettingsTitle);
-            menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
-            menuItem.setIntent(mSettingsIntent);
-        }
-
-        @Override
         public Dialog onCreateDialog(int dialogId) {
             CharSequence title = null;
             CharSequence message = null;
@@ -776,13 +733,13 @@
                     throw new IllegalArgumentException();
             }
             return new AlertDialog.Builder(getActivity())
-                .setTitle(title)
-                .setIconAttribute(android.R.attr.alertDialogIcon)
-                .setMessage(message)
-                .setCancelable(true)
-                .setPositiveButton(android.R.string.ok, this)
-                .setNegativeButton(android.R.string.cancel, this)
-                .create();
+                    .setTitle(title)
+                    .setIconAttribute(android.R.attr.alertDialogIcon)
+                    .setMessage(message)
+                    .setCancelable(true)
+                    .setPositiveButton(android.R.string.ok, this)
+                    .setNegativeButton(android.R.string.cancel, this)
+                    .create();
         }
 
         @Override
@@ -806,8 +763,9 @@
             }
         }
 
-        private void installActionBarToggleSwitch() {
-            mToggleSwitch = createAndAddActionBarToggleSwitch(getActivity());
+        @Override
+        protected void onInstallActionBarToggleSwitch() {
+            super.onInstallActionBarToggleSwitch();
             mToggleSwitch.setOnBeforeCheckedChangeListener(new OnBeforeCheckedChangeListener() {
                 @Override
                 public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked) {
@@ -833,28 +791,9 @@
             });
         }
 
-        private void processArguments() {
-            Bundle arguments = getArguments();
-
-            // Key.
-            mPreferenceKey = arguments.getString(EXTRA_PREFERENCE_KEY);
-
-            // Enabled.
-            final boolean enabled = arguments.getBoolean(EXTRA_CHECKED);
-            mToggleSwitch.setCheckedInternal(enabled);
-
-            // Title.
-            PreferenceActivity activity = (PreferenceActivity) getActivity();
-            if (!activity.onIsMultiPane() || activity.onIsHidingHeaders()) {
-                mOldActivityTitle = getActivity().getTitle();
-                String title = arguments.getString(EXTRA_TITLE);
-                getActivity().getActionBar().setTitle(title);
-            }
-
-            // Summary.
-            String summary = arguments.getString(EXTRA_SUMMARY);
-            mSummaryPreference.setSummary(summary);
-
+        @Override
+        protected void onProcessArguments(Bundle arguments) {
+            super.onProcessArguments(arguments);
             // Settings title and intent.
             String settingsTitle = arguments.getString(EXTRA_SETTINGS_TITLE);
             String settingsComponentName = arguments.getString(EXTRA_SETTINGS_COMPONENT_NAME);
@@ -867,22 +806,157 @@
                     setHasOptionsMenu(true);
                 }
             }
-
             // Enable warning title.
             mEnableWarningTitle = arguments.getCharSequence(
                     AccessibilitySettings.EXTRA_ENABLE_WARNING_TITLE);
-
             // Enable warning message.
             mEnableWarningMessage = arguments.getCharSequence(
                     AccessibilitySettings.EXTRA_ENABLE_WARNING_MESSAGE);
-
             // Disable warning title.
             mDisableWarningTitle = arguments.getString(
                     AccessibilitySettings.EXTRA_DISABLE_WARNING_TITLE);
-
             // Disable warning message.
             mDisableWarningMessage = arguments.getString(
                     AccessibilitySettings.EXTRA_DISABLE_WARNING_MESSAGE);
         }
     }
+
+    public static class ToggleScreenMagnificationPreferenceFragment
+            extends ToggleFeaturePreferenceFragment {
+        @Override
+        protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
+            Settings.Secure.putInt(getContentResolver(),
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, enabled? 1 : 0);
+        }
+
+        @Override
+        protected void onInstallActionBarToggleSwitch() {
+            super.onInstallActionBarToggleSwitch();
+            mToggleSwitch.setOnBeforeCheckedChangeListener(new OnBeforeCheckedChangeListener() {
+                @Override
+                public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked) {
+                    toggleSwitch.setCheckedInternal(checked);
+                    getArguments().putBoolean(EXTRA_CHECKED, checked);
+                    onPreferenceToggled(mPreferenceKey, checked);
+                    return false;
+                }
+            });
+        }
+    }
+
+    public static abstract class ToggleFeaturePreferenceFragment
+            extends SettingsPreferenceFragment {
+
+        protected ToggleSwitch mToggleSwitch;
+
+        protected String mPreferenceKey;
+        protected Preference mSummaryPreference;
+
+        protected CharSequence mSettingsTitle;
+        protected Intent mSettingsIntent;
+
+        // TODO: Showing sub-sub fragment does not handle the activity title
+        // so we do it but this is wrong. Do a real fix when there is time.
+        private CharSequence mOldActivityTitle;
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(
+                    getActivity());
+            setPreferenceScreen(preferenceScreen);
+            mSummaryPreference = new Preference(getActivity()) {
+                @Override
+                protected void onBindView(View view) {
+                    super.onBindView(view);
+                    TextView summaryView = (TextView) view.findViewById(R.id.summary);
+                    summaryView.setText(getSummary());
+                    sendAccessibilityEvent(summaryView);
+                }
+
+                private void sendAccessibilityEvent(View view) {
+                    // Since the view is still not attached we create, populate,
+                    // and send the event directly since we do not know when it
+                    // will be attached and posting commands is not as clean.
+                    AccessibilityManager accessibilityManager =
+                            AccessibilityManager.getInstance(getActivity());
+                    if (accessibilityManager.isEnabled()) {
+                        AccessibilityEvent event = AccessibilityEvent.obtain();
+                        event.setEventType(AccessibilityEvent.TYPE_VIEW_FOCUSED);
+                        view.onInitializeAccessibilityEvent(event);
+                        view.dispatchPopulateAccessibilityEvent(event);
+                        accessibilityManager.sendAccessibilityEvent(event);
+                    }
+                }
+            };
+            mSummaryPreference.setPersistent(false);
+            mSummaryPreference.setLayoutResource(R.layout.text_description_preference);
+            preferenceScreen.addPreference(mSummaryPreference);
+        }
+
+        @Override
+        public void onViewCreated(View view, Bundle savedInstanceState) {
+            super.onViewCreated(view, savedInstanceState);
+            onInstallActionBarToggleSwitch();
+            onProcessArguments(getArguments());
+            getListView().setDivider(null);
+            getListView().setEnabled(false);
+        }
+
+        @Override
+        public void onDestroyView() {
+            getActivity().getActionBar().setCustomView(null);
+            if (mOldActivityTitle != null) {
+                getActivity().getActionBar().setTitle(mOldActivityTitle);
+            }
+            mToggleSwitch.setOnBeforeCheckedChangeListener(null);
+            super.onDestroyView();
+        }
+
+        protected abstract void onPreferenceToggled(String preferenceKey, boolean enabled);
+
+        @Override
+        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+            super.onCreateOptionsMenu(menu, inflater);
+            MenuItem menuItem = menu.add(mSettingsTitle);
+            menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+            menuItem.setIntent(mSettingsIntent);
+        }
+
+        protected void onInstallActionBarToggleSwitch() {
+            mToggleSwitch = createAndAddActionBarToggleSwitch(getActivity());
+        }
+
+        private ToggleSwitch createAndAddActionBarToggleSwitch(Activity activity) {
+            ToggleSwitch toggleSwitch = new ToggleSwitch(activity);
+            final int padding = activity.getResources().getDimensionPixelSize(
+                    R.dimen.action_bar_switch_padding);
+            toggleSwitch.setPadding(0, 0, padding, 0);
+            activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
+                    ActionBar.DISPLAY_SHOW_CUSTOM);
+            activity.getActionBar().setCustomView(toggleSwitch,
+                    new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT,
+                            ActionBar.LayoutParams.WRAP_CONTENT,
+                            Gravity.CENTER_VERTICAL | Gravity.END));
+            return toggleSwitch;
+        }
+
+        protected void onProcessArguments(Bundle arguments) {
+            // Key.
+            mPreferenceKey = arguments.getString(EXTRA_PREFERENCE_KEY);
+            // Enabled.
+            final boolean enabled = arguments.getBoolean(EXTRA_CHECKED);
+            mToggleSwitch.setCheckedInternal(enabled);
+            // Title.
+            PreferenceActivity activity = (PreferenceActivity) getActivity();
+            if (!activity.onIsMultiPane() || activity.onIsHidingHeaders()) {
+                mOldActivityTitle = getActivity().getTitle();
+                String title = arguments.getString(EXTRA_TITLE);
+                getActivity().getActionBar().setTitle(title);
+            }
+            // Summary.
+            String summary = arguments.getString(EXTRA_SUMMARY);
+            mSummaryPreference.setSummary(summary);
+        }
+    }
 }
diff --git a/src/com/android/settings/DevelopmentSettings.java b/src/com/android/settings/DevelopmentSettings.java
index 09d7f9b..f590ea6 100644
--- a/src/com/android/settings/DevelopmentSettings.java
+++ b/src/com/android/settings/DevelopmentSettings.java
@@ -98,6 +98,8 @@
     private static final String TRANSITION_ANIMATION_SCALE_KEY = "transition_animation_scale";
     private static final String ANIMATOR_DURATION_SCALE_KEY = "animator_duration_scale";
     private static final String OVERLAY_DISPLAY_DEVICES_KEY = "overlay_display_devices";
+    private static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE_KEY =
+            "accessibility_display_magnification_auto_update";
 
     private static final String ENABLE_TRACES_KEY = "enable_traces";
 
@@ -142,6 +144,7 @@
     private CheckBoxPreference mShowHwScreenUpdates;
     private CheckBoxPreference mShowHwLayersUpdates;
     private CheckBoxPreference mDebugLayout;
+    private CheckBoxPreference mDisplayMangificationAutoUpdate;
     private ListPreference mWindowAnimationScale;
     private ListPreference mTransitionAnimationScale;
     private ListPreference mAnimatorDurationScale;
@@ -237,6 +240,9 @@
             mAllPrefs.add(hdcpChecking);
         }
         removeHdcpOptionsForProduction();
+
+        mDisplayMangificationAutoUpdate = findAndInitCheckboxPref(
+                ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE_KEY);
     }
 
     private CheckBoxPreference findAndInitCheckboxPref(String key) {
@@ -370,6 +376,7 @@
         updateImmediatelyDestroyActivitiesOptions();
         updateAppProcessLimitOptions();
         updateShowAllANRsOptions();
+        updateDisplayMagnificationAutoUpdate();
     }
 
     private void resetDangerousOptions() {
@@ -623,6 +630,12 @@
         pokeSystemProperties();
     }
 
+    private void writeDisplayMagnificationAutoUpdate() {
+        Settings.Secure.putInt(getActivity().getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE,
+                mDisplayMangificationAutoUpdate.isChecked() ?  1 : 0);
+    }
+
     private void updateCpuUsageOptions() {
         updateCheckBox(mShowCpuUsage, Settings.System.getInt(getActivity().getContentResolver(),
                 Settings.System.SHOW_PROCESSES, 0) != 0);
@@ -756,6 +769,12 @@
             getActivity().getContentResolver(), Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0);
     }
 
+    private void updateDisplayMagnificationAutoUpdate() {
+        updateCheckBox(mDisplayMangificationAutoUpdate,
+                Settings.Secure.getInt(getActivity().getContentResolver(),
+                        Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE, 0) != 0);
+    }
+
     private void updateEnableTracesOptions() {
         long flags = SystemProperties.getLong(Trace.PROPERTY_TRACE_TAG_ENABLEFLAGS, 0);
         String[] values = mEnableTracesPref.getEntryValues();
@@ -909,6 +928,8 @@
             writeShowHwLayersUpdatesOptions();
         } else if (preference == mDebugLayout) {
             writeDebugLayoutOptions();
+        } else if (preference == mDisplayMangificationAutoUpdate) {
+            writeDisplayMagnificationAutoUpdate();
         }
 
         return false;