Merge "Use WebViewFactory accessors to find experimental state"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index c894453..49fe4d5 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -65,6 +65,7 @@
     <uses-permission android:name="android.permission.SET_TIME" />
     <uses-permission android:name="android.permission.ACCESS_NOTIFICATIONS" />
     <uses-permission android:name="android.permission.REBOOT" />
+    <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
 
     <application android:label="@string/settings_label"
             android:icon="@mipmap/ic_launcher_settings"
@@ -966,7 +967,7 @@
                 <category android:name="com.android.settings.SHORTCUT" />
             </intent-filter>
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
-                android:value="com.android.settings.AccessibilitySettings" />
+                android:value="com.android.settings.accessibility.AccessibilitySettings" />
             <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
                 android:resource="@id/accessibility_settings" />
         </activity>
diff --git a/res/layout/preference_app_restrictions.xml b/res/layout/preference_app_restrictions.xml
index a8a93d1..753099d 100644
--- a/res/layout/preference_app_restrictions.xml
+++ b/res/layout/preference_app_restrictions.xml
@@ -19,8 +19,7 @@
     android:layout_height="wrap_content"
     android:minHeight="?android:attr/listPreferredItemHeight"
     android:gravity="center_vertical"
-    android:paddingStart="@*android:dimen/preference_item_padding_side"
-    android:paddingEnd="?android:attr/scrollbarSize">
+    android:paddingStart="@*android:dimen/preference_item_padding_side">
 
     <LinearLayout
         android:layout_width="wrap_content"
@@ -101,7 +100,6 @@
         android:id="@android:id/widget_frame"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
-        android:paddingRight="?android:attr/scrollbarSize"
         android:gravity="center_vertical"
         android:orientation="vertical" />
 </LinearLayout>
diff --git a/res/layout/user_dictionary_add_word_fullscreen.xml b/res/layout/user_dictionary_add_word_fullscreen.xml
index 57f9184..42bd197 100644
--- a/res/layout/user_dictionary_add_word_fullscreen.xml
+++ b/res/layout/user_dictionary_add_word_fullscreen.xml
@@ -62,22 +62,6 @@
             android:imeOptions="flagNoFullscreen"
             android:inputType="textNoSuggestions"
             android:maxLength="@integer/maximum_user_dictionary_word_length" />
-
-        <TextView
-            android:id="@+id/user_dictionary_add_locale_label"
-            style="?android:attr/textAppearanceSmall"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="start|center_vertical"
-            android:text="@string/user_dict_settings_add_locale_option_name" />
-
-        <Spinner
-            android:id="@+id/user_dictionary_add_locale"
-            android:layout_width="wrap_content"
-            android:layout_gravity="fill_horizontal|center_vertical"
-            android:layout_marginBottom="8dip"
-            android:layout_marginStart="8dip"
-            android:layout_marginTop="8dip" />
     </GridLayout>
 
 </LinearLayout>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index a60db45..f7d0f19 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -599,7 +599,7 @@
     <string name="wifi_signal" msgid="5514120261628065287">"Síla signálu"</string>
     <string name="wifi_status" msgid="4824568012414605414">"Stav"</string>
     <string name="wifi_speed" msgid="3526198708812322037">"Rychlost připojení"</string>
-    <string name="wifi_ip_address" msgid="1440054061044402918">"Adresa IP"</string>
+    <string name="wifi_ip_address" msgid="1440054061044402918">"IP adresa"</string>
     <string name="wifi_eap_method" msgid="8529436133640730382">"Metoda EAP"</string>
     <string name="please_select_phase2" msgid="5231074529772044898">"Ověření Phase 2"</string>
     <string name="wifi_eap_ca_cert" msgid="3521574865488892851">"Certifikát CA"</string>
@@ -644,7 +644,7 @@
     <string name="wifi_setting_frequency_band_summary" msgid="3250740757118009784">"Uveďte provozní frekvenční rozsah"</string>
     <string name="wifi_setting_frequency_band_error" msgid="837281974489794378">"Při nastavení frekvenčního pásma došlo k problému."</string>
     <string name="wifi_advanced_mac_address_title" msgid="6571335466330978393">"Adresa MAC"</string>
-    <string name="wifi_advanced_ip_address_title" msgid="6215297094363164846">"Adresa IP"</string>
+    <string name="wifi_advanced_ip_address_title" msgid="6215297094363164846">"IP adresa"</string>
     <string name="wifi_advanced_settings_label" msgid="3654366894867838338">"Nastavení adresy IP"</string>
     <string name="wifi_ip_settings_menu_save" msgid="7296724066102908366">"Uložit"</string>
     <string name="wifi_ip_settings_menu_cancel" msgid="6582567330136502340">"Zrušit"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index a72e930..4d2ef70 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -1624,7 +1624,7 @@
     <string name="background_data_summary" msgid="8328521479872763452">"Synchronisation, envoi et réception de données à tout moment"</string>
     <string name="background_data_dialog_title" msgid="6059217698124786537">"Dés. données arr.-plan ?"</string>
     <string name="background_data_dialog_message" msgid="6981661606680941633">"La désactivation des données en arrière-plan économise la batterie et réduit l\'utilisation des données. Certaines applications peuvent continuer d\'utiliser la connexion Internet en arrière-plan."</string>
-    <string name="sync_automatically" msgid="1682730255435062059">"Synchro auto des données des applis"</string>
+    <string name="sync_automatically" msgid="1682730255435062059">"Synchro auto"</string>
     <string name="sync_enabled" msgid="4551148952179416813">"Synchronisation activée"</string>
     <string name="sync_disabled" msgid="8511659877596511991">"Synchronisation désactivée"</string>
     <string name="sync_error" msgid="5060969083117872149">"Erreur de synchronisation"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 2802756..afe4038 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -353,7 +353,7 @@
     <string name="unlock_set_unlock_off_summary" msgid="94361581669110415"></string>
     <string name="unlock_set_unlock_none_title" msgid="2871898266296656162">"הסט"</string>
     <string name="unlock_set_unlock_none_summary" msgid="8914673583104628191">"אין אבטחה"</string>
-    <string name="unlock_set_unlock_biometric_weak_title" msgid="2227215291604628670">"ביטול נעילת פרצוף"</string>
+    <string name="unlock_set_unlock_biometric_weak_title" msgid="2227215291604628670">"זיהוי פרצוף"</string>
     <string name="unlock_set_unlock_biometric_weak_summary" msgid="180083326982058964">"אבטחה נמוכה, ניסיוני"</string>
     <string name="unlock_set_unlock_pattern_title" msgid="2912067603917311700">"קו"</string>
     <string name="unlock_set_unlock_pattern_summary" msgid="7062696666227725593">"אבטחה בינונית"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index ddedb4a..0aaf258 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -1725,7 +1725,7 @@
     <string name="show_all_anrs_summary" msgid="641908614413544127">"バックグラウンドアプリが応答しない場合に通知する"</string>
     <string name="experimental_webview" msgid="4492200819033780927">"試験運用版WebViewを使用"</string>
     <string name="experimental_webview_summary" msgid="3431620080869482446">"アプリは最新(ベータ版)のWebViewを使用します"</string>
