diff --git a/src/com/android/settings/AccessibilitySettings.java b/src/com/android/settings/AccessibilitySettings.java
deleted file mode 100644
index f4188f1..0000000
--- a/src/com/android/settings/AccessibilitySettings.java
+++ /dev/null
@@ -1,1133 +0,0 @@
-/*
- * Copyright (C) 2009 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;
-
-import android.accessibilityservice.AccessibilityServiceInfo;
-import android.app.ActionBar;
-import android.app.Activity;
-import android.app.ActivityManagerNative;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.content.res.Configuration;
-import android.database.ContentObserver;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemProperties;
-import android.preference.CheckBoxPreference;
-import android.preference.ListPreference;
-import android.preference.Preference;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceCategory;
-import android.preference.PreferenceScreen;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.text.TextUtils.SimpleStringSplitter;
-import android.view.Gravity;
-import android.view.KeyCharacterMap;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.Switch;
-import android.widget.TextView;
-
-import com.android.internal.content.PackageMonitor;
-import com.android.internal.view.RotationPolicy;
-import com.android.settings.AccessibilitySettings.ToggleSwitch.OnBeforeCheckedChangeListener;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Activity with the accessibility settings.
- */
-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";
-
-    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 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";
-
-    // 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_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";
-    private static final String TOGGLE_SPEAK_PASSWORD_PREFERENCE =
-            "toggle_speak_password_preference";
-    private static final String SELECT_LONG_PRESS_TIMEOUT_PREFERENCE =
-            "select_long_press_timeout_preference";
-    private static final String ENABLE_ACCESSIBILITY_GESTURE_PREFERENCE_SCREEN =
-            "enable_global_gesture_preference_screen";
-    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";
-    private static final String EXTRA_CHECKED = "checked";
-    private static final String EXTRA_TITLE = "title";
-    private static final String EXTRA_SUMMARY = "summary";
-    private static final String EXTRA_SETTINGS_TITLE = "settings_title";
-    private static final String EXTRA_COMPONENT_NAME = "component_name";
-    private static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name";
-
-    // Dialog IDs.
-    private static final int DIALOG_ID_NO_ACCESSIBILITY_SERVICES = 1;
-
-    // Auxiliary members.
-    private final static SimpleStringSplitter sStringColonSplitter =
-            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>();
-
-    private final Configuration mCurConfig = new Configuration();
-
-    private final PackageMonitor mSettingsPackageMonitor = new SettingsPackageMonitor();
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void dispatchMessage(Message msg) {
-            super.dispatchMessage(msg);
-            loadInstalledServices();
-            updateServicesPreferences();
-        }
-    };
-
-    private final SettingsContentObserver mSettingsContentObserver =
-            new SettingsContentObserver(mHandler) {
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            loadInstalledServices();
-            updateServicesPreferences();
-        }
-    };
-
-    private final RotationPolicy.RotationPolicyListener mRotationPolicyListener =
-            new RotationPolicy.RotationPolicyListener() {
-                @Override
-                public void onChange() {
-                    updateLockScreenRotationCheckbox();
-                }
-            };
-
-    // Preference controls.
-    private PreferenceCategory mServicesCategory;
-    private PreferenceCategory mSystemsCategory;
-
-    private CheckBoxPreference mToggleLargeTextPreference;
-    private CheckBoxPreference mTogglePowerButtonEndsCallPreference;
-    private CheckBoxPreference mToggleLockScreenRotationPreference;
-    private CheckBoxPreference mToggleSpeakPasswordPreference;
-    private ListPreference mSelectLongPressTimeoutPreference;
-    private Preference mNoServicesMessagePreference;
-    private PreferenceScreen mDisplayMagnificationPreferenceScreen;
-    private PreferenceScreen mGlobalGesturePreferenceScreen;
-
-    private int mLongPressTimeoutDefault;
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        addPreferencesFromResource(R.xml.accessibility_settings);
-        initializeAllPreferences();
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        loadInstalledServices();
-        updateAllPreferences();
-
-        offerInstallAccessibilitySerivceOnce();
-
-        mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
-        mSettingsContentObserver.register(getContentResolver());
-        if (RotationPolicy.isRotationSupported(getActivity())) {
-            RotationPolicy.registerRotationPolicyListener(getActivity(),
-                    mRotationPolicyListener);
-        }
-    }
-
-    @Override
-    public void onPause() {
-        mSettingsPackageMonitor.unregister();
-        mSettingsContentObserver.unregister(getContentResolver());
-        if (RotationPolicy.isRotationSupported(getActivity())) {
-            RotationPolicy.unregisterRotationPolicyListener(getActivity(),
-                    mRotationPolicyListener);
-        }
-        super.onPause();
-    }
-
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        if (preference == mSelectLongPressTimeoutPreference) {
-            String stringValue = (String) newValue;
-            Settings.Secure.putInt(getContentResolver(),
-                    Settings.Secure.LONG_PRESS_TIMEOUT, Integer.parseInt(stringValue));
-            mSelectLongPressTimeoutPreference.setSummary(
-                    mLongPressTimeoutValuetoTitleMap.get(stringValue));
-            return true;
-        }
-        return false;
-    }
-    
-    @Override
-    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
-        if (mToggleLargeTextPreference == preference) {
-            handleToggleLargeTextPreferenceClick();
-            return true;
-        } else if (mTogglePowerButtonEndsCallPreference == preference) {
-            handleTogglePowerButtonEndsCallPreferenceClick();
-            return true;
-        } else if (mToggleLockScreenRotationPreference == preference) {
-            handleLockScreenRotationPreferenceClick();
-            return true;
-        } else if (mToggleSpeakPasswordPreference == preference) {
-            handleToggleSpeakPasswordPreferenceClick();
-            return true;
-        } else if (mGlobalGesturePreferenceScreen == preference) {
-            handleTogglEnableAccessibilityGesturePreferenceClick();
-            return true;
-        } else if (mDisplayMagnificationPreferenceScreen == preference) {
-            handleDisplayMagnificationPreferenceScreenClick();
-            return true;
-        }
-        return super.onPreferenceTreeClick(preferenceScreen, preference);
-    }
-
-    private void handleToggleLargeTextPreferenceClick() {
-        try {
-            mCurConfig.fontScale = mToggleLargeTextPreference.isChecked() ? LARGE_FONT_SCALE : 1;
-            ActivityManagerNative.getDefault().updatePersistentConfiguration(mCurConfig);
-        } catch (RemoteException re) {
-            /* ignore */
-        }
-    }
-
-    private void handleTogglePowerButtonEndsCallPreferenceClick() {
-        Settings.Secure.putInt(getContentResolver(),
-                Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
-                (mTogglePowerButtonEndsCallPreference.isChecked()
-                        ? Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP
-                        : Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF));
-    }
-
-    private void handleLockScreenRotationPreferenceClick() {
-        RotationPolicy.setRotationLockForAccessibility(getActivity(),
-                !mToggleLockScreenRotationPreference.isChecked());
-    }
-
-    private void handleToggleSpeakPasswordPreferenceClick() {
-        Settings.Secure.putInt(getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
-                mToggleSpeakPasswordPreference.isChecked() ? 1 : 0);
-    }
-
-    private void handleTogglEnableAccessibilityGesturePreferenceClick() {
-        Bundle extras = mGlobalGesturePreferenceScreen.getExtras();
-        extras.putString(EXTRA_TITLE, getString(
-                R.string.accessibility_global_gesture_preference_title));
-        extras.putString(EXTRA_SUMMARY, getString(
-                R.string.accessibility_global_gesture_preference_description));
-        extras.putBoolean(EXTRA_CHECKED, Settings.Global.getInt(getContentResolver(),
-                Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED, 0) == 1);
-        super.onPreferenceTreeClick(mGlobalGesturePreferenceScreen,
-                mGlobalGesturePreferenceScreen);
-    }
-
-    private void handleDisplayMagnificationPreferenceScreenClick() {
-        Bundle extras = mDisplayMagnificationPreferenceScreen.getExtras();
-        extras.putString(EXTRA_TITLE, getString(
-                R.string.accessibility_screen_magnification_title));
-        extras.putCharSequence(EXTRA_SUMMARY, getActivity().getResources().getText(
-                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);
-
-        // Power button ends calls.
-        mTogglePowerButtonEndsCallPreference =
-                (CheckBoxPreference) findPreference(TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE);
-        if (!KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
-                || !Utils.isVoiceCapable(getActivity())) {
-            mSystemsCategory.removePreference(mTogglePowerButtonEndsCallPreference);
-        }
-
-        // Lock screen rotation.
-        mToggleLockScreenRotationPreference =
-                (CheckBoxPreference) findPreference(TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE);
-        if (!RotationPolicy.isRotationSupported(getActivity())) {
-            mSystemsCategory.removePreference(mToggleLockScreenRotationPreference);
-        }
-
-        // Speak passwords.
-        mToggleSpeakPasswordPreference =
-                (CheckBoxPreference) findPreference(TOGGLE_SPEAK_PASSWORD_PREFERENCE);
-
-        // Long press timeout.
-        mSelectLongPressTimeoutPreference =
-                (ListPreference) findPreference(SELECT_LONG_PRESS_TIMEOUT_PREFERENCE);
-        mSelectLongPressTimeoutPreference.setOnPreferenceChangeListener(this);
-        if (mLongPressTimeoutValuetoTitleMap.size() == 0) {
-            String[] timeoutValues = getResources().getStringArray(
-                    R.array.long_press_timeout_selector_values);
-            mLongPressTimeoutDefault = Integer.parseInt(timeoutValues[0]);
-            String[] timeoutTitles = getResources().getStringArray(
-                    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]);
-            }
-        }
-
-        // Display magnification.
-        mDisplayMagnificationPreferenceScreen = (PreferenceScreen) findPreference(
-                DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN);
-
-        // Global gesture.
-        mGlobalGesturePreferenceScreen =
-                (PreferenceScreen) findPreference(ENABLE_ACCESSIBILITY_GESTURE_PREFERENCE_SCREEN);
-        final int longPressOnPowerBehavior = getActivity().getResources().getInteger(
-                com.android.internal.R.integer.config_longPressOnPowerBehavior);
-        final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
-        if (!KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
-                || longPressOnPowerBehavior != LONG_PRESS_POWER_GLOBAL_ACTIONS) {
-            // Remove accessibility shortcut if power key is not present
-            // nor long press power does not show global actions menu.
-            mSystemsCategory.removePreference(mGlobalGesturePreferenceScreen);
-        }
-    }
-
-    private void updateAllPreferences() {
-        updateServicesPreferences();
-        updateSystemPreferences();
-    }
-
-    private void updateServicesPreferences() {
-        // Since services category is auto generated we have to do a pass
-        // to generate it since services can come and go and then based on
-        // the global accessibility state to decided whether it is enabled.
-
-        // Generate.
-        mServicesCategory.removeAll();
-
-        AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(getActivity());
-
-        List<AccessibilityServiceInfo> installedServices =
-                accessibilityManager.getInstalledAccessibilityServiceList();
-        Set<ComponentName> enabledServices = getEnabledServicesFromSettings(getActivity());
-
-        final boolean accessibilityEnabled = Settings.Secure.getInt(getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
-
-        for (int i = 0, count = installedServices.size(); i < count; ++i) {
-            AccessibilityServiceInfo info = installedServices.get(i);
-
-            PreferenceScreen preference = getPreferenceManager().createPreferenceScreen(
-                    getActivity());
-            String title = info.getResolveInfo().loadLabel(getPackageManager()).toString();
-
-            ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo;
-            ComponentName componentName = new ComponentName(serviceInfo.packageName,
-                    serviceInfo.name);
-
-            preference.setKey(componentName.flattenToString());
-
-            preference.setTitle(title);
-            final boolean serviceEnabled = accessibilityEnabled
-                    && enabledServices.contains(componentName);
-            if (serviceEnabled) {
-                preference.setSummary(getString(R.string.accessibility_feature_state_on));
-            } else {
-                preference.setSummary(getString(R.string.accessibility_feature_state_off));
-            }
-
-            preference.setOrder(i);
-            preference.setFragment(ToggleAccessibilityServicePreferenceFragment.class.getName());
-            preference.setPersistent(true);
-
-            Bundle extras = preference.getExtras();
-            extras.putString(EXTRA_PREFERENCE_KEY, preference.getKey());
-            extras.putBoolean(EXTRA_CHECKED, serviceEnabled);
-            extras.putString(EXTRA_TITLE, title);
-
-            String description = info.loadDescription(getPackageManager());
-            if (TextUtils.isEmpty(description)) {
-                description = getString(R.string.accessibility_service_default_description);
-            }
-            extras.putString(EXTRA_SUMMARY, description);
-
-            String settingsClassName = info.getSettingsActivityName();
-            if (!TextUtils.isEmpty(settingsClassName)) {
-                extras.putString(EXTRA_SETTINGS_TITLE,
-                        getString(R.string.accessibility_menu_item_settings));
-                extras.putString(EXTRA_SETTINGS_COMPONENT_NAME,
-                        new ComponentName(info.getResolveInfo().serviceInfo.packageName,
-                                settingsClassName).flattenToString());
-            }
-
-            extras.putParcelable(EXTRA_COMPONENT_NAME, componentName);
-
-            mServicesCategory.addPreference(preference);
-        }
-
-        if (mServicesCategory.getPreferenceCount() == 0) {
-            if (mNoServicesMessagePreference == null) {
-                mNoServicesMessagePreference = new Preference(getActivity()) {
-                    @Override
-                    protected void onBindView(View view) {
-                        super.onBindView(view);
-                        TextView summaryView = (TextView) view.findViewById(R.id.summary);
-                        String title = getString(R.string.accessibility_no_services_installed);
-                        summaryView.setText(title);
-                    }
-                };
-                mNoServicesMessagePreference.setPersistent(false);
-                mNoServicesMessagePreference.setLayoutResource(
-                        R.layout.text_description_preference);
-                mNoServicesMessagePreference.setSelectable(false);
-            }
-            mServicesCategory.addPreference(mNoServicesMessagePreference);
-        }
-    }
-
-    private void updateSystemPreferences() {
-        // Large text.
-        try {
-            mCurConfig.updateFrom(ActivityManagerNative.getDefault().getConfiguration());
-        } catch (RemoteException re) {
-            /* ignore */
-        }
-        mToggleLargeTextPreference.setChecked(mCurConfig.fontScale == LARGE_FONT_SCALE);
-
-        // Power button ends calls.
-        if (KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
-                && Utils.isVoiceCapable(getActivity())) {
-            final int incallPowerBehavior = Settings.Secure.getInt(getContentResolver(),
-                    Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
-                    Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT);
-            final boolean powerButtonEndsCall =
-                    (incallPowerBehavior == Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP);
-            mTogglePowerButtonEndsCallPreference.setChecked(powerButtonEndsCall);
-        }
-
-        // Auto-rotate screen
-        updateLockScreenRotationCheckbox();
-
-        // Speak passwords.
-        final boolean speakPasswordEnabled = Settings.Secure.getInt(getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0) != 0;
-        mToggleSpeakPasswordPreference.setChecked(speakPasswordEnabled);
-
-        // Long press timeout.
-        final int longPressTimeout = Settings.Secure.getInt(getContentResolver(),
-                Settings.Secure.LONG_PRESS_TIMEOUT, mLongPressTimeoutDefault);
-        String value = String.valueOf(longPressTimeout);
-        mSelectLongPressTimeoutPreference.setValue(value);
-        mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValuetoTitleMap.get(value));
-
-        // 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);
-        }
-
-        // Global gesture
-        final boolean globalGestureEnabled = Settings.Global.getInt(getContentResolver(),
-                Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED, 0) == 1;
-        if (globalGestureEnabled) {
-            mGlobalGesturePreferenceScreen.setSummary(
-                    R.string.accessibility_global_gesture_preference_summary_on);
-        } else {
-            mGlobalGesturePreferenceScreen.setSummary(
-                    R.string.accessibility_global_gesture_preference_summary_off);
-        }
-    }
-
-    private void updateLockScreenRotationCheckbox() {
-        Context context = getActivity();
-        if (context != null) {
-            mToggleLockScreenRotationPreference.setChecked(
-                    !RotationPolicy.isRotationLocked(context));
-        }
-    }
-
-    private void offerInstallAccessibilitySerivceOnce() {
-        // There is always one preference - if no services it is just a message.
-        if (mServicesCategory.getPreference(0) != mNoServicesMessagePreference) {
-            return;
-        }
-        SharedPreferences preferences = getActivity().getPreferences(Context.MODE_PRIVATE);
-        final boolean offerInstallService = !preferences.getBoolean(
-                KEY_INSTALL_ACCESSIBILITY_SERVICE_OFFERED_ONCE, false);
-        if (offerInstallService) {
-            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);
-
-            if (getPackageManager().resolveActivity(marketIntent, 0) == null) {
-                // Don't show the dialog if no market app is found/installed.
-                return;
-            }
-
-            preferences.edit().putBoolean(KEY_INSTALL_ACCESSIBILITY_SERVICE_OFFERED_ONCE,
-                    true).commit();
-            // Notify user that they do not have any accessibility
-            // services installed and direct them to Market to get TalkBack.
-            showDialog(DIALOG_ID_NO_ACCESSIBILITY_SERVICES);
-        }
-    }
-
-    @Override
-    public Dialog onCreateDialog(int dialogId) {
-        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();
-            default:
-                return null;
-        }
-    }
-
-    private void loadInstalledServices() {
-        Set<ComponentName> installedServices = sInstalledServices;
-        installedServices.clear();
-
-        List<AccessibilityServiceInfo> installedServiceInfos =
-                AccessibilityManager.getInstance(getActivity())
-                        .getInstalledAccessibilityServiceList();
-        if (installedServiceInfos == null) {
-            return;
-        }
-
-        final int installedServiceInfoCount = installedServiceInfos.size();
-        for (int i = 0; i < installedServiceInfoCount; i++) {
-            ResolveInfo resolveInfo = installedServiceInfos.get(i).getResolveInfo();
-            ComponentName installedService = new ComponentName(
-                    resolveInfo.serviceInfo.packageName,
-                    resolveInfo.serviceInfo.name);
-            installedServices.add(installedService);
-        }
-    }
-
-    private static Set<ComponentName> getEnabledServicesFromSettings(Context context) {
-        String enabledServicesSetting = Settings.Secure.getString(context.getContentResolver(),
-                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
-        if (enabledServicesSetting == null) {
-            enabledServicesSetting = "";
-        }
-        Set<ComponentName> enabledServices = new HashSet<ComponentName>();
-        SimpleStringSplitter colonSplitter = sStringColonSplitter;
-        colonSplitter.setString(enabledServicesSetting);
-        while (colonSplitter.hasNext()) {
-            String componentNameString = colonSplitter.next();
-            ComponentName enabledService = ComponentName.unflattenFromString(
-                    componentNameString);
-            if (enabledService != null) {
-                enabledServices.add(enabledService);
-            }
-        }
-        return enabledServices;
-    }
-
-    private class SettingsPackageMonitor extends PackageMonitor {
-
-        @Override
-        public void onPackageAdded(String packageName, int uid) {
-            Message message = mHandler.obtainMessage();
-            mHandler.sendMessageDelayed(message, DELAY_UPDATE_SERVICES_MILLIS);
-        }
-
-        @Override
-        public void onPackageAppeared(String packageName, int reason) {
-            Message message = mHandler.obtainMessage();
-            mHandler.sendMessageDelayed(message, DELAY_UPDATE_SERVICES_MILLIS);
-        }
-
-        @Override
-        public void onPackageDisappeared(String packageName, int reason) {
-            Message message = mHandler.obtainMessage();
-            mHandler.sendMessageDelayed(message, DELAY_UPDATE_SERVICES_MILLIS);
-        }
-
-        @Override
-        public void onPackageRemoved(String packageName, int uid) {
-            Message message = mHandler.obtainMessage();
-            mHandler.sendMessageDelayed(message, DELAY_UPDATE_SERVICES_MILLIS);
-        }
-    }
-
-    public static class ToggleSwitch extends Switch {
-
-        private OnBeforeCheckedChangeListener mOnBeforeListener;
-
-        public static interface OnBeforeCheckedChangeListener {
-            public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked);
-        }
-
-        public ToggleSwitch(Context context) {
-            super(context);
-        }
-
-        public void setOnBeforeCheckedChangeListener(OnBeforeCheckedChangeListener listener) {
-            mOnBeforeListener = listener;
-        }
-
-        @Override
-        public void setChecked(boolean checked) {
-            if (mOnBeforeListener != null
-                    && mOnBeforeListener.onBeforeCheckedChanged(this, checked)) {
-                return;
-            }
-            super.setChecked(checked);
-        }
-
-        public void setCheckedInternal(boolean checked) {
-            super.setChecked(checked);
-        }
-    }
-
-    public static class ToggleAccessibilityServicePreferenceFragment
-            extends ToggleFeaturePreferenceFragment implements DialogInterface.OnClickListener {
-
-        private static final int DIALOG_ID_ENABLE_WARNING = 1;
-        private static final int DIALOG_ID_DISABLE_WARNING = 2;
-
-        private final SettingsContentObserver mSettingsContentObserver =
-                new SettingsContentObserver(new Handler()) {
-            @Override
-            public void onChange(boolean selfChange, Uri uri) {
-                String settingValue = Settings.Secure.getString(getContentResolver(),
-                        Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
-                final boolean enabled = settingValue.contains(mComponentName.flattenToString());
-                mToggleSwitch.setCheckedInternal(enabled);
-            }
-        };
-
-        private ComponentName mComponentName;
-
-        private int mShownDialogId;
-
-        @Override
-        public void onResume() {
-            mSettingsContentObserver.register(getContentResolver());
-            super.onResume();
-        }
-
-        @Override
-        public void onPause() {
-            mSettingsContentObserver.unregister(getContentResolver());
-            super.onPause();
-        }
-
-        @Override
-        public void onPreferenceToggled(String preferenceKey, boolean enabled) {
-            // Parse the enabled services.
-            Set<ComponentName> enabledServices = getEnabledServicesFromSettings(getActivity());
-
-            // Determine enabled services and accessibility state.
-            ComponentName toggledService = ComponentName.unflattenFromString(preferenceKey);
-            boolean accessibilityEnabled = false;
-            if (enabled) {
-                enabledServices.add(toggledService);
-                // Enabling at least one service enables accessibility.
-                accessibilityEnabled = true;
-            } else {
-                enabledServices.remove(toggledService);
-                // Check how many enabled and installed services are present.
-                Set<ComponentName> installedServices = sInstalledServices;
-                for (ComponentName enabledService : enabledServices) {
-                    if (installedServices.contains(enabledService)) {
-                        // Disabling the last service disables accessibility.
-                        accessibilityEnabled = true;
-                        break;
-                    }
-                }
-            }
-
-            // 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.
-            for (ComponentName enabledService : enabledServices) {
-                enabledServicesBuilder.append(enabledService.flattenToString());
-                enabledServicesBuilder.append(ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR);
-            }
-            final int enabledServicesBuilderLength = enabledServicesBuilder.length();
-            if (enabledServicesBuilderLength > 0) {
-                enabledServicesBuilder.deleteCharAt(enabledServicesBuilderLength - 1);
-            }
-            Settings.Secure.putString(getContentResolver(),
-                    Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
-                    enabledServicesBuilder.toString());
-
-            // Update accessibility enabled.
-            Settings.Secure.putInt(getContentResolver(),
-                    Settings.Secure.ACCESSIBILITY_ENABLED, accessibilityEnabled ? 1 : 0);
-        }
-
-        // IMPORTANT: Refresh the info since there are dynamically changing capabilities. For
-        // example, before JellyBean MR2 the user was granting the explore by touch one.
-        private AccessibilityServiceInfo getAccessibilityServiceInfo() {
-            List<AccessibilityServiceInfo> serviceInfos = AccessibilityManager.getInstance(
-                    getActivity()).getInstalledAccessibilityServiceList();
-            final int serviceInfoCount = serviceInfos.size();
-            for (int i = 0; i < serviceInfoCount; i++) {
-                AccessibilityServiceInfo serviceInfo = serviceInfos.get(i);
-                ResolveInfo resolveInfo = serviceInfo.getResolveInfo();
-                if (mComponentName.getPackageName().equals(resolveInfo.serviceInfo.packageName)
-                        && mComponentName.getClassName().equals(resolveInfo.serviceInfo.name)) {
-                    return serviceInfo;
-                }
-            }
-            return null;
-        }
-
-        @Override
-        public Dialog onCreateDialog(int dialogId) {
-            switch (dialogId) {
-                case DIALOG_ID_ENABLE_WARNING: {
-                    mShownDialogId = DIALOG_ID_ENABLE_WARNING;
-                    AccessibilityServiceInfo info = getAccessibilityServiceInfo();
-                    if (info == null) {
-                        return null;
-                    }
-                    return new AlertDialog.Builder(getActivity())
-                        .setTitle(getString(R.string.enable_service_title,
-                                info.getResolveInfo().loadLabel(getPackageManager())))
-                        .setIconAttribute(android.R.attr.alertDialogIcon)
-                        .setView(createEnableDialogContentView(info))
-                        .setCancelable(true)
-                        .setPositiveButton(android.R.string.ok, this)
-                        .setNegativeButton(android.R.string.cancel, this)
-                        .create();
-                }
-                case DIALOG_ID_DISABLE_WARNING: {
-                    mShownDialogId = DIALOG_ID_DISABLE_WARNING;
-                    AccessibilityServiceInfo info = getAccessibilityServiceInfo();
-                    if (info == null) {
-                        return null;
-                    }
-                    return new AlertDialog.Builder(getActivity())
-                        .setTitle(getString(R.string.disable_service_title,
-                                info.getResolveInfo().loadLabel(getPackageManager())))
-                        .setIconAttribute(android.R.attr.alertDialogIcon)
-                        .setMessage(getString(R.string.disable_service_message,
-                                info.getResolveInfo().loadLabel(getPackageManager())))
-                        .setCancelable(true)
-                        .setPositiveButton(android.R.string.ok, this)
-                        .setNegativeButton(android.R.string.cancel, this)
-                        .create();
-                }
-                default: {
-                    throw new IllegalArgumentException();
-                }
-            }
-        }
-
-        private View createEnableDialogContentView(AccessibilityServiceInfo info) {
-            LayoutInflater inflater = (LayoutInflater) getSystemService(
-                    Context.LAYOUT_INFLATER_SERVICE);
-
-            View content = inflater.inflate(R.layout.enable_accessibility_service_dialog_content,
-                    null);
-
-            TextView capabilitiesHeaderView = (TextView) content.findViewById(
-                    R.id.capabilities_header);
-            capabilitiesHeaderView.setText(getString(R.string.capabilities_list_title,
-                    info.getResolveInfo().loadLabel(getPackageManager())));
-
-            LinearLayout capabilitiesView = (LinearLayout) content.findViewById(R.id.capabilities);
-
-            // This capability is implicit for all services.
-            View capabilityView = inflater.inflate(
-                    com.android.internal.R.layout.app_permission_item_old, null);
-
-            ImageView imageView = (ImageView) capabilityView.findViewById(
-                    com.android.internal.R.id.perm_icon);
-            imageView.setImageDrawable(getResources().getDrawable(
-                    com.android.internal.R.drawable.ic_text_dot));
-
-            TextView labelView = (TextView) capabilityView.findViewById(
-                    com.android.internal.R.id.permission_group);
-            labelView.setText(getString(R.string.capability_title_receiveAccessibilityEvents));
-
-            TextView descriptionView = (TextView) capabilityView.findViewById(
-                    com.android.internal.R.id.permission_list);
-            descriptionView.setText(getString(R.string.capability_desc_receiveAccessibilityEvents));
-
-            List<AccessibilityServiceInfo.CapabilityInfo> capabilities =
-                    info.getCapabilityInfos();
-
-            capabilitiesView.addView(capabilityView);
-
-            // Service specific capabilities.
-            final int capabilityCount = capabilities.size();
-            for (int i = 0; i < capabilityCount; i++) {
-                AccessibilityServiceInfo.CapabilityInfo capability = capabilities.get(i);
-
-                capabilityView = inflater.inflate(
-                        com.android.internal.R.layout.app_permission_item_old, null);
-
-                imageView = (ImageView) capabilityView.findViewById(
-                        com.android.internal.R.id.perm_icon);
-                imageView.setImageDrawable(getResources().getDrawable(
-                        com.android.internal.R.drawable.ic_text_dot));
-
-                labelView = (TextView) capabilityView.findViewById(
-                        com.android.internal.R.id.permission_group);
-                labelView.setText(getString(capability.titleResId));
-
-                descriptionView = (TextView) capabilityView.findViewById(
-                        com.android.internal.R.id.permission_list);
-                descriptionView.setText(getString(capability.descResId));
-
-                capabilitiesView.addView(capabilityView);
-            }
-
-            return content;
-        }
-
-        @Override
-        public void onClick(DialogInterface dialog, int which) {
-            final boolean checked;
-            switch (which) {
-                case DialogInterface.BUTTON_POSITIVE:
-                    checked = (mShownDialogId == DIALOG_ID_ENABLE_WARNING);
-                    mToggleSwitch.setCheckedInternal(checked);
-                    getArguments().putBoolean(EXTRA_CHECKED, checked);
-                    onPreferenceToggled(mPreferenceKey, checked);
-                    break;
-                case DialogInterface.BUTTON_NEGATIVE:
-                    checked = (mShownDialogId == DIALOG_ID_DISABLE_WARNING);
-                    mToggleSwitch.setCheckedInternal(checked);
-                    getArguments().putBoolean(EXTRA_CHECKED, checked);
-                    onPreferenceToggled(mPreferenceKey, checked);
-                    break;
-                default:
-                    throw new IllegalArgumentException();
-            }
-        }
-
-        @Override
-        protected void onInstallActionBarToggleSwitch() {
-            super.onInstallActionBarToggleSwitch();
-            mToggleSwitch.setOnBeforeCheckedChangeListener(new OnBeforeCheckedChangeListener() {
-                @Override
-                public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked) {
-                    if (checked) {
-                        toggleSwitch.setCheckedInternal(false);
-                        getArguments().putBoolean(EXTRA_CHECKED, false);
-                        showDialog(DIALOG_ID_ENABLE_WARNING);
-                    } else {
-                        toggleSwitch.setCheckedInternal(true);
-                        getArguments().putBoolean(EXTRA_CHECKED, true);
-                        showDialog(DIALOG_ID_DISABLE_WARNING);
-                    }
-                    return true;
-                }
-            });
-        }
-
-        @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);
-            if (!TextUtils.isEmpty(settingsTitle) && !TextUtils.isEmpty(settingsComponentName)) {
-                Intent settingsIntent = new Intent(Intent.ACTION_MAIN).setComponent(
-                        ComponentName.unflattenFromString(settingsComponentName.toString()));
-                if (!getPackageManager().queryIntentActivities(settingsIntent, 0).isEmpty()) {
-                    mSettingsTitle = settingsTitle;
-                    mSettingsIntent = settingsIntent;
-                    setHasOptionsMenu(true);
-                }
-            }
-
-            mComponentName = arguments.getParcelable(EXTRA_COMPONENT_NAME);
-        }
-    }
-
-    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 class ToggleGlobalGesturePreferenceFragment
-            extends ToggleFeaturePreferenceFragment {
-        @Override
-        protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
-            Settings.Global.putInt(getContentResolver(),
-                    Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_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());
-            // Set a transparent drawable to prevent use of the default one.
-            getListView().setSelector(new ColorDrawable(Color.TRANSPARENT));
-            getListView().setDivider(null);
-        }
-
-        @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.setPaddingRelative(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.
-            CharSequence summary = arguments.getCharSequence(EXTRA_SUMMARY);
-            mSummaryPreference.setSummary(summary);
-        }
-    }
-
-    private static abstract class SettingsContentObserver extends ContentObserver {
-
-        public SettingsContentObserver(Handler handler) {
-            super(handler);
-        }
-
-        public void register(ContentResolver contentResolver) {
-            contentResolver.registerContentObserver(Settings.Secure.getUriFor(
-                    Settings.Secure.ACCESSIBILITY_ENABLED), false, this);
-            contentResolver.registerContentObserver(Settings.Secure.getUriFor(
-                    Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES), false, this);
-        }
-
-        public void unregister(ContentResolver contentResolver) {
-            contentResolver.unregisterContentObserver(this);
-        }
-
-        @Override
-        public abstract void onChange(boolean selfChange, Uri uri);
-    }
-}
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 24ffc50..bcf7abc 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -53,7 +53,7 @@
 import android.widget.TextView;
 
 import com.android.internal.util.ArrayUtils;