-    <string name="data_usage_summary_title" msgid="3804110657238092929">"データ使用"</string>
+    <string name="data_usage_summary_title" msgid="3804110657238092929">"データ使用量"</string>
     <string name="data_usage_cycle" msgid="5652529796195787949">"データ使用サイクル"</string>
     <string name="data_usage_menu_roaming" msgid="8042359966835203296">"データローミング"</string>
     <string name="data_usage_menu_restrict_background" msgid="1989394568592253331">"バックグラウンドデータを制限する"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index cf6e195..5fdff24 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -1720,7 +1720,7 @@
     <string name="show_all_anrs_summary" msgid="641908614413544127">"Afiş. dialog. Aplic. nu răsp. pt. aplic. de fundal"</string>
     <string name="experimental_webview" msgid="4492200819033780927">"WebView experimental"</string>
     <string name="experimental_webview_summary" msgid="3431620080869482446">"Aplicațiile vor utiliza cel mai nou WebView (beta)"</string>
-    <string name="data_usage_summary_title" msgid="3804110657238092929">"Rata de utilizare a datelor"</string>
+    <string name="data_usage_summary_title" msgid="3804110657238092929">"Utilizarea datelor"</string>
     <string name="data_usage_cycle" msgid="5652529796195787949">"Ciclul de util. a datelor"</string>
     <string name="data_usage_menu_roaming" msgid="8042359966835203296">"Roaming de date"</string>
     <string name="data_usage_menu_restrict_background" msgid="1989394568592253331">"Restricţionaţi datele de fundal"</string>
@@ -1728,7 +1728,7 @@
     <string name="data_usage_menu_show_wifi" msgid="5056401102877964564">"Afișați utilizarea Wi-Fi"</string>
     <string name="data_usage_menu_show_ethernet" msgid="5181361208532314097">"Afişaţi utiliz. conex. Ethernet"</string>
     <string name="data_usage_menu_metered" msgid="5056695223222541863">"Hotspoturi mobile"</string>
-    <string name="data_usage_menu_auto_sync" msgid="8203999775948778560">"Sincronizaţi datele în mod automat"</string>
+    <string name="data_usage_menu_auto_sync" msgid="8203999775948778560">"Sincronizați automat datele"</string>
     <string name="data_usage_change_cycle" msgid="7776556448920114866">"Schimbaţi data ciclului..."</string>
     <string name="data_usage_pick_cycle_day" msgid="4470796861757050966">"Ziua din lună pentru resetarea ciclului de utilizare a datelor:"</string>
     <string name="data_usage_empty" msgid="8621855507876539282">"Nicio aplic. nu a utilizat date în ac. perioadă."</string>
diff --git a/res/values-tr/arrays.xml b/res/values-tr/arrays.xml
index 4073c12..e052fd1 100644
--- a/res/values-tr/arrays.xml
+++ b/res/values-tr/arrays.xml
@@ -278,7 +278,7 @@
     <item msgid="785049718065337473">"bildirim sesi düzeyi"</item>
     <item msgid="6700305533746877052">"Bluetooth sesi düzeyi"</item>
     <item msgid="2029227495214047094">"uyanık tut"</item>
-    <item msgid="26109888160231211">"monitör konumu"</item>
+    <item msgid="26109888160231211">"konumu izle"</item>
   </string-array>
   <string-array name="app_ops_labels">
     <item msgid="6602854600289714121">"Konum"</item>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 21a4e04..1d2ba38 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3074,6 +3074,10 @@
     <string name="keep_screen_on">Stay awake</string>
     <!-- setting Checkbox summary whether to keep the screen on when plugged in  -->
     <string name="keep_screen_on_summary">Screen will never sleep while charging</string>
+    <!-- Setting Checkbox title whether to enable bluetooth HCI snoop log -->
+    <string name="bt_hci_snoop_log">Enable Bluetooth HCI snoop log</string>
+    <!-- setting Checkbox summary whether to capture all bluetooth HCI packets in a file -->
+    <string name="bt_hci_snoop_log_summary">Capture all bluetooth HCI packets in a file</string>
 
     <!-- Runtime selection title, used for debug purposes only. [CHAR LIMIT=25] -->
     <string name="select_runtime_title">Select runtime </string>
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index fa447f2..e2328d3 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -28,7 +28,7 @@
             android:title="@string/accessibility_system_title">
 
         <PreferenceScreen
-            android:fragment="com.android.settings.AccessibilitySettings$ToggleScreenMagnificationPreferenceFragment"
+            android:fragment="com.android.settings.accessibility.ToggleScreenMagnificationPreferenceFragment"
             android:key="screen_magnification_preference_screen"
             android:title="@string/accessibility_screen_magnification_title"/>
 
@@ -53,7 +53,7 @@
                 android:persistent="false"/>
 
         <PreferenceScreen
-                android:fragment="com.android.settings.AccessibilitySettings$ToggleGlobalGesturePreferenceFragment"
+                android:fragment="com.android.settings.accessibility.ToggleGlobalGesturePreferenceFragment"
                 android:key="enable_global_gesture_preference_screen"
                 android:title="@string/accessibility_global_gesture_preference_title"/>
 
diff --git a/res/xml/development_prefs.xml b/res/xml/development_prefs.xml
index eddc411..db003d3 100644
--- a/res/xml/development_prefs.xml
+++ b/res/xml/development_prefs.xml
@@ -56,6 +56,11 @@
         android:title="@string/enforce_read_external_title"
         android:summary="@string/enforce_read_external_summary" />
 
+    <CheckBoxPreference
+        android:key="bt_hci_snoop_log"
+        android:title="@string/bt_hci_snoop_log"
+        android:summary="@string/bt_hci_snoop_log_summary"/>
+
     <PreferenceCategory android:key="debug_debugging_category"
             android:title="@string/debug_debugging_category">
 
diff --git a/res/xml/settings_headers.xml b/res/xml/settings_headers.xml
index b00ecf5..5d3a39f 100644
--- a/res/xml/settings_headers.xml
+++ b/res/xml/settings_headers.xml
@@ -178,7 +178,7 @@
     <!-- Accessibility feedback -->
     <header
         android:id="@+id/accessibility_settings"
-        android:fragment="com.android.settings.AccessibilitySettings"
+        android:fragment="com.android.settings.accessibility.AccessibilitySettings"
         android:icon="@drawable/ic_settings_accessibility"
         android:title="@string/accessibility_settings" />
 
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/DevelopmentSettings.java b/src/com/android/settings/DevelopmentSettings.java
index a7ad1f7..8ed9a7e 100644
--- a/src/com/android/settings/DevelopmentSettings.java
+++ b/src/com/android/settings/DevelopmentSettings.java
@@ -27,6 +27,7 @@
 import android.app.DialogFragment;
 import android.app.admin.DevicePolicyManager;
 import android.app.backup.IBackupManager;
+import android.bluetooth.BluetoothAdapter;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -97,6 +98,7 @@
     private static final String CLEAR_ADB_KEYS = "clear_adb_keys";
     private static final String ENABLE_TERMINAL = "enable_terminal";
     private static final String KEEP_SCREEN_ON = "keep_screen_on";
+    private static final String BT_HCI_SNOOP_LOG = "bt_hci_snoop_log";
     private static final String SELECT_RUNTIME_KEY = "select_runtime";
     private static final String SELECT_RUNTIME_PROPERTY = "persist.sys.dalvik.vm.lib";
     private static final String ALLOW_MOCK_LOCATION = "allow_mock_location";
@@ -167,6 +169,7 @@
     private Preference mBugreport;
     private CheckBoxPreference mBugreportInPower;
     private CheckBoxPreference mKeepScreenOn;
+    private CheckBoxPreference mBtHciSnoopLog;
     private CheckBoxPreference mEnforceReadExternal;
     private CheckBoxPreference mAllowMockLocation;
     private PreferenceScreen mPassword;
@@ -252,6 +255,7 @@
         mBugreport = findPreference(BUGREPORT);
         mBugreportInPower = findAndInitCheckboxPref(BUGREPORT_IN_POWER_KEY);
         mKeepScreenOn = findAndInitCheckboxPref(KEEP_SCREEN_ON);
+        mBtHciSnoopLog = findAndInitCheckboxPref(BT_HCI_SNOOP_LOG);
         mEnforceReadExternal = findAndInitCheckboxPref(ENFORCE_READ_EXTERNAL);
         mAllowMockLocation = findAndInitCheckboxPref(ALLOW_MOCK_LOCATION);
         mPassword = (PreferenceScreen) findPreference(LOCAL_BACKUP_PASSWORD);
@@ -477,6 +481,8 @@
                 Settings.Secure.BUGREPORT_IN_POWER_MENU, 0) != 0);
         updateCheckBox(mKeepScreenOn, Settings.Global.getInt(cr,
                 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0) != 0);
+        updateCheckBox(mBtHciSnoopLog, Settings.Secure.getInt(cr,
+                Settings.Secure.BLUETOOTH_HCI_LOG, 0) != 0);
         updateCheckBox(mEnforceReadExternal, isPermissionEnforced(READ_EXTERNAL_STORAGE));
         updateCheckBox(mAllowMockLocation, Settings.Secure.getInt(cr,
                 Settings.Secure.ALLOW_MOCK_LOCATION, 0) != 0);
@@ -607,6 +613,14 @@
         }
     }
 
+    private void writeBtHciSnoopLogOptions() {
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        adapter.configHciSnoopLog(mBtHciSnoopLog.isChecked());
+        Settings.Secure.putInt(getActivity().getContentResolver(),
+                Settings.Secure.BLUETOOTH_HCI_LOG,
+                mBtHciSnoopLog.isChecked() ? 1 : 0);
+    }
+
     private void writeDebuggerOptions() {
         try {
             ActivityManagerNative.getDefault().setDebugApp(
@@ -1191,6 +1205,8 @@
                     Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
                     mKeepScreenOn.isChecked() ? 
                     (BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB) : 0);
+        } else if (preference == mBtHciSnoopLog) {
+            writeBtHciSnoopLogOptions();
         } else if (preference == mEnforceReadExternal) {
             if (mEnforceReadExternal.isChecked()) {
                 ConfirmEnforceFragment.show(this);
diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java
index 495f3fd..3777a8e 100644
--- a/src/com/android/settings/MasterClear.java
+++ b/src/com/android/settings/MasterClear.java
@@ -29,6 +29,7 @@
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.SystemProperties;
+import android.os.UserManager;
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
 import android.util.Log;
@@ -54,6 +55,7 @@
     private static final String TAG = "MasterClear";
 
     private static final int KEYGUARD_REQUEST = 55;
+    private static final int PIN_REQUEST = 56;
 
     static final String ERASE_EXTERNAL_EXTRA = "erase_sd";
 
@@ -61,6 +63,7 @@
     private Button mInitiateButton;
     private View mExternalStorageContainer;
     private CheckBox mExternalStorage;
+    private boolean mPinConfirmed;
 
     /**
      * Keyguard validation is run using the standard {@link ConfirmLockPattern}
@@ -76,11 +79,25 @@
                         res.getText(R.string.master_clear_gesture_explanation));
     }
 
+    private boolean runRestrictionsChallenge() {
+        if (UserManager.get(getActivity()).hasRestrictionsPin()) {
+            startActivityForResult(
+                    new Intent(Intent.ACTION_RESTRICTIONS_PIN_CHALLENGE), PIN_REQUEST);
+            return true;
+        }
+        return false;
+    }
+
     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
 
-        if (requestCode != KEYGUARD_REQUEST) {
+        if (requestCode == PIN_REQUEST) {
+            if (resultCode == Activity.RESULT_OK) {
+                mPinConfirmed = true;
+            }
+            return;
+        } else if (requestCode != KEYGUARD_REQUEST) {
             return;
         }
 
@@ -109,6 +126,10 @@
     private final Button.OnClickListener mInitiateListener = new Button.OnClickListener() {
 
         public void onClick(View v) {
+            mPinConfirmed = false;
+            if (runRestrictionsChallenge()) {
+                return;
+            }
             if (!runKeyguardConfirmation(KEYGUARD_REQUEST)) {
                 showFinalConfirmation();
             }
@@ -239,4 +260,17 @@
         establishInitialState();
         return mContentView;
     }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        // If this is the second step after restrictions pin challenge
+        if (mPinConfirmed) {
+            mPinConfirmed = false;
+            if (!runKeyguardConfirmation(KEYGUARD_REQUEST)) {
+                showFinalConfirmation();
+            }
+        }
+    }
 }
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 24ffc50..e90b1cd 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;
@@ -488,7 +488,8 @@
                     target.remove(i);
                 }
             } else if (id == R.id.restriction_settings) {
-                if (um.isLinkedUser()) {
+                if (um.isLinkedUser()
+                        || um.hasUserRestriction(UserManager.DISALLOW_APP_RESTRICTIONS)) {
                     target.remove(i);
                 }
             }
diff --git a/src/com/android/settings/UserDictionarySettings.java b/src/com/android/settings/UserDictionarySettings.java
index b156105..9f6df50 100644
--- a/src/com/android/settings/UserDictionarySettings.java
+++ b/src/com/android/settings/UserDictionarySettings.java
@@ -38,6 +38,7 @@
 import android.widget.TextView;
 
 import com.android.settings.inputmethod.UserDictionaryAddWordContents;
+import com.android.settings.inputmethod.UserDictionarySettingsUtils;
 
 import java.util.Locale;
 
@@ -115,7 +116,9 @@
         listView.setEmptyView(emptyView);
 
         setHasOptionsMenu(true);
-
+        // Show the language as a subtitle of the action bar
+        getActivity().getActionBar().setSubtitle(
+                UserDictionarySettingsUtils.getLocaleDisplayName(getActivity(), mLocale));
     }
 
     private Cursor createCursor(final String locale) {
diff --git a/src/com/android/settings/WirelessSettings.java b/src/com/android/settings/WirelessSettings.java
index a3684be..1f29927 100644
--- a/src/com/android/settings/WirelessSettings.java
+++ b/src/com/android/settings/WirelessSettings.java
@@ -45,7 +45,7 @@
 import com.android.settings.NsdEnabler;
 
 public class WirelessSettings extends SettingsPreferenceFragment {
-    private static final String TAG = "WirelessSettiings";
+    private static final String TAG = "WirelessSettings";
 
     private static final String KEY_TOGGLE_AIRPLANE = "toggle_airplane";
     private static final String KEY_TOGGLE_NFC = "toggle_nfc";
@@ -106,7 +106,7 @@
         NetworkInfo ni = mCm.getActiveNetworkInfo();
         if (mTm.hasIccCard() && (ni != null)) {
             // Get provisioning URL
-            String url = getProvisioningUrl();
+            String url = mCm.getMobileProvisioningUrl();
             if (!TextUtils.isEmpty(url)) {
                 // Send user to provisioning webpage
                 Intent intent = new Intent(Intent.ACTION_VIEW);
@@ -145,26 +145,6 @@
         }
     }
 
-    private String getProvisioningUrl() {
-        String url = getActivity().getResources()
-                .getString(com.android.internal.R.string.mobile_provisioning_url);
-        log("getProvisioningUrl: mobile_provisioning_url=" + url);
-
-        // populate the iccid, imei and phone number in the provisioning url.
-        if (!TextUtils.isEmpty(url)) {
-            String phoneNumber = mTm.getLine1Number();
-            if (TextUtils.isEmpty(phoneNumber)) {
-                phoneNumber = "0000000000";
-            }
-            url = String.format(url,
-                    mTm.getSimSerialNumber() /* ICCID */,
-                    mTm.getDeviceId() /* IMEI */,
-                    phoneNumber /* Phone number */);
-        }
-
-        return url;
-    }
-
     @Override
     public Dialog onCreateDialog(int dialogId) {
         log("onCreateDialog: dialogId=" + dialogId);
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);
+    }
+}
diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
index 4658955..45b1182 100644
--- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
+++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
@@ -20,10 +20,12 @@
 import com.android.settings.Settings.KeyboardLayoutPickerActivity;
 import com.android.settings.Settings.SpellCheckersSettingsActivity;
 import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.UserDictionarySettings;
 import com.android.settings.Utils;
 import com.android.settings.VoiceInputOutputSettings;
 
 import android.app.Activity;