-import com.android.settings.AccessibilitySettings.ToggleAccessibilityServicePreferenceFragment;
+import com.android.settings.accessibility.ToggleAccessibilityServicePreferenceFragment;
 import com.android.settings.accounts.AccountSyncSettings;
 import com.android.settings.accounts.AuthenticatorHelper;
 import com.android.settings.accounts.ManageAccountsSettings;
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
new file mode 100644
index 0000000..d2198a7
--- /dev/null
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -0,0 +1,622 @@
+/*
+ * Copyright (C) 2009 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.AccessibilityServiceInfo;
+import android.app.ActivityManagerNative;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.res.Configuration;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.preference.CheckBoxPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceScreen;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.text.TextUtils.SimpleStringSplitter;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.accessibility.AccessibilityManager;
+import android.widget.TextView;
+
+import com.android.internal.content.PackageMonitor;
+import com.android.internal.view.RotationPolicy;
+import com.android.internal.view.RotationPolicy.RotationPolicyListener;
+import com.android.settings.DialogCreatable;
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.Utils;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Activity with the accessibility settings.
+ */
+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";
+
+    private static final float LARGE_FONT_SCALE = 1.3f;
+
+    private static final String SYSTEM_PROPERTY_MARKET_URL = "ro.screenreader.market";
+
+    static final char ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR = ':';
+
+    private static final String 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_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";
+    private static final String TOGGLE_SPEAK_PASSWORD_PREFERENCE =
+            "toggle_speak_password_preference";
+    private static final String SELECT_LONG_PRESS_TIMEOUT_PREFERENCE =
+            "select_long_press_timeout_preference";
+    private static final String ENABLE_ACCESSIBILITY_GESTURE_PREFERENCE_SCREEN =
+            "enable_global_gesture_preference_screen";
+    private static final String DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN =
+            "screen_magnification_preference_screen";
+
+    // Extras passed to sub-fragments.
+    static final String EXTRA_PREFERENCE_KEY = "preference_key";
+    static final String EXTRA_CHECKED = "checked";
+    static final String EXTRA_TITLE = "title";
+    static final String EXTRA_SUMMARY = "summary";
+    static final String EXTRA_SETTINGS_TITLE = "settings_title";
+    static final String EXTRA_COMPONENT_NAME = "component_name";
+    static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name";
+
+    // Timeout before we update the services if packages are added/removed
+    // since 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;
+
+    // Dialog IDs.
+    private static final int DIALOG_ID_NO_ACCESSIBILITY_SERVICES = 1;
+
+    // Auxiliary members.
+    final static SimpleStringSplitter sStringColonSplitter =
+            new SimpleStringSplitter(ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR);
+
+    static final Set<ComponentName> sInstalledServices = new HashSet<ComponentName>();
+
+    private final Map<String, String> mLongPressTimeoutValuetoTitleMap =
+            new HashMap<String, String>();
+
+    private final Configuration mCurConfig = new Configuration();
+
+    private final Handler mHandler = new Handler();
+
+    private final Runnable mUpdateRunnable = new Runnable() {
+        @Override
+        public void run() {
+            loadInstalledServices();
+            updateServicesPreferences();
+        }
+    };
+
+    private final PackageMonitor mSettingsPackageMonitor = new PackageMonitor() {
+        @Override
+        public void onPackageAdded(String packageName, int uid) {
+            sendUpdate();
+        }
+
+        @Override
+        public void onPackageAppeared(String packageName, int reason) {
+            sendUpdate();
+        }
+
+        @Override
+        public void onPackageDisappeared(String packageName, int reason) {
+            sendUpdate();
+        }
+
+        @Override
+        public void onPackageRemoved(String packageName, int uid) {
+            sendUpdate();
+        }
+
+        private void sendUpdate() {
+            mHandler.postDelayed(mUpdateRunnable, DELAY_UPDATE_SERVICES_MILLIS);
+        }
+    };
+
+    private final SettingsContentObserver mSettingsContentObserver =
+            new SettingsContentObserver(mHandler) {
+                @Override
+                public void onChange(boolean selfChange, Uri uri) {
+                    loadInstalledServices();
+                    updateServicesPreferences();
+                }
+            };
+
+    private final RotationPolicyListener mRotationPolicyListener = new RotationPolicyListener() {
+        @Override
+        public void onChange() {
+            updateLockScreenRotationCheckbox();
+        }
+    };
+
+    // Preference controls.
+    private PreferenceCategory mServicesCategory;
+    private PreferenceCategory mSystemsCategory;
+
+    private CheckBoxPreference mToggleLargeTextPreference;
+    private CheckBoxPreference mTogglePowerButtonEndsCallPreference;
+    private CheckBoxPreference mToggleLockScreenRotationPreference;
+    private CheckBoxPreference mToggleSpeakPasswordPreference;
+    private ListPreference mSelectLongPressTimeoutPreference;
+    private Preference mNoServicesMessagePreference;
+    private PreferenceScreen mDisplayMagnificationPreferenceScreen;
+    private PreferenceScreen mGlobalGesturePreferenceScreen;
+
+    private int mLongPressTimeoutDefault;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        addPreferencesFromResource(R.xml.accessibility_settings);
+        initializeAllPreferences();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        loadInstalledServices();
+        updateAllPreferences();
+
+        offerInstallAccessibilitySerivceOnce();
+
+        mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
+        mSettingsContentObserver.register(getContentResolver());
+        if (RotationPolicy.isRotationSupported(getActivity())) {
+            RotationPolicy.registerRotationPolicyListener(getActivity(),
+                    mRotationPolicyListener);
+        }
+    }
+
+    @Override
+    public void onPause() {
+        mSettingsPackageMonitor.unregister();
+        mSettingsContentObserver.unregister(getContentResolver());
+        if (RotationPolicy.isRotationSupported(getActivity())) {
+            RotationPolicy.unregisterRotationPolicyListener(getActivity(),
+                    mRotationPolicyListener);
+        }
+        super.onPause();
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if (preference == mSelectLongPressTimeoutPreference) {
+            String stringValue = (String) newValue;
+            Settings.Secure.putInt(getContentResolver(),
+                    Settings.Secure.LONG_PRESS_TIMEOUT, Integer.parseInt(stringValue));
+            mSelectLongPressTimeoutPreference.setSummary(
+                    mLongPressTimeoutValuetoTitleMap.get(stringValue));
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        if (mToggleLargeTextPreference == preference) {
+            handleToggleLargeTextPreferenceClick();
+            return true;
+        } else if (mTogglePowerButtonEndsCallPreference == preference) {
+            handleTogglePowerButtonEndsCallPreferenceClick();
+            return true;
+        } else if (mToggleLockScreenRotationPreference == preference) {
+            handleLockScreenRotationPreferenceClick();
+            return true;
+        } else if (mToggleSpeakPasswordPreference == preference) {
+            handleToggleSpeakPasswordPreferenceClick();
+            return true;
+        } else if (mGlobalGesturePreferenceScreen == preference) {
+            handleTogglEnableAccessibilityGesturePreferenceClick();
+            return true;
+        } else if (mDisplayMagnificationPreferenceScreen == preference) {
+            handleDisplayMagnificationPreferenceScreenClick();
+            return true;
+        }
+        return super.onPreferenceTreeClick(preferenceScreen, preference);
+    }
+
+    private void handleToggleLargeTextPreferenceClick() {
+        try {
+            mCurConfig.fontScale = mToggleLargeTextPreference.isChecked() ? LARGE_FONT_SCALE : 1;
+            ActivityManagerNative.getDefault().updatePersistentConfiguration(mCurConfig);
+        } catch (RemoteException re) {
+            /* ignore */
+        }
+    }
+
+    private void handleTogglePowerButtonEndsCallPreferenceClick() {
+        Settings.Secure.putInt(getContentResolver(),
+                Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
+                (mTogglePowerButtonEndsCallPreference.isChecked()
+                        ? Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP
+                        : Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF));
+    }
+
+    private void handleLockScreenRotationPreferenceClick() {
+        RotationPolicy.setRotationLockForAccessibility(getActivity(),
+                !mToggleLockScreenRotationPreference.isChecked());
+    }
+
+    private void handleToggleSpeakPasswordPreferenceClick() {
+        Settings.Secure.putInt(getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
+                mToggleSpeakPasswordPreference.isChecked() ? 1 : 0);
+    }
+
+    private void handleTogglEnableAccessibilityGesturePreferenceClick() {
+        Bundle extras = mGlobalGesturePreferenceScreen.getExtras();
+        extras.putString(EXTRA_TITLE, getString(
+                R.string.accessibility_global_gesture_preference_title));
+        extras.putString(EXTRA_SUMMARY, getString(
+                R.string.accessibility_global_gesture_preference_description));
+        extras.putBoolean(EXTRA_CHECKED, Settings.Global.getInt(getContentResolver(),
+                Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED, 0) == 1);
+        super.onPreferenceTreeClick(mGlobalGesturePreferenceScreen,
+                mGlobalGesturePreferenceScreen);
+    }
+
+    private void handleDisplayMagnificationPreferenceScreenClick() {
+        Bundle extras = mDisplayMagnificationPreferenceScreen.getExtras();
+        extras.putString(EXTRA_TITLE, getString(
+                R.string.accessibility_screen_magnification_title));
+        extras.putCharSequence(EXTRA_SUMMARY, getActivity().getResources().getText(
+                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);
+
+        // Power button ends calls.
+        mTogglePowerButtonEndsCallPreference =
+                (CheckBoxPreference) findPreference(TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE);
+        if (!KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
+                || !Utils.isVoiceCapable(getActivity())) {
+            mSystemsCategory.removePreference(mTogglePowerButtonEndsCallPreference);
+        }
+
+        // Lock screen rotation.
+        mToggleLockScreenRotationPreference =
+                (CheckBoxPreference) findPreference(TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE);
+        if (!RotationPolicy.isRotationSupported(getActivity())) {
+            mSystemsCategory.removePreference(mToggleLockScreenRotationPreference);
+        }
+
+        // Speak passwords.
+        mToggleSpeakPasswordPreference =
+                (CheckBoxPreference) findPreference(TOGGLE_SPEAK_PASSWORD_PREFERENCE);
+
+        // Long press timeout.
+        mSelectLongPressTimeoutPreference =
+                (ListPreference) findPreference(SELECT_LONG_PRESS_TIMEOUT_PREFERENCE);
+        mSelectLongPressTimeoutPreference.setOnPreferenceChangeListener(this);
+        if (mLongPressTimeoutValuetoTitleMap.size() == 0) {
+            String[] timeoutValues = getResources().getStringArray(
+                    R.array.long_press_timeout_selector_values);
+            mLongPressTimeoutDefault = Integer.parseInt(timeoutValues[0]);
+            String[] timeoutTitles = getResources().getStringArray(
+                    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]);
+            }
+        }
+
+        // Display magnification.
+        mDisplayMagnificationPreferenceScreen = (PreferenceScreen) findPreference(
+                DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN);
+
+        // Global gesture.
+        mGlobalGesturePreferenceScreen =
+                (PreferenceScreen) findPreference(ENABLE_ACCESSIBILITY_GESTURE_PREFERENCE_SCREEN);
+        final int longPressOnPowerBehavior = getActivity().getResources().getInteger(
+                com.android.internal.R.integer.config_longPressOnPowerBehavior);
+        final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
+        if (!KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
+                || longPressOnPowerBehavior != LONG_PRESS_POWER_GLOBAL_ACTIONS) {
+            // Remove accessibility shortcut if power key is not present
+            // nor long press power does not show global actions menu.
+            mSystemsCategory.removePreference(mGlobalGesturePreferenceScreen);
+        }
+    }
+
+    private void updateAllPreferences() {
+        updateServicesPreferences();
+        updateSystemPreferences();
+    }
+
+    private void updateServicesPreferences() {
+        // Since services category is auto generated we have to do a pass
+        // to generate it since services can come and go and then based on
+        // the global accessibility state to decided whether it is enabled.
+
+        // Generate.
+        mServicesCategory.removeAll();
+
+        AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(getActivity());
+
+        List<AccessibilityServiceInfo> installedServices =
+                accessibilityManager.getInstalledAccessibilityServiceList();
+        Set<ComponentName> enabledServices = AccessibilityUtils.getEnabledServicesFromSettings(
+                getActivity());
+
+        final boolean accessibilityEnabled = Settings.Secure.getInt(getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
+
+        for (int i = 0, count = installedServices.size(); i < count; ++i) {
+            AccessibilityServiceInfo info = installedServices.get(i);
+
+            PreferenceScreen preference = getPreferenceManager().createPreferenceScreen(
+                    getActivity());
+            String title = info.getResolveInfo().loadLabel(getPackageManager()).toString();
+
+            ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo;
+            ComponentName componentName = new ComponentName(serviceInfo.packageName,
+                    serviceInfo.name);
+
+            preference.setKey(componentName.flattenToString());
+
+            preference.setTitle(title);
+            final boolean serviceEnabled = accessibilityEnabled
+                    && enabledServices.contains(componentName);
+            if (serviceEnabled) {
+                preference.setSummary(getString(R.string.accessibility_feature_state_on));
+            } else {
+                preference.setSummary(getString(R.string.accessibility_feature_state_off));
+            }
+
+            preference.setOrder(i);
+            preference.setFragment(ToggleAccessibilityServicePreferenceFragment.class.getName());
+            preference.setPersistent(true);
+
+            Bundle extras = preference.getExtras();
+            extras.putString(EXTRA_PREFERENCE_KEY, preference.getKey());
+            extras.putBoolean(EXTRA_CHECKED, serviceEnabled);
+            extras.putString(EXTRA_TITLE, title);
+
+            String description = info.loadDescription(getPackageManager());
+            if (TextUtils.isEmpty(description)) {
+                description = getString(R.string.accessibility_service_default_description);
+            }
+            extras.putString(EXTRA_SUMMARY, description);
+
+            String settingsClassName = info.getSettingsActivityName();
+            if (!TextUtils.isEmpty(settingsClassName)) {
+                extras.putString(EXTRA_SETTINGS_TITLE,
+                        getString(R.string.accessibility_menu_item_settings));
+                extras.putString(EXTRA_SETTINGS_COMPONENT_NAME,
+                        new ComponentName(info.getResolveInfo().serviceInfo.packageName,
+                                settingsClassName).flattenToString());
+            }
+
+            extras.putParcelable(EXTRA_COMPONENT_NAME, componentName);
+
+            mServicesCategory.addPreference(preference);
+        }
+
+        if (mServicesCategory.getPreferenceCount() == 0) {
+            if (mNoServicesMessagePreference == null) {
+                mNoServicesMessagePreference = new Preference(getActivity()) {
+                        @Override
+                    protected void onBindView(View view) {
+                        super.onBindView(view);
+                        TextView summaryView = (TextView) view.findViewById(R.id.summary);
+                        String title = getString(R.string.accessibility_no_services_installed);
+                        summaryView.setText(title);
+                    }
+                };
+                mNoServicesMessagePreference.setPersistent(false);
+                mNoServicesMessagePreference.setLayoutResource(
+                        R.layout.text_description_preference);
+                mNoServicesMessagePreference.setSelectable(false);
+            }
+            mServicesCategory.addPreference(mNoServicesMessagePreference);
+        }
+    }
+
+    private void updateSystemPreferences() {
+        // Large text.
+        try {
+            mCurConfig.updateFrom(ActivityManagerNative.getDefault().getConfiguration());
+        } catch (RemoteException re) {
+            /* ignore */
+        }
+        mToggleLargeTextPreference.setChecked(mCurConfig.fontScale == LARGE_FONT_SCALE);
+
+        // Power button ends calls.
+        if (KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
+                && Utils.isVoiceCapable(getActivity())) {
+            final int incallPowerBehavior = Settings.Secure.getInt(getContentResolver(),
+                    Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
+                    Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT);
+            final boolean powerButtonEndsCall =
+                    (incallPowerBehavior == Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP);
+            mTogglePowerButtonEndsCallPreference.setChecked(powerButtonEndsCall);
+        }
+
+        // Auto-rotate screen
+        updateLockScreenRotationCheckbox();
+
+        // Speak passwords.
+        final boolean speakPasswordEnabled = Settings.Secure.getInt(getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0) != 0;
+        mToggleSpeakPasswordPreference.setChecked(speakPasswordEnabled);
+
+        // Long press timeout.
+        final int longPressTimeout = Settings.Secure.getInt(getContentResolver(),
+                Settings.Secure.LONG_PRESS_TIMEOUT, mLongPressTimeoutDefault);
+        String value = String.valueOf(longPressTimeout);
+        mSelectLongPressTimeoutPreference.setValue(value);
+        mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValuetoTitleMap.get(value));
+
+        // 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);
+        }
+
+        // Global gesture
+        final boolean globalGestureEnabled = Settings.Global.getInt(getContentResolver(),
+                Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED, 0) == 1;
+        if (globalGestureEnabled) {
+            mGlobalGesturePreferenceScreen.setSummary(
+                    R.string.accessibility_global_gesture_preference_summary_on);
+        } else {
+            mGlobalGesturePreferenceScreen.setSummary(
+                    R.string.accessibility_global_gesture_preference_summary_off);
+        }
+    }
+
+    private void updateLockScreenRotationCheckbox() {
+        Context context = getActivity();
+        if (context != null) {
+            mToggleLockScreenRotationPreference.setChecked(
+                    !RotationPolicy.isRotationLocked(context));
+        }
+    }
+
+    private void offerInstallAccessibilitySerivceOnce() {
+        // There is always one preference - if no services it is just a message.
+        if (mServicesCategory.getPreference(0) != mNoServicesMessagePreference) {
+            return;
+        }
+        SharedPreferences preferences = getActivity().getPreferences(Context.MODE_PRIVATE);
+        final boolean offerInstallService = !preferences.getBoolean(
+                KEY_INSTALL_ACCESSIBILITY_SERVICE_OFFERED_ONCE, false);
+        if (offerInstallService) {
+            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);
+
+            if (getPackageManager().resolveActivity(marketIntent, 0) == null) {
+                // Don't show the dialog if no market app is found/installed.
+                return;
+            }
+
+            preferences.edit().putBoolean(KEY_INSTALL_ACCESSIBILITY_SERVICE_OFFERED_ONCE,
+                    true).commit();
+            // Notify user that they do not have any accessibility
+            // services installed and direct them to Market to get TalkBack.
+            showDialog(DIALOG_ID_NO_ACCESSIBILITY_SERVICES);
+        }
+    }
+
+    @Override
+    public Dialog onCreateDialog(int dialogId) {
+        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() {
+                                    @Override
+                                    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;
+        }
+    }
+
+    private void loadInstalledServices() {
+        Set<ComponentName> installedServices = sInstalledServices;
+        installedServices.clear();
+
+        List<AccessibilityServiceInfo> installedServiceInfos =
+                AccessibilityManager.getInstance(getActivity())
+                        .getInstalledAccessibilityServiceList();
+        if (installedServiceInfos == null) {
+            return;
+        }
+
+        final int installedServiceInfoCount = installedServiceInfos.size();
+        for (int i = 0; i < installedServiceInfoCount; i++) {
+            ResolveInfo resolveInfo = installedServiceInfos.get(i).getResolveInfo();
+            ComponentName installedService = new ComponentName(
+                    resolveInfo.serviceInfo.packageName,
+                    resolveInfo.serviceInfo.name);
+            installedServices.add(installedService);
+        }
+    }
+}
diff --git a/src/com/android/settings/accessibility/AccessibilityUtils.java b/src/com/android/settings/accessibility/AccessibilityUtils.java
new file mode 100644
index 0000000..fd4a34f
--- /dev/null
+++ b/src/com/android/settings/accessibility/AccessibilityUtils.java
@@ -0,0 +1,37 @@
+package com.android.settings.accessibility;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
+import android.text.TextUtils.SimpleStringSplitter;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * TODO: Insert description here. (generated by alanv)
+ */
+public class AccessibilityUtils {
+
+    static Set<ComponentName> getEnabledServicesFromSettings(Context context) {
+        String enabledServicesSetting = Settings.Secure.getString(context.getContentResolver(),
+                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+        if (enabledServicesSetting == null) {
+            enabledServicesSetting = "";
+        }
+        Set<ComponentName> enabledServices = new HashSet<ComponentName>();
+        SimpleStringSplitter colonSplitter = AccessibilitySettings.sStringColonSplitter;
+        colonSplitter.setString(enabledServicesSetting);
+        while (colonSplitter.hasNext()) {
+            String componentNameString = colonSplitter.next();
+            ComponentName enabledService = ComponentName.unflattenFromString(
+                    componentNameString);
+            if (enabledService != null) {
+                enabledServices.add(enabledService);
+            }
+        }
+        return enabledServices;
+    }
+
+}
diff --git a/src/com/android/settings/accessibility/SettingsContentObserver.java b/src/com/android/settings/accessibility/SettingsContentObserver.java
new file mode 100644
index 0000000..c3baec5
--- /dev/null
+++ b/src/com/android/settings/accessibility/SettingsContentObserver.java
@@ -0,0 +1,43 @@
+/*
+ * 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.content.ContentResolver;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.Settings;
+
+abstract class SettingsContentObserver extends ContentObserver {
+    public SettingsContentObserver(Handler handler) {
+        super(handler);
+    }
+
+    public void register(ContentResolver contentResolver) {
+        contentResolver.registerContentObserver(Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_ENABLED), false, this);
+        contentResolver.registerContentObserver(Settings.Secure.getUriFor(
+                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES), false, this);
+    }
+
+    public void unregister(ContentResolver contentResolver) {
+        contentResolver.unregisterContentObserver(this);
+    }
+
+    @Override
+    public abstract void onChange(boolean selfChange, Uri uri);
+}
diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
new file mode 100644
index 0000000..3059dcc
--- /dev/null
+++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
@@ -0,0 +1,312 @@
+/*
+ * 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.AccessibilityServiceInfo;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.accessibility.AccessibilityManager;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.settings.R;
+import com.android.settings.accessibility.ToggleSwitch.OnBeforeCheckedChangeListener;
+
+import java.util.List;
+import java.util.Set;
+
+public class ToggleAccessibilityServicePreferenceFragment
+        extends ToggleFeaturePreferenceFragment implements DialogInterface.OnClickListener {
+
+    private static final int DIALOG_ID_ENABLE_WARNING = 1;
+    private static final int DIALOG_ID_DISABLE_WARNING = 2;
+
+    private final SettingsContentObserver mSettingsContentObserver =
+            new SettingsContentObserver(new Handler()) {
+            @Override
+                public void onChange(boolean selfChange, Uri uri) {
+                    String settingValue = Settings.Secure.getString(getContentResolver(),
+                            Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+                    final boolean enabled = settingValue.contains(mComponentName.flattenToString());
+                    mToggleSwitch.setCheckedInternal(enabled);
+                }
+            };
+
+    private ComponentName mComponentName;
+
+    private int mShownDialogId;
+
+    @Override
+    public void onResume() {
+        mSettingsContentObserver.register(getContentResolver());
+        super.onResume();
+    }
+
+    @Override
+    public void onPause() {
+        mSettingsContentObserver.unregister(getContentResolver());
+        super.onPause();
+    }
+
+    @Override
+    public void onPreferenceToggled(String preferenceKey, boolean enabled) {
+        // Parse the enabled services.
+        Set<ComponentName> enabledServices = AccessibilityUtils.getEnabledServicesFromSettings(
+                getActivity());
+
+        // Determine enabled services and accessibility state.
+        ComponentName toggledService = ComponentName.unflattenFromString(preferenceKey);
+        boolean accessibilityEnabled = false;
+        if (enabled) {
+            enabledServices.add(toggledService);
+            // Enabling at least one service enables accessibility.
+            accessibilityEnabled = true;
+        } else {
+            enabledServices.remove(toggledService);
+            // Check how many enabled and installed services are present.
+            Set<ComponentName> installedServices = AccessibilitySettings.sInstalledServices;
+            for (ComponentName enabledService : enabledServices) {
+                if (installedServices.contains(enabledService)) {
+                    // Disabling the last service disables accessibility.
+                    accessibilityEnabled = true;
+                    break;
+                }
+            }
+        }
+
+        // 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.
+        for (ComponentName enabledService : enabledServices) {
+            enabledServicesBuilder.append(enabledService.flattenToString());
+            enabledServicesBuilder.append(
+                    AccessibilitySettings.ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR);
+        }
+        final int enabledServicesBuilderLength = enabledServicesBuilder.length();
+        if (enabledServicesBuilderLength > 0) {
+            enabledServicesBuilder.deleteCharAt(enabledServicesBuilderLength - 1);
+        }
+        Settings.Secure.putString(getContentResolver(),
+                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+                enabledServicesBuilder.toString());
+
+        // Update accessibility enabled.
+        Settings.Secure.putInt(getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_ENABLED, accessibilityEnabled ? 1 : 0);
+    }
+
+    // IMPORTANT: Refresh the info since there are dynamically changing
+    // capabilities. For
+    // example, before JellyBean MR2 the user was granting the explore by touch
+    // one.
+    private AccessibilityServiceInfo getAccessibilityServiceInfo() {
+        List<AccessibilityServiceInfo> serviceInfos = AccessibilityManager.getInstance(
+                getActivity()).getInstalledAccessibilityServiceList();
+        final int serviceInfoCount = serviceInfos.size();
+        for (int i = 0; i < serviceInfoCount; i++) {
+            AccessibilityServiceInfo serviceInfo = serviceInfos.get(i);
+            ResolveInfo resolveInfo = serviceInfo.getResolveInfo();
+            if (mComponentName.getPackageName().equals(resolveInfo.serviceInfo.packageName)
+                    && mComponentName.getClassName().equals(resolveInfo.serviceInfo.name)) {
+                return serviceInfo;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Dialog onCreateDialog(int dialogId) {
+        switch (dialogId) {
+            case DIALOG_ID_ENABLE_WARNING: {
+            mShownDialogId = DIALOG_ID_ENABLE_WARNING;
+            AccessibilityServiceInfo info = getAccessibilityServiceInfo();
+            if (info == null) {
+                return null;
+            }
+            return new AlertDialog.Builder(getActivity())
+            .setTitle(getString(R.string.enable_service_title,
+                    info.getResolveInfo().loadLabel(getPackageManager())))
+                    .setIconAttribute(android.R.attr.alertDialogIcon)
+                    .setView(createEnableDialogContentView(info))
+                    .setCancelable(true)
+                    .setPositiveButton(android.R.string.ok, this)
+                    .setNegativeButton(android.R.string.cancel, this)
+                    .create();
+        }
+            case DIALOG_ID_DISABLE_WARNING: {
+            mShownDialogId = DIALOG_ID_DISABLE_WARNING;
+            AccessibilityServiceInfo info = getAccessibilityServiceInfo();
+            if (info == null) {
+                return null;
+            }
+            return new AlertDialog.Builder(getActivity())
+            .setTitle(getString(R.string.disable_service_title,
+                    info.getResolveInfo().loadLabel(getPackageManager())))
+                    .setIconAttribute(android.R.attr.alertDialogIcon)
+                    .setMessage(getString(R.string.disable_service_message,
+                            info.getResolveInfo().loadLabel(getPackageManager())))
+                    .setCancelable(true)
+                    .setPositiveButton(android.R.string.ok, this)
+                    .setNegativeButton(android.R.string.cancel, this)
+                    .create();
+        }
+            default: {
+            throw new IllegalArgumentException();
+        }
+        }
+    }
+
+    private View createEnableDialogContentView(AccessibilityServiceInfo info) {
+        LayoutInflater inflater = (LayoutInflater) getSystemService(
+                Context.LAYOUT_INFLATER_SERVICE);
+
+        View content = inflater.inflate(R.layout.enable_accessibility_service_dialog_content,
+                null);
+
+        TextView capabilitiesHeaderView = (TextView) content.findViewById(
+                R.id.capabilities_header);
+        capabilitiesHeaderView.setText(getString(R.string.capabilities_list_title,
+                info.getResolveInfo().loadLabel(getPackageManager())));
+
+        LinearLayout capabilitiesView = (LinearLayout) content.findViewById(R.id.capabilities);
+
+        // This capability is implicit for all services.
+        View capabilityView = inflater.inflate(
+                com.android.internal.R.layout.app_permission_item_old, null);
+
+        ImageView imageView = (ImageView) capabilityView.findViewById(
+                com.android.internal.R.id.perm_icon);
+        imageView.setImageDrawable(getResources().getDrawable(
+                com.android.internal.R.drawable.ic_text_dot));
+
+        TextView labelView = (TextView) capabilityView.findViewById(
+                com.android.internal.R.id.permission_group);
+        labelView.setText(getString(R.string.capability_title_receiveAccessibilityEvents));
+
+        TextView descriptionView = (TextView) capabilityView.findViewById(
+                com.android.internal.R.id.permission_list);
+        descriptionView.setText(getString(R.string.capability_desc_receiveAccessibilityEvents));
+
+        List<AccessibilityServiceInfo.CapabilityInfo> capabilities =
+                info.getCapabilityInfos();
+
+        capabilitiesView.addView(capabilityView);
+
+        // Service specific capabilities.
+        final int capabilityCount = capabilities.size();
+        for (int i = 0; i < capabilityCount; i++) {
+            AccessibilityServiceInfo.CapabilityInfo capability = capabilities.get(i);
+
+            capabilityView = inflater.inflate(
+                    com.android.internal.R.layout.app_permission_item_old, null);
+
+            imageView = (ImageView) capabilityView.findViewById(
+                    com.android.internal.R.id.perm_icon);
+            imageView.setImageDrawable(getResources().getDrawable(
+                    com.android.internal.R.drawable.ic_text_dot));
+
+            labelView = (TextView) capabilityView.findViewById(
+                    com.android.internal.R.id.permission_group);
+            labelView.setText(getString(capability.titleResId));
+
+            descriptionView = (TextView) capabilityView.findViewById(
+                    com.android.internal.R.id.permission_list);
+            descriptionView.setText(getString(capability.descResId));
+
+            capabilitiesView.addView(capabilityView);
+        }
+
+        return content;
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        final boolean checked;
+        switch (which) {
+            case DialogInterface.BUTTON_POSITIVE:
+                checked = (mShownDialogId == DIALOG_ID_ENABLE_WARNING);
+                mToggleSwitch.setCheckedInternal(checked);
+                getArguments().putBoolean(AccessibilitySettings.EXTRA_CHECKED, checked);
+                onPreferenceToggled(mPreferenceKey, checked);
+                break;
+            case DialogInterface.BUTTON_NEGATIVE:
+                checked = (mShownDialogId == DIALOG_ID_DISABLE_WARNING);
+                mToggleSwitch.setCheckedInternal(checked);
+                getArguments().putBoolean(AccessibilitySettings.EXTRA_CHECKED, checked);
+                onPreferenceToggled(mPreferenceKey, checked);
+                break;
+            default:
+                throw new IllegalArgumentException();
+        }
+    }
+
+    @Override
+    protected void onInstallActionBarToggleSwitch() {
+        super.onInstallActionBarToggleSwitch();
+        mToggleSwitch.setOnBeforeCheckedChangeListener(new OnBeforeCheckedChangeListener() {
+                @Override
+            public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked) {
+                if (checked) {
+                    toggleSwitch.setCheckedInternal(false);
+                    getArguments().putBoolean(AccessibilitySettings.EXTRA_CHECKED, false);
+                    showDialog(DIALOG_ID_ENABLE_WARNING);
+                } else {
+                    toggleSwitch.setCheckedInternal(true);
+                    getArguments().putBoolean(AccessibilitySettings.EXTRA_CHECKED, true);
+                    showDialog(DIALOG_ID_DISABLE_WARNING);
+                }
+                return true;
+            }
+        });
+    }
+
+    @Override
+    protected void onProcessArguments(Bundle arguments) {
+        super.onProcessArguments(arguments);
+        // Settings title and intent.
+        String settingsTitle = arguments.getString(AccessibilitySettings.EXTRA_SETTINGS_TITLE);
+        String settingsComponentName = arguments.getString(
+                AccessibilitySettings.EXTRA_SETTINGS_COMPONENT_NAME);
+        if (!TextUtils.isEmpty(settingsTitle) && !TextUtils.isEmpty(settingsComponentName)) {
+            Intent settingsIntent = new Intent(Intent.ACTION_MAIN).setComponent(
+                    ComponentName.unflattenFromString(settingsComponentName.toString()));
+            if (!getPackageManager().queryIntentActivities(settingsIntent, 0).isEmpty()) {
+                mSettingsTitle = settingsTitle;
+                mSettingsIntent = settingsIntent;
+                setHasOptionsMenu(true);
+            }
+        }
+
+        mComponentName = arguments.getParcelable(AccessibilitySettings.EXTRA_COMPONENT_NAME);
+    }
+}
diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
new file mode 100644
index 0000000..171b1ac
--- /dev/null
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -0,0 +1,155 @@
+/*
+ * 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.app.ActionBar;
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+import android.view.Gravity;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.widget.TextView;
+
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+
+public 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());
+        // Set a transparent drawable to prevent use of the default one.
+        getListView().setSelector(new ColorDrawable(Color.TRANSPARENT));
+        getListView().setDivider(null);
+    }
+
+    @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.setPaddingRelative(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(AccessibilitySettings.EXTRA_PREFERENCE_KEY);
+        // Enabled.
+        final boolean enabled = arguments.getBoolean(AccessibilitySettings.EXTRA_CHECKED);
+        mToggleSwitch.setCheckedInternal(enabled);
+        // Title.
+        PreferenceActivity activity = (PreferenceActivity) getActivity();
+        if (!activity.onIsMultiPane() || activity.onIsHidingHeaders()) {
+            mOldActivityTitle = getActivity().getTitle();
+            String title = arguments.getString(AccessibilitySettings.EXTRA_TITLE);
+            getActivity().getActionBar().setTitle(title);
+        }
+        // Summary.
+        CharSequence summary = arguments.getCharSequence(AccessibilitySettings.EXTRA_SUMMARY);
+        mSummaryPreference.setSummary(summary);
+    }
+}
diff --git a/src/com/android/settings/accessibility/ToggleGlobalGesturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleGlobalGesturePreferenceFragment.java
new file mode 100644
index 0000000..f4ac2cc
--- /dev/null
+++ b/src/com/android/settings/accessibility/ToggleGlobalGesturePreferenceFragment.java
@@ -0,0 +1,44 @@
+/*
+ * 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.provider.Settings;
+
+import com.android.settings.accessibility.ToggleSwitch.OnBeforeCheckedChangeListener;
+
+public class ToggleGlobalGesturePreferenceFragment
+        extends ToggleFeaturePreferenceFragment {
+    @Override
+    protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
+        Settings.Global.putInt(getContentResolver(),
+                Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_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(AccessibilitySettings.EXTRA_CHECKED, checked);
+                onPreferenceToggled(mPreferenceKey, checked);
+                return false;
+            }
+        });
+    }
+}
diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
new file mode 100644
index 0000000..27d07d2
--- /dev/null
+++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
@@ -0,0 +1,44 @@
+/*
+ * 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.provider.Settings;
+
+import com.android.settings.accessibility.ToggleSwitch.OnBeforeCheckedChangeListener;
+
+public 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(AccessibilitySettings.EXTRA_CHECKED, checked);
+                onPreferenceToggled(mPreferenceKey, checked);
+                return false;
+            }
+        });
+    }
+}
diff --git a/src/com/android/settings/accessibility/ToggleSwitch.java b/src/com/android/settings/accessibility/ToggleSwitch.java
new file mode 100644
index 0000000..e7c39e4
--- /dev/null
+++ b/src/com/android/settings/accessibility/ToggleSwitch.java
@@ -0,0 +1,49 @@
+/*
+ * 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.content.Context;
+import android.widget.Switch;
+
+public class ToggleSwitch extends Switch {
+    private ToggleSwitch.OnBeforeCheckedChangeListener mOnBeforeListener;
+
+    public static interface OnBeforeCheckedChangeListener {
+        public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked);
+    }
+
+    public ToggleSwitch(Context context) {
+        super(context);
+    }
+
+    public void setOnBeforeCheckedChangeListener(OnBeforeCheckedChangeListener listener) {
+        mOnBeforeListener = listener;
+    }
+
+    @Override
+    public void setChecked(boolean checked) {
+        if (mOnBeforeListener != null
+                && mOnBeforeListener.onBeforeCheckedChanged(this, checked)) {
+            return;
+        }
+        super.setChecked(checked);
+    }
+
+    public void setCheckedInternal(boolean checked) {
+        super.setChecked(checked);
+    }
+}