+import android.app.Fragment;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -38,6 +40,7 @@
 import android.preference.CheckBoxPreference;
 import android.preference.ListPreference;
 import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
 import android.preference.PreferenceCategory;
 import android.preference.PreferenceScreen;
 import android.provider.Settings;
@@ -200,7 +203,35 @@
             // not present or disabled. In this case we need to remove the preference.
             getPreferenceScreen().removePreference(userDictionaryPreference);
         } else {
-            userDictionaryPreference.setFragment(UserDictionaryList.class.getName());
+            userDictionaryPreference.setOnPreferenceClickListener(
+                    new OnPreferenceClickListener() {
+                        @Override
+                        public boolean onPreferenceClick(Preference arg0) {
+                            // Redirect to UserDictionarySettings if the user needs only one
+                            // language.
+                            final Bundle extras = new Bundle();
+                            final Class<? extends Fragment> targetFragment;
+                            if (localeSet.size() <= 1) {
+                                if (!localeSet.isEmpty()) {
+                                    // If the size of localeList is 0, we don't set the locale
+                                    // parameter in the extras. This will be interpreted by the
+                                    // UserDictionarySettings class as meaning
+                                    // "the current locale". Note that with the current code for
+                                    // UserDictionaryList#getUserDictionaryLocalesSet()
+                                    // the locale list always has at least one element, since it
+                                    // always includes the current locale explicitly.
+                                    // @see UserDictionaryList.getUserDictionaryLocalesSet().
+                                    extras.putString("locale", localeSet.first());
+                                }
+                                targetFragment = UserDictionarySettings.class;
+                            } else {
+                                targetFragment = UserDictionaryList.class;
+                            }
+                            startFragment(InputMethodAndLanguageSettings.this,
+                                    targetFragment.getCanonicalName(), -1, extras);
+                            return true;
+                        }
+                    });
         }
     }
 
diff --git a/src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java b/src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java
index 5efe117..d81703e 100644
--- a/src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java
+++ b/src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java
@@ -57,6 +57,8 @@
     private String mLocale;
     private final String mOldWord;
     private final String mOldShortcut;
+    private String mSavedWord;
+    private String mSavedShortcut;
 
     /* package */ UserDictionaryAddWordContents(final View view, final Bundle args) {
         mWordEditText = (EditText)view.findViewById(R.id.user_dictionary_add_word_text);
@@ -78,6 +80,16 @@
         updateLocale(args.getString(EXTRA_LOCALE));
     }
 
+    /* package */ UserDictionaryAddWordContents(final View view,
+            final UserDictionaryAddWordContents oldInstanceToBeEdited) {
+        mWordEditText = (EditText)view.findViewById(R.id.user_dictionary_add_word_text);
+        mShortcutEditText = (EditText)view.findViewById(R.id.user_dictionary_add_shortcut);
+        mMode = MODE_EDIT;
+        mOldWord = oldInstanceToBeEdited.mSavedWord;
+        mOldShortcut = oldInstanceToBeEdited.mSavedShortcut;
+        updateLocale(mLocale);
+    }
+
     // locale may be null, this means default locale
     // It may also be the empty string, which means "all locales"
     /* package */ void updateLocale(final String locale) {
@@ -128,6 +140,8 @@
             // If the word is somehow empty, don't insert it.
             return UserDictionaryAddWordActivity.CODE_CANCEL;
         }
+        mSavedWord = newWord;
+        mSavedShortcut = newShortcut;
         // If there is no shortcut, and the word already exists in the database, then we
         // should not insert, because either A. the word exists with no shortcut, in which
         // case the exact same thing we want to insert is already there, or B. the word
@@ -239,4 +253,8 @@
         localesList.add(new LocaleRenderer(activity, null)); // meaning: select another locale
         return localesList;
     }
+
+    public String getCurrentUserDictionaryLocale() {
+        return mLocale;
+    }
 }
diff --git a/src/com/android/settings/inputmethod/UserDictionaryAddWordFragment.java b/src/com/android/settings/inputmethod/UserDictionaryAddWordFragment.java
index e33333b..8f7029a 100644
--- a/src/com/android/settings/inputmethod/UserDictionaryAddWordFragment.java
+++ b/src/com/android/settings/inputmethod/UserDictionaryAddWordFragment.java
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.android.settings.inputmethod;
 
 import android.app.Fragment;
@@ -51,23 +52,39 @@
     private boolean mIsDeleting = false;
 
     @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
+    public void onActivityCreated(final Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
         setHasOptionsMenu(true);
+        getActivity().getActionBar().setTitle(R.string.user_dict_settings_title);
+        // Keep the instance so that we remember mContents when configuration changes (eg rotation)
+        setRetainInstance(true);
     }
 
     @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
+    public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
+            final Bundle savedState) {
         mRootView = inflater.inflate(R.layout.user_dictionary_add_word_fullscreen, null);
         mIsDeleting = false;
+        // If we have a non-null mContents object, it's the old value before a configuration
+        // change (eg rotation) so we need to use its values. Otherwise, read from the arguments.
         if (null == mContents) {
             mContents = new UserDictionaryAddWordContents(mRootView, getArguments());
+        } else {
+            // We create a new mContents object to account for the new situation : a word has
+            // been added to the user dictionary when we started rotating, and we are now editing
+            // it. That means in particular if the word undergoes any change, the old version should
+            // be updated, so the mContents object needs to switch to EDIT mode if it was in
+            // INSERT mode.
+            mContents = new UserDictionaryAddWordContents(mRootView,
+                    mContents /* oldInstanceToBeEdited */);
         }
+        getActivity().getActionBar().setSubtitle(UserDictionarySettingsUtils.getLocaleDisplayName(
+                getActivity(), mContents.getCurrentUserDictionaryLocale()));
         return mRootView;
     }
 
     @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+    public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
         MenuItem actionItem = menu.add(0, OPTIONS_MENU_DELETE, 0, R.string.delete)
                 .setIcon(android.R.drawable.ic_menu_delete);
         actionItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM |
@@ -102,13 +119,9 @@
     private void updateSpinner() {
         final ArrayList<LocaleRenderer> localesList = mContents.getLocalesList(getActivity());
 
-        final Spinner localeSpinner =
-                (Spinner)mRootView.findViewById(R.id.user_dictionary_add_locale);
         final ArrayAdapter<LocaleRenderer> adapter = new ArrayAdapter<LocaleRenderer>(getActivity(),
                 android.R.layout.simple_spinner_item, localesList);
         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-        localeSpinner.setAdapter(adapter);
-        localeSpinner.setOnItemSelectedListener(this);
     }
 
     @Override
diff --git a/src/com/android/settings/inputmethod/UserDictionaryList.java b/src/com/android/settings/inputmethod/UserDictionaryList.java
index f9e4379..24acb4a 100644
--- a/src/com/android/settings/inputmethod/UserDictionaryList.java
+++ b/src/com/android/settings/inputmethod/UserDictionaryList.java
@@ -26,18 +26,13 @@
 import android.database.Cursor;
 import android.os.Bundle;
 import android.preference.Preference;
-import android.preference.PreferenceActivity;
 import android.preference.PreferenceGroup;
 import android.provider.UserDictionary;
 import android.text.TextUtils;
-import android.util.Log;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.view.inputmethod.InputMethodSubtype;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.TreeSet;
@@ -129,9 +124,8 @@
     /**
      * Creates the entries that allow the user to go into the user dictionary for each locale.
      * @param userDictGroup The group to put the settings in.
-     * @return the shown language set
      */
-    protected TreeSet<String> createUserDictSettingsAndReturnSet(PreferenceGroup userDictGroup) {
+    protected void createUserDictSettings(PreferenceGroup userDictGroup) {
         final Activity activity = getActivity();
         userDictGroup.removeAll();
         final TreeSet<String> localeSet =
@@ -141,6 +135,11 @@
             // in the list.
             localeSet.add(mLocale);
         }
+        if (localeSet.size() > 1) {
+            // Have an "All languages" entry in the languages list if there are two or more active
+            // languages
+            localeSet.add("");
+        }
 
         if (localeSet.isEmpty()) {
             userDictGroup.addPreference(createUserDictionaryPreference(null, activity));
@@ -149,7 +148,6 @@
                 userDictGroup.addPreference(createUserDictionaryPreference(locale, activity));
             }
         }
-        return localeSet;
     }
 
     /**
@@ -178,25 +176,6 @@
     @Override
     public void onResume() {
         super.onResume();
-        final TreeSet<String> localeSet = createUserDictSettingsAndReturnSet(getPreferenceScreen());
-        if (localeSet.size() <= 1) {
-            // Redirect to UserDictionarySettings if the user needs only one language.
-            final Bundle extras = new Bundle();
-            if (!localeSet.isEmpty()) {
-                // If the size of localeList is 0, we don't set the locale parameter in the
-                // extras. This will be interpreted by the UserDictionarySettings class as
-                // meaning "the current locale".
-                // Note that with the current code for
-                // UserDictionaryList#getUserDictionaryLocalesSet()
-                // the locale list always has at least one element, since it always includes
-                // the current locale explicitly.
-                // @see UserDictionaryList.getUserDictionaryLocalesSet().
-                extras.putString("locale", localeSet.first());
-            }
-            startFragment(this,
-                    com.android.settings.UserDictionarySettings.class.getCanonicalName(), -1,
-                    extras);
-            finish();
-        }
+        createUserDictSettings(getPreferenceScreen());
     }
 }
diff --git a/src/com/android/settings/inputmethod/UserDictionarySettingsUtils.java b/src/com/android/settings/inputmethod/UserDictionarySettingsUtils.java
new file mode 100644
index 0000000..2238b4b
--- /dev/null
+++ b/src/com/android/settings/inputmethod/UserDictionarySettingsUtils.java
@@ -0,0 +1,34 @@
+/*
+ * 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.inputmethod;
+
+import com.android.settings.Utils;
+
+import android.content.Context;
+
+import java.util.Locale;
+
+/**
+ * Utilities of the user dictionary settings
+ */
+public class UserDictionarySettingsUtils {
+    public static String getLocaleDisplayName(Context context, String localeStr) {
+        final Locale locale = Utils.createLocaleFromString(localeStr);
+        final Locale systemLocale = context.getResources().getConfiguration().locale;
+        return locale.getDisplayName(systemLocale);
+    }
+}
diff --git a/src/com/android/settings/users/AppRestrictionsFragment.java b/src/com/android/settings/users/AppRestrictionsFragment.java
index 2f99d11..0e15cec 100644
--- a/src/com/android/settings/users/AppRestrictionsFragment.java
+++ b/src/com/android/settings/users/AppRestrictionsFragment.java
@@ -57,6 +57,7 @@
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.view.ViewGroup;
+import android.widget.CheckBox;
 import android.widget.CompoundButton;
 import android.widget.CompoundButton.OnCheckedChangeListener;
 import android.widget.Switch;
@@ -85,7 +86,9 @@
 
     protected PackageManager mPackageManager;
     protected UserManager mUserManager;
+    protected IPackageManager mIPm;
     protected UserHandle mUser;
+    private PackageInfo mSysPackageInfo;
 
     private PreferenceGroup mAppList;
 
@@ -129,6 +132,13 @@
         }
     };
 
+    private BroadcastReceiver mPackageObserver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            onPackageChanged(intent);
+        }
+    };
+
     static class SelectableAppInfo {
         String packageName;
         CharSequence appName;
@@ -147,9 +157,9 @@
         private boolean hasSettings;
         private OnClickListener listener;
         private ArrayList<RestrictionEntry> restrictions;
-        boolean panelOpen;
+        private boolean mPanelOpen;
         private boolean immutable;
-        List<Preference> childPreferences = new ArrayList<Preference>();
+        private List<Preference> mChildren = new ArrayList<Preference>();
         private final ColorFilter grayscaleFilter;
 
         AppRestrictionsPreference(Context context, OnClickListener listener) {
@@ -204,6 +214,14 @@
             return restrictions;
         }
 
+        boolean isPanelOpen() {
+            return mPanelOpen;
+        }
+
+        List<Preference> getChildren() {
+            return mChildren;
+        }
+
         @Override
         protected void onBindView(View view) {
             super.onBindView(view);
@@ -222,13 +240,13 @@
             ViewGroup widget = (ViewGroup) view.findViewById(android.R.id.widget_frame);
             widget.setEnabled(!isImmutable());
             if (widget.getChildCount() > 0) {
-                final Switch switchView = (Switch) widget.getChildAt(0);
-                switchView.setEnabled(!isImmutable());
-                switchView.setTag(this);
-                switchView.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+                final Switch toggle = (Switch) widget.getChildAt(0);
+                toggle.setEnabled(!isImmutable());
+                toggle.setTag(this);
+                toggle.setOnCheckedChangeListener(new OnCheckedChangeListener() {
                     @Override
                     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-                        listener.onClick(switchView);
+                        listener.onClick(toggle);
                     }
                 });
             }
@@ -253,9 +271,15 @@
         }
 
         mPackageManager = getActivity().getPackageManager();
+        mIPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
         mUserManager = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
         mRestrictedProfile = mUserManager.getUserInfo(mUser.getIdentifier()).isRestricted();
-
+        try {
+            mSysPackageInfo = mPackageManager.getPackageInfo("android",
+                PackageManager.GET_SIGNATURES);
+        } catch (NameNotFoundException nnfe) {
+            // ?
+        }
         addPreferencesFromResource(R.xml.app_restrictions);
         mAppList = getAppPreferenceGroup();
     }
@@ -266,21 +290,30 @@
         outState.putInt(EXTRA_USER_ID, mUser.getIdentifier());
     }
 
+    @Override
     public void onResume() {
         super.onResume();
 
         getActivity().registerReceiver(mUserBackgrounding,
                 new IntentFilter(Intent.ACTION_USER_BACKGROUND));
+        IntentFilter packageFilter = new IntentFilter();
+        packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        packageFilter.addDataScheme("package");
+        getActivity().registerReceiver(mPackageObserver, packageFilter);
+
         mAppListChanged = false;
         if (mAppLoadingTask == null || mAppLoadingTask.getStatus() == AsyncTask.Status.FINISHED) {
             mAppLoadingTask = new AppLoadingTask().execute((Void[]) null);
         }
     }
 
+    @Override
     public void onPause() {
         super.onPause();
         mNewUser = false;
         getActivity().unregisterReceiver(mUserBackgrounding);
+        getActivity().unregisterReceiver(mPackageObserver);
         if (mAppListChanged) {
             new Thread() {
                 public void run() {
@@ -290,6 +323,20 @@
         }
     }
 
+    private void onPackageChanged(Intent intent) {
+        String action = intent.getAction();
+        String packageName = intent.getData().getSchemeSpecificPart();
+        // Package added, check if the preference needs to be enabled
+        AppRestrictionsPreference pref = (AppRestrictionsPreference)
+                findPreference(getKeyForPackage(packageName));
+        if (pref == null) return;
+
+        if ((Intent.ACTION_PACKAGE_ADDED.equals(action) && pref.isChecked())
+                || (Intent.ACTION_PACKAGE_REMOVED.equals(action) && !pref.isChecked())) {
+            pref.setEnabled(true);
+        }
+    }
+
     protected PreferenceGroup getAppPreferenceGroup() {
         return getPreferenceScreen();
     }
@@ -306,8 +353,6 @@
     }
 
     private void applyUserAppsStates() {
-        IPackageManager ipm = IPackageManager.Stub.asInterface(
-                ServiceManager.getService("package"));
         final int userId = mUser.getIdentifier();
         if (!mUserManager.getUserInfo(userId).isRestricted() && userId != UserHandle.myUserId()) {
             Log.e(TAG, "Cannot apply application restrictions on another user!");
@@ -315,47 +360,64 @@
         }
         for (Map.Entry<String,Boolean> entry : mSelectedPackages.entrySet()) {
             String packageName = entry.getKey();
-            if (entry.getValue()) {
-                // Enable selected apps
-                try {
-                    ApplicationInfo info = ipm.getApplicationInfo(packageName,
-                            PackageManager.GET_UNINSTALLED_PACKAGES, userId);
-                    if (info == null || info.enabled == false) {
-                        ipm.installExistingPackageAsUser(packageName, mUser.getIdentifier());
-                        if (DEBUG) {
-                            Log.d(TAG, "Installing " + packageName);
-                        }
+            boolean enabled = entry.getValue();
+            applyUserAppState(packageName, enabled);
+        }
+    }
+
+    private void applyUserAppState(String packageName, boolean enabled) {
+        final int userId = mUser.getIdentifier();
+        if (enabled) {
+            // Enable selected apps
+            try {
+                ApplicationInfo info = mIPm.getApplicationInfo(packageName,
+                        PackageManager.GET_UNINSTALLED_PACKAGES, userId);
+                if (info == null || info.enabled == false
+                        || (info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
+                    mIPm.installExistingPackageAsUser(packageName, mUser.getIdentifier());
+                    if (DEBUG) {
+                        Log.d(TAG, "Installing " + packageName);
                     }
-                    if (info != null && (info.flags&ApplicationInfo.FLAG_BLOCKED) != 0
-                            && (info.flags&ApplicationInfo.FLAG_INSTALLED) != 0) {
-                        ipm.setApplicationBlockedSettingAsUser(packageName, false, userId);
-                        if (DEBUG) {
-                            Log.d(TAG, "Unblocking " + packageName);
-                        }
-                    }
-                } catch (RemoteException re) {
                 }
-            } else {
-                // Blacklist all other apps, system or downloaded
-                try {
-                    ApplicationInfo info = ipm.getApplicationInfo(packageName, 0, userId);
-                    if (info != null) {
-                        if (mRestrictedProfile) {
-                            ipm.deletePackageAsUser(entry.getKey(), null, mUser.getIdentifier(),
-                                    PackageManager.DELETE_SYSTEM_APP);
-                            if (DEBUG) {
-                                Log.d(TAG, "Uninstalling " + packageName);
-                            }
-                        } else {
-                            ipm.setApplicationBlockedSettingAsUser(packageName, true, userId);
-                            if (DEBUG) {
-                                Log.d(TAG, "Blocking " + packageName);
-                            }
-                        }
+                if (info != null && (info.flags&ApplicationInfo.FLAG_BLOCKED) != 0
+                        && (info.flags&ApplicationInfo.FLAG_INSTALLED) != 0) {
+                    disableUiForPackage(packageName);
+                    mIPm.setApplicationBlockedSettingAsUser(packageName, false, userId);
+                    if (DEBUG) {
+                        Log.d(TAG, "Unblocking " + packageName);
                     }
-                } catch (RemoteException re) {
                 }
+            } catch (RemoteException re) {
             }
+        } else {
+            // Blacklist all other apps, system or downloaded
+            try {
+                ApplicationInfo info = mIPm.getApplicationInfo(packageName, 0, userId);
+                if (info != null) {
+                    if (mRestrictedProfile) {
+                        mIPm.deletePackageAsUser(packageName, null, mUser.getIdentifier(),
+                                PackageManager.DELETE_SYSTEM_APP);
+                        if (DEBUG) {
+                            Log.d(TAG, "Uninstalling " + packageName);
+                        }
+                    } else {
+                        disableUiForPackage(packageName);
+                        mIPm.setApplicationBlockedSettingAsUser(packageName, true, userId);
+                        if (DEBUG) {
+                            Log.d(TAG, "Blocking " + packageName);
+                        }
+                    }
+                }
+            } catch (RemoteException re) {
+            }
+        }
+    }
+
+    private void disableUiForPackage(String packageName) {
+        AppRestrictionsPreference pref = (AppRestrictionsPreference) findPreference(
+                getKeyForPackage(packageName));
+        if (pref != null) {
+            pref.setEnabled(false);
         }
     }
 
@@ -457,7 +519,7 @@
         final Context context = getActivity();
         if (context == null) return;
         final PackageManager pm = mPackageManager;
-        IPackageManager ipm = AppGlobals.getPackageManager();
+        final IPackageManager ipm = mIPm;
 
         final HashSet<String> excludePackages = new HashSet<String>();
         addSystemImes(excludePackages);
@@ -552,6 +614,11 @@
         }
     }
 
+    private boolean isPlatformSigned(PackageInfo pi) {
+        return (pi != null && pi.signatures != null &&
+                    mSysPackageInfo.signatures[0].equals(pi.signatures[0]));
+    }
+
     private boolean isAppEnabledForUser(PackageInfo pi) {
         if (pi == null) return false;
         final int flags = pi.applicationInfo.flags;
@@ -564,7 +631,8 @@
         final Context context = getActivity();
         if (context == null) return;
         final PackageManager pm = mPackageManager;
-        IPackageManager ipm = AppGlobals.getPackageManager();
+        final IPackageManager ipm = mIPm;
+
         mAppList.removeAll();
         Intent restrictionsIntent = new Intent(Intent.ACTION_GET_RESTRICTION_ENTRIES);
         final List<ResolveInfo> receivers = pm.queryBroadcastReceivers(restrictionsIntent, 0);
@@ -583,7 +651,7 @@
                     p.setSummary(context.getString(R.string.user_restrictions_controlled_by,
                             app.masterEntry.activityName));
                 }
-                p.setKey(PKG_PREFIX + packageName);
+                p.setKey(getKeyForPackage(packageName));
                 p.setSettingsEnabled(hasSettings || isSettingsApp);
                 p.setPersistent(false);
                 p.setOnPreferenceChangeListener(this);
@@ -591,10 +659,11 @@
                 PackageInfo pi = null;
                 try {
                     pi = ipm.getPackageInfo(packageName,
-                            PackageManager.GET_UNINSTALLED_PACKAGES, mUser.getIdentifier());
+                            PackageManager.GET_UNINSTALLED_PACKAGES
+                            | PackageManager.GET_SIGNATURES, mUser.getIdentifier());
                 } catch (RemoteException e) {
                 }
-                if (pi != null && pi.requiredForAllUsers) {
+                if (pi != null && (pi.requiredForAllUsers || isPlatformSigned(pi))) {
                     p.setChecked(true);
                     p.setImmutable(true);
                     // If the app is required and has no restrictions, skip showing it
@@ -602,10 +671,10 @@
                     // Get and populate the defaults, since the user is not going to be
                     // able to toggle this app ON (it's ON by default and immutable).
                     // Only do this for restricted profiles, not single-user restrictions
-                    if (hasSettings && mRestrictedProfile) {
+                    if (hasSettings) {
                         requestRestrictionsForApp(packageName, p);
                     }
-                } else if (!mNewUser && isAppEnabledForUser(pi)) { /*appInfoListHasPackage(mUserApps, packageName)*/
+                } else if (!mNewUser && isAppEnabledForUser(pi)) {
                     p.setChecked(true);
                 }
                 if (mRestrictedProfile
@@ -640,6 +709,10 @@
         }
     }
 
+    private String getKeyForPackage(String packageName) {
+        return PKG_PREFIX + packageName;
+    }
+
     private class AppLabelComparator implements Comparator<SelectableAppInfo> {
 
         @Override
@@ -686,6 +759,10 @@
                     requestRestrictionsForApp(packageName, pref);
                 }
                 mAppListChanged = true;
+                // If it's not a restricted profile, apply the changes immediately
+                if (!mRestrictedProfile) {
+                    applyUserAppState(packageName, pref.isChecked());
+                }
                 updateAllEntries(pref.getKey(), pref.isChecked());
             }
         }
@@ -742,11 +819,11 @@
 
     private void toggleAppPanel(AppRestrictionsPreference preference) {
         if (preference.getKey().startsWith(PKG_PREFIX)) {
-            if (preference.panelOpen) {
-                for (Preference p : preference.childPreferences) {
+            if (preference.mPanelOpen) {
+                for (Preference p : preference.mChildren) {
                     mAppList.removePreference(p);
                 }
-                preference.childPreferences.clear();
+                preference.mChildren.clear();
             } else {
                 String packageName = preference.getKey().substring(PKG_PREFIX.length());
                 if (packageName.equals(getActivity().getPackageName())) {
@@ -758,7 +835,7 @@
                     requestRestrictionsForApp(packageName, preference);
                 }
             }
-            preference.panelOpen = !preference.panelOpen;
+            preference.mPanelOpen = !preference.mPanelOpen;
         }
     }
 
@@ -795,8 +872,10 @@
             Intent restrictionsIntent = (Intent) results.getParcelable(CUSTOM_RESTRICTIONS_INTENT);
             if (restrictions != null && restrictionsIntent == null) {
                 onRestrictionsReceived(preference, packageName, restrictions);
-                mUserManager.setApplicationRestrictions(packageName,
-                        RestrictionUtils.restrictionsToBundle(restrictions), mUser);
+                if (mRestrictedProfile) {
+                    mUserManager.setApplicationRestrictions(packageName,
+                            RestrictionUtils.restrictionsToBundle(restrictions), mUser);
+                }
             } else if (restrictionsIntent != null) {
                 final Intent customIntent = restrictionsIntent;
                 if (restrictions != null) {
@@ -817,7 +896,7 @@
                 });
                 p.setPersistent(false);
                 p.setOrder(preference.getOrder() + 1);
-                preference.childPreferences.add(p);
+                preference.mChildren.add(p);
                 mAppList.addPreference(p);
                 preference.setRestrictions(restrictions);
             }
@@ -876,7 +955,7 @@
                         + entry.getKey());
                 mAppList.addPreference(p);
                 p.setOnPreferenceChangeListener(AppRestrictionsFragment.this);
-                preference.childPreferences.add(p);
+                preference.mChildren.add(p);
                 count++;
             }
         }
@@ -946,10 +1025,13 @@
         if (preference.getKey().startsWith(PKG_PREFIX)) {
             AppRestrictionsPreference arp = (AppRestrictionsPreference) preference;
             if (!arp.isImmutable()) {
-                arp.setChecked(!arp.isChecked());
-                mSelectedPackages.put(arp.getKey().substring(PKG_PREFIX.length()), arp.isChecked());
-                updateAllEntries(arp.getKey(), arp.isChecked());
+                final String packageName = arp.getKey().substring(PKG_PREFIX.length());
+                final boolean newEnabledState = !arp.isChecked();
+                arp.setChecked(newEnabledState);
+                mSelectedPackages.put(packageName, newEnabledState);
+                updateAllEntries(arp.getKey(), newEnabledState);
                 mAppListChanged = true;
+                applyUserAppState(packageName, newEnabledState);
             }
             return true;
         }
diff --git a/src/com/android/settings/users/RestrictionSettings.java b/src/com/android/settings/users/RestrictionSettings.java
index 789cee4..91b8bd3 100644
--- a/src/com/android/settings/users/RestrictionSettings.java
+++ b/src/com/android/settings/users/RestrictionSettings.java
@@ -41,25 +41,36 @@
     private static final int MENU_RESET = Menu.FIRST + 1;
     private static final int MENU_CHANGE_PIN = Menu.FIRST + 2;
 
+    private static final String KEY_CHALLENGE_SUCCEEDED = "chsc";
     private static final String KEY_CHALLENGE_REQUESTED = "chrq";
 
     private boolean mChallengeSucceeded;
     private boolean mChallengeRequested;
+    private boolean mDisableSelf;
 
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
-
+        if (UserManager.get(getActivity()).hasUserRestriction(
+                UserManager.DISALLOW_APP_RESTRICTIONS)) {
+            mDisableSelf = true;
+            return;
+        }
         init(icicle);
-        mChallengeSucceeded = false;
-        mChallengeRequested = icicle != null
-                ? icicle.getBoolean(KEY_CHALLENGE_REQUESTED, false)
-                : false;
+        if (icicle != null) {
+            mChallengeSucceeded = icicle.getBoolean(KEY_CHALLENGE_SUCCEEDED, false);
+            mChallengeRequested = icicle.getBoolean(KEY_CHALLENGE_REQUESTED, false);
+        }
         setHasOptionsMenu(true);
     }
 
     public void onResume() {
         super.onResume();
+        if (!mDisableSelf) {
+            ensurePin();
+        }
+    }
 
+    private void ensurePin() {
         if (!mChallengeSucceeded) {
             getListView().setEnabled(false);
             final UserManager um = UserManager.get(getActivity());
@@ -81,24 +92,13 @@
 
     private void resetAndRemovePin() {
         final UserManager um = UserManager.get(getActivity());
-        final PackageManager pm = getActivity().getPackageManager();
-        List<ApplicationInfo> installedApps = pm.getInstalledApplications(
-                PackageManager.GET_UNINSTALLED_PACKAGES);
-        UserHandle user = android.os.Process.myUserHandle();
-        for (ApplicationInfo info: installedApps) {
-            if ((info.flags & ApplicationInfo.FLAG_BLOCKED) != 0
-                    && (info.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
-                pm.setApplicationBlockedSettingAsUser(info.packageName, false, user);
-            }
-        }
-        um.changeRestrictionsPin(null);
+        um.removeRestrictions();
         clearSelectedApps();
         finishFragment();
     }
 
     private void changePin() {
         final UserManager um = UserManager.get(getActivity());
-        um.changeRestrictionsPin(null);
         Intent requestPin = new Intent("android.intent.action.RESTRICTIONS_PIN_CREATE");
         startActivityForResult(requestPin, REQUEST_PIN_CHALLENGE);
     }
@@ -120,14 +120,19 @@
 
     public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
+
         outState.putBoolean(KEY_CHALLENGE_REQUESTED, mChallengeRequested);
+        if (getActivity().isChangingConfigurations()) {
+            outState.putBoolean(KEY_CHALLENGE_SUCCEEDED, mChallengeSucceeded);
+        }
     }
 
     @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        menu.add(0, MENU_RESET, 0, R.string.restriction_menu_reset);
-        menu.add(0, MENU_CHANGE_PIN, 0, R.string.restriction_menu_change_pin);
-
+        if (!mDisableSelf) {
+            menu.add(0, MENU_RESET, 0, R.string.restriction_menu_reset);
+            menu.add(0, MENU_CHANGE_PIN, 0, R.string.restriction_menu_change_pin);
+        }
         super.onCreateOptionsMenu(menu, inflater);
     }