Merge "Don't read state twice ("on on"/"off off") in Settings Toggle preferences. Bug: 26967006" into nyc-dev
diff --git a/res/layout/battery_usage_graph.xml b/res/layout/battery_usage_graph.xml
new file mode 100644
index 0000000..ddf7d93
--- /dev/null
+++ b/res/layout/battery_usage_graph.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/charge"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceLarge"
+        android:textSize="36sp"
+        android:textColor="?android:attr/colorAccent" />
+
+    <TextView
+        android:id="@+id/estimation"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingBottom="8dp"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textColor="?android:attr/textColorSecondary" />
+
+    <com.android.settingslib.graph.UsageView
+        android:id="@+id/battery_usage"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        settings:sideLabels="@array/battery_labels"
+        android:colorAccent="?android:attr/colorAccent"
+        android:gravity="end"
+        settings:textColor="?android:attr/textColorSecondary" />
+
+</LinearLayout>
diff --git a/res/layout/screen_zoom_preview_3.xml b/res/layout/preference_widget_summary.xml
similarity index 72%
rename from res/layout/screen_zoom_preview_3.xml
rename to res/layout/preference_widget_summary.xml
index 6fc7fd0..aa4c76b 100644
--- a/res/layout/screen_zoom_preview_3.xml
+++ b/res/layout/preference_widget_summary.xml
@@ -14,7 +14,9 @@
      limitations under the License.
 -->
 
-<com.android.settings.display.AppGridView
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/widget_summary"
     android:layout_width="match_parent"
-    android:layout_height="match_parent" />
+    android:layout_height="wrap_content"
+    android:textAppearance="?android:attr/textAppearanceSmall"
+    android:textColor="?android:attr/textColorSecondary" />
diff --git a/res/layout/preview_seek_bar_view_pager.xml b/res/layout/preview_seek_bar_view_pager.xml
index ac315b8..4badca4 100644
--- a/res/layout/preview_seek_bar_view_pager.xml
+++ b/res/layout/preview_seek_bar_view_pager.xml
@@ -24,7 +24,8 @@
         android:id="@+id/preview_pager"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:background="?android:attr/colorBackgroundFloating" />
+        android:background="?android:attr/colorBackgroundFloating"
+        android:importantForAccessibility="noHideDescendants"/>
 
     <View
         android:layout_width="match_parent"
diff --git a/res/layout/screen_zoom_preview_2.xml b/res/layout/screen_zoom_preview_2.xml
index ca2ecca..d9b748d 100644
--- a/res/layout/screen_zoom_preview_2.xml
+++ b/res/layout/screen_zoom_preview_2.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
+<!-- Copyright (C) 2016 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.
@@ -13,11 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.settings.display.AppGridView
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:scrollbars="none"
-    android:background="?android:attr/colorBackgroundFloating">
-
-</ScrollView>
+    android:layout_height="match_parent" />
diff --git a/res/layout/screen_zoom_preview_settings.xml b/res/layout/screen_zoom_preview_settings.xml
new file mode 100644
index 0000000..cf9a8bd
--- /dev/null
+++ b/res/layout/screen_zoom_preview_settings.xml
@@ -0,0 +1,219 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:scrollbars="none"
+    android:background="?android:attr/colorBackgroundFloating">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <!-- Wifi Setting -->
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="16dp"
+            android:paddingStart="8dp"
+            android:orientation="horizontal">
+
+            <ImageView
+                android:layout_width="48dp"
+                android:layout_height="48dp"
+                android:src="@drawable/wifi_signal_dark"
+                android:tint="?android:attr/colorAccent"
+                android:scaleType="center" />
+
+            <LinearLayout
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:orientation="vertical"
+                android:paddingStart="16dp">
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/wifi_settings"
+                    android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+                    android:textColor="?android:attr/textColorPrimary" />
+
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/wifi_display_status_not_available"
+                    android:textAppearance="@android:style/TextAppearance.Material.Body1"
+                    android:textColor="?android:attr/textColorSecondary" />
+            </LinearLayout>
+        </LinearLayout>
+
+        <!-- Data usage Setting -->
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="16dp"
+            android:paddingStart="8dp"
+            android:orientation="horizontal">
+
+            <ImageView
+                android:layout_width="48dp"
+                android:layout_height="48dp"
+                android:src="@drawable/ic_settings_data_usage"
+                android:tint="?android:attr/colorAccent"
+                android:scaleType="center" />
+
+            <LinearLayout
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:orientation="vertical"
+                android:paddingStart="16dp">
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/data_usage_summary_title"
+                    android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+                    android:textColor="?android:attr/textColorPrimary" />
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/no_data_usage"
+                    android:textAppearance="@android:style/TextAppearance.Material.Body1"
+                    android:textColor="?android:attr/textColorSecondary" />
+            </LinearLayout>
+        </LinearLayout>
+
+        <!-- Display Setting -->
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="16dp"
+            android:paddingStart="8dp"
+            android:orientation="horizontal">
+
+            <ImageView
+                android:layout_width="48dp"
+                android:layout_height="48dp"
+                android:src="@drawable/ic_settings_display"
+                android:tint="?android:attr/colorAccent"
+                android:scaleType="center" />
+
+            <LinearLayout
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:orientation="vertical"
+                android:paddingStart="16dp">
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/display_settings_title"
+                    android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+                    android:textColor="?android:attr/textColorPrimary" />
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/display_summary_on"
+                    android:textAppearance="@android:style/TextAppearance.Material.Body1"
+                    android:textColor="?android:attr/textColorSecondary" />
+            </LinearLayout>
+        </LinearLayout>
+
+        <!-- Sound & Notification Setting -->
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="16dp"
+            android:paddingStart="8dp"
+            android:orientation="horizontal">
+
+            <ImageView
+                android:layout_width="48dp"
+                android:layout_height="48dp"
+                android:src="@drawable/ic_settings_sound"
+                android:tint="?android:attr/colorAccent"
+                android:scaleType="center" />
+
+            <LinearLayout
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:orientation="vertical"
+                android:paddingStart="16dp">
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/sound_settings"
+                    android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+                    android:textColor="?android:attr/textColorPrimary" />
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/sound_settings_example_summary"
+                    android:textAppearance="@android:style/TextAppearance.Material.Body1"
+                    android:textColor="?android:attr/textColorSecondary" />
+            </LinearLayout>
+        </LinearLayout>
+
+        <!-- Apps Setting -->
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="16dp"
+            android:paddingStart="8dp"
+            android:orientation="horizontal">
+
+            <ImageView
+                android:layout_width="48dp"
+                android:layout_height="48dp"
+                android:src="@drawable/ic_settings_applications"
+                android:tint="?android:attr/colorAccent"
+                android:scaleType="center" />
+
+            <LinearLayout
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:orientation="vertical"
+                android:paddingStart="16dp">
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/applications_settings"
+                    android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+                    android:textColor="?android:attr/textColorPrimary" />
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/apps_summary_example"
+                    android:textAppearance="@android:style/TextAppearance.Material.Body1"
+                    android:textColor="?android:attr/textColorSecondary" />
+            </LinearLayout>
+        </LinearLayout>
+    </LinearLayout>
+</ScrollView>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1122e0f..9644171 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1130,6 +1130,21 @@
     <!-- Title shown on security settings to allow the user to change their lockscreen password [CHAR LIMIT=22]-->
     <string name="unlock_change_lock_password_title">Change unlock password</string>
 
+    <!-- Message shown when the user incorrectly enters their lock and it counts towards the max attempts before wiping the work profile. -->
+    <string name="lock_profile_wipe_attempts">Try again. Attempt <xliff:g id="current_attempts">%1$d</xliff:g> of <xliff:g id="total_attempts">%2$d</xliff:g>.</string>
+    <!-- Title of a dialog shown when the user only has one attempt left to provide the lock before the work profile is wiped. -->
+    <string name="lock_profile_wipe_warning_title">Last try</string>
+    <!-- Content of the dialog shown when the user only has one attempt left to provide the work pattern before the work profile is wiped. -->
+    <string name="lock_profile_wipe_warning_content_pattern">If you enter an incorrect work pattern on this attempt, your work profile and associated data will be removed from this device.</string>
+    <!-- Content of the dialog shown when the user only has one attempt left to provide the work PIN before the work profile is wiped. -->
+    <string name="lock_profile_wipe_warning_content_pin">If you enter an incorrect work PIN on this attempt, your work profile and associated data will be removed from this device.</string>
+    <!-- Content of the dialog shown when the user only has one attempt left to provide the work password before the work profile is wiped. -->
+    <string name="lock_profile_wipe_warning_content_password">If you enter an incorrect work password on this attempt, your work profile and associated data will be removed from this device.</string>
+    <!-- Content of the dialog shown when the user has failed to provide the work lock too many times and the work profile is wiped. -->
+    <string name="lock_profile_wipe_content">Too many incorrect attempts. Your work profile and associated data will be removed from this device.</string>
+    <!-- Button label to dismiss the dialog telling the user the work profile has been wiped. [CHAR LIMIT=40] -->
+    <string name="lock_profile_wipe_dismiss">Dismiss</string>
+
     <!-- Hint shown in dialog screen when password is too short -->
     <string name="lockpassword_password_too_short">Password must be at least %d characters</string>
     <!-- Hint shown in dialog screen when PIN is too short -->
@@ -4443,6 +4458,11 @@
         behalf.  It comes from the <xliff:g id="voice_input_service_app_name">%s</xliff:g>
         application.  Enable the use of this service?</string>
 
+    <!-- On main TTS Settings screen, in default settings section, reset speech rate for synthesized voice to 1x speech rate.-->
+    <string name="tts_reset_speech_rate_title">Reset speech rate</string>
+    <!-- On main TTS Settings screen, summary for reset speech rate for synthesized voice -->
+    <string name="tts_reset_speech_rate_summary">Reset the speed at which the text is spoken to normal.</string>
+
     <!-- Power Control Widget -->
     <string name="gadget_title">Power control</string>
     <string name="gadget_toggle_wifi">Updating Wi\u2011Fi setting</string>
@@ -5748,6 +5768,9 @@
     <!-- Sound: Dashboard summary. [CHAR LIMIT=100] -->
     <string name="sound_settings_summary">Ringer volume at <xliff:g id="percentage" example="2">%1$s</xliff:g></string>
 
+    <!-- Sound: Dashboard summary example used in Setup Wizard preview screen. [CHAR LIMIT=100] -->
+    <string name="sound_settings_example_summary">Ringer volume at 80%</string>
+
     <!-- Sound: Title for the option managing media volume. [CHAR LIMIT=30] -->
     <string name="media_volume_option_title">Media volume</string>
 
@@ -6923,6 +6946,8 @@
 
     <!-- Summary of apps [CHAR LIMIT=NONE] -->
     <string name="apps_summary"><xliff:g id="count" example="24">%1$d</xliff:g> apps installed</string>
+    <!-- Example summary of apps used in Setup Wizard preview screen [CHAR LIMIT=NONE] -->
+    <string name="apps_summary_example">24 apps installed</string>
 
     <!-- Summary of storage usage [CHAR LIMIT=NONE] -->
     <string name="storage_summary"><xliff:g id="size1" example="8GB">%1$s</xliff:g> of <xliff:g id="size2" example="32GB">%2$s</xliff:g> used</string>
@@ -7146,4 +7171,19 @@
     <!-- Title for suggestion adding more fingerprints [CHAR LIMIT=30] -->
     <string name="suggestion_additional_fingerprints">Additional Fingerprints</string>
 
+    <!-- Summary of battery saver when on [CHAR LIMIT=NONE] -->
+    <string name="battery_saver_on_summary">On / <xliff:g name="automatic_state" example="Never turn on automatically">%1$s</xliff:g></string>
+
+    <!-- Summary of battery saver when off [CHAR LIMIT=NONE] -->
+    <string name="battery_saver_off_summary">Off / <xliff:g name="automatic_state" example="Never turn on automatically">%1$s</xliff:g></string>
+
+    <!-- [CHAR_LIMIT=NONE] Battery saver: Description for automatic entry option: Never -->
+    <string name="battery_saver_desc_turn_on_auto_never">Never turn on automatically</string>
+
+    <!-- [CHAR_LIMIT=NONE] Battery saver: Description for automatic entry option: pct% battery -->
+    <string name="battery_saver_desc_turn_on_auto_pct">Turn on automatically at %1$s battery</string>
+
+    <!-- [CHAR_LIMIT=NONE] Label for when app is ignoring battery optimizations -->
+    <string name="not_battery_optimizing">Not using battery optimization</string>
+
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index a74d70b..70b5005 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -101,6 +101,10 @@
         <item name="android:widgetLayout">@layout/preference_widget_sync_toggle</item>
     </style>
 
+    <style name="EditTextPreference" parent="@*android:style/Preference.Material.DialogPreference.EditTextPreference">
+        <item name="android:dialogLayout">@layout/preference_dialog_edittext</item>
+    </style>
+
     <style name="PreferenceHeaderPanelSinglePane">
         <item name="android:layout_marginStart">0dp</item>
         <item name="android:layout_marginEnd">0dp</item>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 30c372b..fbe574e 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -102,6 +102,7 @@
 
     <style name="PreferenceTheme" parent="@android:style/Theme.DeviceDefault.Settings">
         <item name="@android:preferenceStyle">@style/Preference</item>
+        <item name="@android:editTextPreferenceStyle">@style/EditTextPreference</item>
         <item name="@dropdownPreferenceStyle">@style/Preference.DropDown.Material</item>
         <item name="@android:preferenceFragmentStyle">@style/PreferenceFragmentStyle</item>
         <item name="apnPreferenceStyle">@style/ApnPreference</item>
diff --git a/res/xml/power_usage_summary.xml b/res/xml/power_usage_summary.xml
index 3f39d47..1ae0a44 100644
--- a/res/xml/power_usage_summary.xml
+++ b/res/xml/power_usage_summary.xml
@@ -19,6 +19,10 @@
         android:title="@string/power_usage_summary_title"
         settings:keywords="@string/keywords_battery">
 
+        <com.android.settings.fuelgauge.BatterySaverPreference
+            android:title="@string/battery_saver"
+            android:fragment="com.android.settings.fuelgauge.BatterySaverSettings" />
+
         <com.android.settings.fuelgauge.BatteryHistoryPreference
             android:key="battery_history" />
 
diff --git a/res/xml/tts_settings.xml b/res/xml/tts_settings.xml
index 071406b..b980f0a 100644
--- a/res/xml/tts_settings.xml
+++ b/res/xml/tts_settings.xml
@@ -31,6 +31,11 @@
             android:defaultValue="50"
             android:max="600" />
 
+        <Preference android:key="reset_speech_rate"
+            android:persistent="false"
+            android:title="@string/tts_reset_speech_rate_title"
+            android:summary="@string/tts_reset_speech_rate_summary" />
+
         <Preference android:key="tts_play_example"
             android:persistent="false"
             android:title="@string/tts_play_example_title"
diff --git a/res/xml/user_settings.xml b/res/xml/user_settings.xml
index 5944b3e..8d20f31 100644
--- a/res/xml/user_settings.xml
+++ b/res/xml/user_settings.xml
@@ -35,9 +35,9 @@
                 android:key="add_users_when_locked"
                 android:title="@string/user_add_on_lockscreen_menu"
                 android:summary="@string/user_add_on_lockscreen_menu_summary" />
-        <Preference
-            android:key="emergency_info"
-            android:title="@string/emergency_info_title"
-            android:summary="@string/emergency_info_subtitle"/>
     </PreferenceCategory>
+    <Preference
+        android:key="emergency_info"
+        android:title="@string/emergency_info_title"
+        android:summary="@string/emergency_info_subtitle"/>
 </PreferenceScreen>
diff --git a/src/com/android/settings/ApnEditor.java b/src/com/android/settings/ApnEditor.java
index c0b6e00..102d6cc 100644
--- a/src/com/android/settings/ApnEditor.java
+++ b/src/com/android/settings/ApnEditor.java
@@ -21,7 +21,6 @@
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Intent;
-import android.content.SharedPreferences;
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.net.Uri;
@@ -40,15 +39,13 @@
 import android.view.KeyEvent;
 import android.view.Menu;
 import android.view.MenuItem;
-
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 
 import java.util.HashSet;
 import java.util.Set;
 
 public class ApnEditor extends InstrumentedPreferenceActivity
-        implements SharedPreferences.OnSharedPreferenceChangeListener,
-                    Preference.OnPreferenceChangeListener {
+        implements Preference.OnPreferenceChangeListener {
 
     private final static String TAG = ApnEditor.class.getSimpleName();
 
@@ -250,6 +247,10 @@
 
         mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
 
+        for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
+            getPreferenceScreen().getPreference(i).setOnPreferenceChangeListener(this);
+        }
+
         fillUi();
     }
 
@@ -261,14 +262,10 @@
     @Override
     public void onResume() {
         super.onResume();
-        getPreferenceScreen().getSharedPreferences()
-                .registerOnSharedPreferenceChangeListener(this);
     }
 
     @Override
     public void onPause() {
-        getPreferenceScreen().getSharedPreferences()
-                .unregisterOnSharedPreferenceChangeListener(this);
         super.onPause();
     }
 
@@ -487,7 +484,7 @@
                 int index = Integer.parseInt((String) newValue);
                 mAuthType.setValueIndex(index);
 
-                String []values = mRes.getStringArray(R.array.apn_auth_entries);
+                String[] values = mRes.getStringArray(R.array.apn_auth_entries);
                 mAuthType.setSummary(values[index]);
             } catch (NumberFormatException e) {
                 return false;
@@ -521,6 +518,13 @@
             mMvnoType.setValue((String) newValue);
             mMvnoType.setSummary(mvno);
         }
+        if (preference.equals(mPassword)) {
+            preference.setSummary(starify(newValue != null ? String.valueOf(newValue) : ""));
+        } else if (preference.equals(mCarrierEnabled) || preference.equals(mBearerMulti)) {
+            // do nothing
+        } else {
+            preference.setSummary(checkNull(newValue != null ? String.valueOf(newValue) : null));
+        }
 
         return true;
     }
@@ -765,16 +769,4 @@
         }
     }
 
-    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
-        Preference pref = findPreference(key);
-        if (pref != null) {
-            if (pref.equals(mPassword)){
-                pref.setSummary(starify(sharedPreferences.getString(key, "")));
-            } else if (pref.equals(mCarrierEnabled) || pref.equals(mBearerMulti)) {
-                // do nothing
-            } else {
-                pref.setSummary(checkNull(sharedPreferences.getString(key, "")));
-            }
-        }
-    }
 }
diff --git a/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java b/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java
index 40e3103..ad1d2eb 100644
--- a/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java
+++ b/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java
@@ -20,10 +20,13 @@
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
+import android.app.AlertDialog;
 import android.app.IActivityManager;
 import android.app.admin.DevicePolicyManager;
 import android.app.trust.TrustManager;
 import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
 import android.content.Intent;
 import android.content.IntentSender;
 import android.graphics.Point;
@@ -31,7 +34,9 @@
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.os.UserManager;
 import android.view.View;
 import android.view.ViewGroup;
@@ -40,6 +45,7 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import com.android.internal.widget.LockPatternUtils;
 import com.android.settings.fingerprint.FingerprintUiHelper;
 
 /**
@@ -65,6 +71,9 @@
     protected Button mCancelButton;
     protected ImageView mFingerprintIcon;
     protected int mEffectiveUserId;
+    protected LockPatternUtils mLockPatternUtils;
+    protected TextView mErrorTextView;
+    protected final Handler mHandler = new Handler();
 
     @Override
     public void onCreate(@Nullable Bundle savedInstanceState) {
@@ -74,6 +83,7 @@
         // Only take this argument into account if it belongs to the current profile.
         Intent intent = getActivity().getIntent();
         mEffectiveUserId = Utils.getUserIdFromBundle(getActivity(), intent.getExtras());
+        mLockPatternUtils = new LockPatternUtils(getActivity());
     }
 
     @Override
@@ -109,6 +119,10 @@
         if (mAllowFpAuthentication) {
             mFingerprintHelper.startListening();
         }
+        if (isProfileChallenge()) {
+            updateErrorMessage(mLockPatternUtils.getCurrentFailedPasswordAttempts(
+                    mEffectiveUserId));
+        }
     }
 
     protected void setAccessibilityTitle(CharSequence suplementalText) {
@@ -200,4 +214,87 @@
                     screenSize.y));
         }
     }
+
+    protected boolean isProfileChallenge() {
+        return UserHandle.myUserId() != mEffectiveUserId;
+    }
+
+    protected void reportSuccessfullAttempt() {
+        if (isProfileChallenge()) {
+            mLockPatternUtils.reportSuccessfulPasswordAttempt(mEffectiveUserId);
+        }
+    }
+
+    protected void reportFailedAttempt() {
+        if (isProfileChallenge()) {
+            // + 1 for this attempt.
+            updateErrorMessage(
+                    mLockPatternUtils.getCurrentFailedPasswordAttempts(mEffectiveUserId) + 1);
+            mLockPatternUtils.reportFailedPasswordAttempt(mEffectiveUserId);
+        }
+    }
+
+    protected void updateErrorMessage(int numAttempts) {
+        final int maxAttempts =
+                mLockPatternUtils.getMaximumFailedPasswordsForWipe(mEffectiveUserId);
+        if (maxAttempts > 0 && numAttempts > 0) {
+            int remainingAttempts = maxAttempts - numAttempts;
+            if (remainingAttempts == 1) {
+                // Last try
+                final String title = getActivity().getString(
+                        R.string.lock_profile_wipe_warning_title);
+                final String message = getActivity().getString(getLastTryErrorMessage());
+                showDialog(title, message, android.R.string.ok, false /* dismiss */);
+            } else if (remainingAttempts <= 0) {
+                // Profile is wiped
+                final String message = getActivity().getString(R.string.lock_profile_wipe_content);
+                showDialog(null, message, R.string.lock_profile_wipe_dismiss, true /* dismiss */);
+            }
+            if (mErrorTextView != null) {
+                final String message = getActivity().getString(R.string.lock_profile_wipe_attempts,
+                        numAttempts, maxAttempts);
+                showError(message, 0);
+            }
+        }
+    }
+
+    protected abstract int getLastTryErrorMessage();
+
+    private final Runnable mResetErrorRunnable = new Runnable() {
+        @Override
+        public void run() {
+            mErrorTextView.setText("");
+        }
+    };
+
+    protected void showError(CharSequence msg, long timeout) {
+        mErrorTextView.setText(msg);
+        onShowError();
+        mHandler.removeCallbacks(mResetErrorRunnable);
+        if (timeout != 0) {
+            mHandler.postDelayed(mResetErrorRunnable, timeout);
+        }
+    }
+
+    protected abstract void onShowError();
+
+    protected void showError(int msg, long timeout) {
+        showError(getText(msg), timeout);
+    }
+
+    private void showDialog(String title, String message, int buttonString, final boolean dismiss) {
+        final AlertDialog dialog = new AlertDialog.Builder(getActivity())
+            .setTitle(title)
+            .setMessage(message)
+            .setPositiveButton(buttonString, new OnClickListener() {
+                @Override
+                public void onClick(DialogInterface dialog, int which) {
+                    if (dismiss) {
+                        getActivity().finish();
+                    }
+                }
+            })
+            .create();
+        dialog.show();
+    }
 }
diff --git a/src/com/android/settings/ConfirmLockPassword.java b/src/com/android/settings/ConfirmLockPassword.java
index 8f83221..c69bb89 100644
--- a/src/com/android/settings/ConfirmLockPassword.java
+++ b/src/com/android/settings/ConfirmLockPassword.java
@@ -20,11 +20,9 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentSender;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.CountDownTimer;
-import android.os.Handler;
 import android.os.SystemClock;
 import android.os.UserManager;
 import android.os.storage.StorageManager;
@@ -84,14 +82,11 @@
         private static final String FRAGMENT_TAG_CHECK_LOCK_RESULT = "check_lock_result";
         private TextView mPasswordEntry;
         private TextViewInputDisabler mPasswordEntryInputDisabler;
-        private LockPatternUtils mLockPatternUtils;
         private AsyncTask<?, ?, ?> mPendingLockCheck;
         private CredentialCheckResultTracker mCredentialCheckResultTracker;
         private boolean mDisappearing = false;
         private TextView mHeaderTextView;
         private TextView mDetailsTextView;
-        private TextView mErrorTextView;
-        private Handler mHandler = new Handler();
         private CountDownTimer mCountdownTimer;
         private boolean mIsAlpha;
         private InputMethodManager mImm;
@@ -108,7 +103,6 @@
         @Override
         public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
-            mLockPatternUtils = new LockPatternUtils(getActivity());
         }
 
         @Override
@@ -194,6 +188,12 @@
         }
 
         @Override
+        protected int getLastTryErrorMessage() {
+            return mIsAlpha ? R.string.lock_profile_wipe_warning_content_password
+                    : R.string.lock_profile_wipe_warning_content_pin;
+        }
+
+        @Override
         public void prepareEnterAnimation() {
             super.prepareEnterAnimation();
             mHeaderTextView.setAlpha(0f);
@@ -406,9 +406,12 @@
         }
 
         private void onPasswordChecked(boolean matched, Intent intent, int timeoutMs,
-                int effectiveUserId) {
+                int effectiveUserId, boolean newResult) {
             mPasswordEntryInputDisabler.setInputEnabled(true);
             if (matched) {
+                if (newResult) {
+                    reportSuccessfullAttempt();
+                }
                 startDisappearAnimation(intent);
                 checkForPendingIntent();
             } else {
@@ -417,15 +420,23 @@
                             effectiveUserId, timeoutMs);
                     handleAttemptLockout(deadline);
                 } else {
-                    showError(getErrorMessage());
+                    showError(getErrorMessage(), ERROR_MESSAGE_TIMEOUT);
+                }
+                if (newResult) {
+                    reportFailedAttempt();
                 }
             }
         }
 
         @Override
         public void onCredentialChecked(boolean matched, Intent intent, int timeoutMs,
-                int effectiveUserId) {
-            onPasswordChecked(matched, intent, timeoutMs, effectiveUserId);
+                int effectiveUserId, boolean newResult) {
+            onPasswordChecked(matched, intent, timeoutMs, effectiveUserId, newResult);
+        }
+
+        @Override
+        protected void onShowError() {
+            mPasswordEntry.setText(null);
         }
 
         private void handleAttemptLockout(long elapsedRealtimeDeadline) {
@@ -447,6 +458,10 @@
                 public void onFinish() {
                     resetState();
                     mErrorTextView.setText("");
+                    if (isProfileChallenge()) {
+                        updateErrorMessage(mLockPatternUtils.getCurrentFailedPasswordAttempts(
+                                mEffectiveUserId));
+                    }
                 }
             }.start();
         }
@@ -464,29 +479,6 @@
             }
         }
 
-        private void showError(int msg) {
-            showError(msg, ERROR_MESSAGE_TIMEOUT);
-        }
-
-        private final Runnable mResetErrorRunnable = new Runnable() {
-            public void run() {
-                mErrorTextView.setText("");
-            }
-        };
-
-        private void showError(CharSequence msg, long timeout) {
-            mErrorTextView.setText(msg);
-            mPasswordEntry.setText(null);
-            mHandler.removeCallbacks(mResetErrorRunnable);
-            if (timeout != 0) {
-                mHandler.postDelayed(mResetErrorRunnable, timeout);
-            }
-        }
-
-        private void showError(int msg, long timeout) {
-            showError(getText(msg), timeout);
-        }
-
         // {@link OnEditorActionListener} methods.
         public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
             // Check if this was the result of hitting the enter or "done" key
diff --git a/src/com/android/settings/ConfirmLockPattern.java b/src/com/android/settings/ConfirmLockPattern.java
index d4b0902..dbe9ebe 100644
--- a/src/com/android/settings/ConfirmLockPattern.java
+++ b/src/com/android/settings/ConfirmLockPattern.java
@@ -18,7 +18,6 @@
 
 import android.app.Activity;
 import android.content.Intent;
-import android.content.IntentSender;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.CountDownTimer;
@@ -85,7 +84,6 @@
         private static final String FRAGMENT_TAG_CHECK_LOCK_RESULT = "check_lock_result";
 
         private LockPatternView mLockPatternView;
-        private LockPatternUtils mLockPatternUtils;
         private AsyncTask<?, ?, ?> mPendingLockCheck;
         private CredentialCheckResultTracker mCredentialCheckResultTracker;
         private boolean mDisappearing = false;
@@ -93,7 +91,6 @@
 
         private TextView mHeaderTextView;
         private TextView mDetailsTextView;
-        private TextView mErrorTextView;
         private View mLeftSpacerLandscape;
         private View mRightSpacerLandscape;
 
@@ -112,7 +109,6 @@
         @Override
         public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
-            mLockPatternUtils = new LockPatternUtils(getActivity());
         }
 
         @Override
@@ -221,6 +217,10 @@
         }
 
         @Override
+        protected void onShowError() {
+        }
+
+        @Override
         public void prepareEnterAnimation() {
             super.prepareEnterAnimation();
             mHeaderTextView.setAlpha(0f);
@@ -284,6 +284,10 @@
                                 R.string.lockpassword_confirm_your_pattern_generic_profile);
                     }
                     mErrorTextView.setText("");
+                    if (isProfileChallenge()) {
+                        updateErrorMessage(mLockPatternUtils.getCurrentFailedPasswordAttempts(
+                                mEffectiveUserId));
+                    }
 
                     mLockPatternView.setEnabled(true);
                     mLockPatternView.enableInput();
@@ -470,9 +474,12 @@
         };
 
         private void onPatternChecked(boolean matched, Intent intent, int timeoutMs,
-                int effectiveUserId) {
+                int effectiveUserId, boolean newResult) {
             mLockPatternView.setEnabled(true);
             if (matched) {
+                if (newResult) {
+                    reportSuccessfullAttempt();
+                }
                 startDisappearAnimation(intent);
                 checkForPendingIntent();
             } else {
@@ -484,13 +491,21 @@
                     updateStage(Stage.NeedToUnlockWrong);
                     postClearPatternRunnable();
                 }
+                if (newResult) {
+                    reportFailedAttempt();
+                }
             }
         }
 
         @Override
         public void onCredentialChecked(boolean matched, Intent intent, int timeoutMs,
-                int effectiveUserId) {
-            onPatternChecked(matched, intent, timeoutMs, effectiveUserId);
+                int effectiveUserId, boolean newResult) {
+            onPatternChecked(matched, intent, timeoutMs, effectiveUserId, newResult);
+        }
+
+        @Override
+        protected int getLastTryErrorMessage() {
+            return R.string.lock_profile_wipe_warning_content_pattern;
         }
 
         private void handleAttemptLockout(long elapsedRealtimeDeadline) {
diff --git a/src/com/android/settings/CredentialCheckResultTracker.java b/src/com/android/settings/CredentialCheckResultTracker.java
index 5c55073..179a93c 100644
--- a/src/com/android/settings/CredentialCheckResultTracker.java
+++ b/src/com/android/settings/CredentialCheckResultTracker.java
@@ -47,7 +47,7 @@
         mListener = listener;
         if (mListener != null && mHasResult) {
             mListener.onCredentialChecked(mResultMatched, mResultData, mResultTimeoutMs,
-                    mResultEffectiveUserId);
+                    mResultEffectiveUserId, false /* newResult */);
         }
     }
 
@@ -60,7 +60,7 @@
         mHasResult = true;
         if (mListener != null) {
             mListener.onCredentialChecked(mResultMatched, mResultData, mResultTimeoutMs,
-                    mResultEffectiveUserId);
+                    mResultEffectiveUserId, true /* newResult */);
         }
     }
 
@@ -74,6 +74,6 @@
 
     interface Listener {
         public void onCredentialChecked(boolean matched, Intent intent, int timeoutMs,
-                int effectiveUserId);
+                int effectiveUserId, boolean newResult);
     }
 }
diff --git a/src/com/android/settings/DateTimeSettings.java b/src/com/android/settings/DateTimeSettings.java
index a67ef72..90c1d38 100644
--- a/src/com/android/settings/DateTimeSettings.java
+++ b/src/com/android/settings/DateTimeSettings.java
@@ -19,9 +19,10 @@
 import android.app.Activity;
 import android.app.AlarmManager;
 import android.app.DatePickerDialog;
+import android.app.DatePickerDialog.OnDateSetListener;
 import android.app.Dialog;
 import android.app.TimePickerDialog;
-import android.app.admin.DevicePolicyManager;
+import android.app.TimePickerDialog.OnTimeSetListener;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -33,10 +34,10 @@
 import android.provider.Settings.SettingNotFoundException;
 import android.support.v14.preference.SwitchPreference;
 import android.support.v7.preference.Preference;
+import android.support.v7.preference.Preference.OnPreferenceChangeListener;
 import android.text.format.DateFormat;
 import android.widget.DatePicker;
 import android.widget.TimePicker;
-
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.settings.dashboard.SummaryLoader;
 import com.android.settingslib.RestrictedLockUtils;
@@ -49,8 +50,7 @@
 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 
 public class DateTimeSettings extends SettingsPreferenceFragment
-        implements OnSharedPreferenceChangeListener,
-                TimePickerDialog.OnTimeSetListener, DatePickerDialog.OnDateSetListener {
+        implements OnTimeSetListener, OnDateSetListener, OnPreferenceChangeListener {
 
     private static final String HOURS_12 = "12";
     private static final String HOURS_24 = "24";
@@ -94,6 +94,7 @@
         boolean autoTimeZoneEnabled = getAutoState(Settings.Global.AUTO_TIME_ZONE);
 
         mAutoTimePref = (RestrictedSwitchPreference) findPreference(KEY_AUTO_TIME);
+        mAutoTimePref.setOnPreferenceChangeListener(this);
         EnforcedAdmin admin = RestrictedLockUtils.checkIfAutoTimeRequired(getActivity());
         mAutoTimePref.setDisabledByAdmin(admin);
 
@@ -106,6 +107,7 @@
         // Settings.Global.AUTO_TIME to true. Note that this app listens to that change.
         mAutoTimePref.setChecked(autoTimeEnabled);
         mAutoTimeZonePref = (SwitchPreference) findPreference(KEY_AUTO_TIME_ZONE);
+        mAutoTimeZonePref.setOnPreferenceChangeListener(this);
         // Override auto-timezone if it's a wifi-only device or if we're still in setup wizard.
         // TODO: Remove the wifiOnly test when auto-timezone is implemented based on wifi-location.
         if (Utils.isWifiOnly(getActivity()) || isFirstRun) {
@@ -131,9 +133,6 @@
     public void onResume() {
         super.onResume();
 
-        getPreferenceScreen().getSharedPreferences()
-                .registerOnSharedPreferenceChangeListener(this);
-
         ((SwitchPreference)mTime24Pref).setChecked(is24Hour());
 
         // Register for time ticks and other reasons for time change
@@ -150,8 +149,6 @@
     public void onPause() {
         super.onPause();
         getActivity().unregisterReceiver(mIntentReceiver);
-        getPreferenceScreen().getSharedPreferences()
-                .unregisterOnSharedPreferenceChangeListener(this);
     }
 
     public void updateTimeAndDateDisplay(Context context) {
@@ -190,19 +187,20 @@
     }
 
     @Override
-    public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
-        if (key.equals(KEY_AUTO_TIME)) {
-            boolean autoEnabled = preferences.getBoolean(key, true);
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if (preference.getKey().equals(KEY_AUTO_TIME)) {
+            boolean autoEnabled = (Boolean) newValue;
             Settings.Global.putInt(getContentResolver(), Settings.Global.AUTO_TIME,
                     autoEnabled ? 1 : 0);
             mTimePref.setEnabled(!autoEnabled);
             mDatePref.setEnabled(!autoEnabled);
-        } else if (key.equals(KEY_AUTO_TIME_ZONE)) {
-            boolean autoZoneEnabled = preferences.getBoolean(key, true);
+        } else if (preference.getKey().equals(KEY_AUTO_TIME_ZONE)) {
+            boolean autoZoneEnabled = (Boolean) newValue;
             Settings.Global.putInt(
                     getContentResolver(), Settings.Global.AUTO_TIME_ZONE, autoZoneEnabled ? 1 : 0);
             mTimeZone.setEnabled(!autoZoneEnabled);
         }
+        return true;
     }
 
     @Override
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index 9aebdbf..49d72b4 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -40,7 +40,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Button;
-import com.android.settings.accessibility.AccessibilitySettingsForSetupWizardActivity;
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.widget.FloatingActionButton;
 
@@ -164,8 +163,7 @@
     @Override
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
-        if (!TextUtils.isEmpty(mHelpUri)
-                && !(getActivity() instanceof AccessibilitySettingsForSetupWizardActivity)) {
+        if (!TextUtils.isEmpty(mHelpUri)) {
             setHasOptionsMenu(true);
         }
     }
diff --git a/src/com/android/settings/TintablePreference.java b/src/com/android/settings/TintablePreference.java
index 0ada6ed..45f43fb 100644
--- a/src/com/android/settings/TintablePreference.java
+++ b/src/com/android/settings/TintablePreference.java
@@ -42,6 +42,8 @@
         if (mTintColor != 0) {
             ((ImageView) view.findViewById(android.R.id.icon)).setImageTintList(
                     ColorStateList.valueOf(mTintColor));
+        } else {
+            ((ImageView) view.findViewById(android.R.id.icon)).setImageTintList(null);
         }
     }
 }
diff --git a/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizard.java b/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizard.java
index 26f5f39..35bb83b 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizard.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizard.java
@@ -17,14 +17,18 @@
 package com.android.settings.accessibility;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
+import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.ServiceInfo;
 import android.content.res.Resources;
 import android.os.Bundle;
+import android.os.Handler;
 import android.provider.Settings;
 import android.support.v7.preference.Preference;
+import android.util.Log;
 import android.view.accessibility.AccessibilityManager;
 
 import com.android.internal.logging.MetricsProto;
@@ -40,16 +44,30 @@
 public class AccessibilitySettingsForSetupWizard extends SettingsPreferenceFragment
         implements DialogCreatable, Preference.OnPreferenceChangeListener {
 
+    private static final String TAG = AccessibilitySettingsForSetupWizard.class.getSimpleName();
+
     // Preferences.
     private static final String DISPLAY_MAGNIFICATION_PREFERENCE =
             "screen_magnification_preference";
-    private static final String TALKBACK_PREFERENCE = "talkback_preference";
+    private static final String SCREEN_READER_PREFERENCE = "talkback_preference";
     private static final String FONT_SIZE_PREFERENCE = "font_size_preference";
 
+    // Time needed to let Talkback initialize its self before launching the tutorial.
+    private static final long SCREEN_READER_INITIALIZATION_DELAY_MS = 3000;
+
+    private String mTalkbackPackage;
+
     // Preference controls.
     private Preference mDisplayMagnificationPreference;
     private Preference mTalkbackPreference;
 
+    private Runnable mStartTalkbackRunnable = new Runnable() {
+        @Override
+        public void run() {
+            launchTalkbackTutorial();
+        }
+    };
+
     @Override
     protected int getMetricsCategory() {
         return MetricsProto.MetricsEvent.ACCESSIBILITY;
@@ -61,7 +79,7 @@
         addPreferencesFromResource(R.xml.accessibility_settings_for_setup_wizard);
 
         mDisplayMagnificationPreference = findPreference(DISPLAY_MAGNIFICATION_PREFERENCE);
-        mTalkbackPreference = findPreference(TALKBACK_PREFERENCE);
+        mTalkbackPreference = findPreference(SCREEN_READER_PREFERENCE);
     }
 
     @Override
@@ -75,41 +93,16 @@
         return false;
     }
 
-    /**
-     * Returns a semicolon-delimited string containing a list of all the
-     * installed {@link AccessibilityService}s that provide at least one
-     * required feedback type.
-     *
-     * @param context The {@link android.app.Activity} context.
-     * @param requiredFeedbackTypes An integer mask containing the required
-     *            feedback types.
-     * @return A semicolon-delimited string containing a list of accessibility services.
-     */
-    private String getAccessibilityServicesFiltered(
-            Context context, int requiredFeedbackTypes) {
-        final AccessibilityManager manager = context.getSystemService(AccessibilityManager.class);
-        final List<AccessibilityServiceInfo> accessibilityServices = manager
-                .getInstalledAccessibilityServiceList();
-        final StringBuilder servicesToEnable = new StringBuilder();
-
-        for (AccessibilityServiceInfo accessibilityService : accessibilityServices) {
-            if ((accessibilityService.feedbackType & requiredFeedbackTypes) == 0) {
-                continue;
-            }
-
-            final ServiceInfo serviceInfo = accessibilityService.getResolveInfo().serviceInfo;
-            final ComponentName componentName = new ComponentName(serviceInfo.packageName,
-                    serviceInfo.name);
-
-            servicesToEnable.append(componentName.flattenToString());
-            servicesToEnable.append(':');
+    private void launchTalkbackTutorial() {
+        try {
+            Intent intent = new Intent(Settings.ACTION_SCREEN_READER_TUTORIAL);
+            intent.setPackage(mTalkbackPackage);
+            startActivity(intent);
+        } catch (ActivityNotFoundException e) {
+            // This can happen if either the build is misconfigued or an OEM removes the intent
+            // filter for the Talkback tutorial from their implementation of Talkback.
+            Log.e(TAG, "Can't find Talkback Tutorial: " + Settings.ACTION_SCREEN_READER_TUTORIAL);
         }
-
-        if (servicesToEnable.length() > 0) {
-            servicesToEnable.deleteCharAt(servicesToEnable.length() - 1);
-        }
-
-        return servicesToEnable.toString();
     }
 
     @Override
@@ -130,17 +123,34 @@
             final int accessibilityEnabled =
                     Settings.Secure.getInt(resolver, Settings.Secure.ACCESSIBILITY_ENABLED, 0);
             if (accessibilityEnabled == 0) {
-                final String servicesToEnable = getAccessibilityServicesFiltered(
-                        getActivity(), AccessibilityServiceInfo.FEEDBACK_SPOKEN);
+                // Find the first installed screen reader.
+                String serviceToEnable = null;
+                final AccessibilityManager manager =
+                        getActivity().getSystemService(AccessibilityManager.class);
+                final List<AccessibilityServiceInfo> accessibilityServices =
+                        manager.getInstalledAccessibilityServiceList();
+                for (AccessibilityServiceInfo accessibilityService : accessibilityServices) {
+                    if ((accessibilityService.feedbackType
+                            & AccessibilityServiceInfo.FEEDBACK_SPOKEN) != 0) {
+                        final ServiceInfo serviceInfo =
+                                accessibilityService.getResolveInfo().serviceInfo;
+                        mTalkbackPackage = serviceInfo.packageName;
+                        final ComponentName componentName =
+                                new ComponentName(serviceInfo.packageName, serviceInfo.name);
+
+                        serviceToEnable = componentName.flattenToString();
+                        break;
+                    }
+                }
 
                 // Enable all accessibility services with spoken feedback type.
                 Settings.Secure.putString(resolver, Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
-                        servicesToEnable);
+                        serviceToEnable);
 
                 // Allow the services we just enabled to toggle touch exploration.
                 Settings.Secure.putString(resolver,
                         Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
-                        servicesToEnable);
+                        serviceToEnable);
 
                 // Enable touch exploration.
                 Settings.Secure.putInt(resolver, Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1);
@@ -148,6 +158,13 @@
                 // Turn on accessibility mode last, since enabling accessibility with no
                 // services has no effect.
                 Settings.Secure.putInt(resolver, Settings.Secure.ACCESSIBILITY_ENABLED, 1);
+
+                // Since Talkback will display an error message if it's not active when the Tutorial
+                // is launched, launch Talkbck Tutorial with a delay.
+                new Handler().postDelayed(mStartTalkbackRunnable,
+                        SCREEN_READER_INITIALIZATION_DELAY_MS);
+            } else {
+                launchTalkbackTutorial();
             }
         }
 
diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
index 041fed8..748dc15 100644
--- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
@@ -55,7 +55,7 @@
             view.setDividerAllowedBelow(false);
             final RelativeLayout background =
                     (RelativeLayout) view.findViewById(R.id.video_background);
-            final VideoView videoView = (VideoView) view.findViewById(R.id.video);
+            VideoView videoView = (VideoView) view.findViewById(R.id.video);
 
             // Hacky adjustment for using VideoView in recycle view and positioning
             // it on the background image
@@ -98,7 +98,8 @@
                     ContentResolver.SCHEME_ANDROID_RESOURCE,
                     getPrefContext().getPackageName(),
                     R.raw.accessibility_screen_magnification)));
-            videoView.setMediaController(new MediaController(getPrefContext()));
+            // Make sure video controls (e.g. for pausing) are not displayed.
+            videoView.setMediaController(null);
             videoView.start();
         }
     }
@@ -149,6 +150,11 @@
                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 0) {
             setMagnificationEnabled(1);
         }
+
+        VideoView videoView = (VideoView) getView().findViewById(R.id.video);
+        if (videoView != null) {
+            videoView.start();
+        }
     }
 
     @Override
diff --git a/src/com/android/settings/dashboard/SuggestionsChecks.java b/src/com/android/settings/dashboard/SuggestionsChecks.java
index d465942..7d617b7 100644
--- a/src/com/android/settings/dashboard/SuggestionsChecks.java
+++ b/src/com/android/settings/dashboard/SuggestionsChecks.java
@@ -20,12 +20,14 @@
 import android.app.IWallpaperManagerCallback;
 import android.app.KeyguardManager;
 import android.app.NotificationManager;
+import android.app.WallpaperManager;
 import android.content.Context;
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+
 import com.android.ims.ImsManager;
 import com.android.settings.Settings.FingerprintEnrollSuggestionActivity;
 import com.android.settings.Settings.FingerprintSuggestionActivity;
@@ -98,7 +100,8 @@
         IBinder b = ServiceManager.getService(Context.WALLPAPER_SERVICE);
         IWallpaperManager service = Stub.asInterface(b);
         try {
-            return service.getWallpaper(mCallback, new Bundle()) != null;
+            return service.getWallpaper(mCallback, WallpaperManager.FLAG_SET_SYSTEM,
+                    new Bundle(), mContext.getUserId()) != null;
         } catch (RemoteException e) {
         }
         return false;
diff --git a/src/com/android/settings/deviceinfo/StorageItemPreference.java b/src/com/android/settings/deviceinfo/StorageItemPreference.java
index 3875885..b6eedc3 100644
--- a/src/com/android/settings/deviceinfo/StorageItemPreference.java
+++ b/src/com/android/settings/deviceinfo/StorageItemPreference.java
@@ -39,7 +39,11 @@
 
     public void setStorageSize(long size, long total) {
         setSummary(Formatter.formatFileSize(getContext(), size));
-        progress = (int)(size * PROGRESS_MAX / total);
+        if (total == 0) {
+            progress = 0;
+        } else {
+            progress = (int)(size * PROGRESS_MAX / total);
+        }
         updateProgressBar();
     }
 
diff --git a/src/com/android/settings/display/DisplayDensityUtils.java b/src/com/android/settings/display/DisplayDensityUtils.java
index cef5418..891b7fb 100644
--- a/src/com/android/settings/display/DisplayDensityUtils.java
+++ b/src/com/android/settings/display/DisplayDensityUtils.java
@@ -116,7 +116,8 @@
         if (numSmaller > 0) {
             final float interval = (1 - minScale) / numSmaller;
             for (int i = numSmaller - 1; i >= 0; i--) {
-                final int density = (int) (normalDensity * (1 - (i + 1) * interval));
+                // Round down to a multiple of 2 by truncating the low bit.
+                final int density = ((int) (normalDensity * (1 - (i + 1) * interval))) & ~1;
                 if (currentDensity == density) {
                     currentDensityIndex = curIndex;
                 }
@@ -136,7 +137,8 @@
         if (numLarger > 0) {
             final float interval = (maxScale - 1) / numLarger;
             for (int i = 0; i < numLarger; i++) {
-                final int density = (int) (normalDensity * (1 + (i + 1) * interval));
+                // Round down to a multiple of 2 by truncating the low bit.
+                final int density = ((int) (normalDensity * (1 + (i + 1) * interval))) & ~1;
                 if (currentDensity == density) {
                     currentDensityIndex = curIndex;
                 }
diff --git a/src/com/android/settings/display/ScreenZoomSettings.java b/src/com/android/settings/display/ScreenZoomSettings.java
index 406c993..d87f230 100644
--- a/src/com/android/settings/display/ScreenZoomSettings.java
+++ b/src/com/android/settings/display/ScreenZoomSettings.java
@@ -50,7 +50,7 @@
         // This should be replaced once the final preview sample screen is in place.
         mPreviewSampleResIds = new int[]{R.layout.screen_zoom_preview_1,
                 R.layout.screen_zoom_preview_2,
-                R.layout.screen_zoom_preview_3};
+                R.layout.screen_zoom_preview_settings};
 
         final DisplayDensityUtils density = new DisplayDensityUtils(getContext());
 
diff --git a/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java b/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java
index 461c498..7aafeba 100644
--- a/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java
+++ b/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java
@@ -17,17 +17,17 @@
 package com.android.settings.fuelgauge;
 
 import android.content.Context;
-import android.content.Intent;
-import android.os.BatteryStats;
 import android.os.Bundle;
+import android.os.SystemClock;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceViewHolder;
 import android.util.AttributeSet;
-import android.view.ViewGroup;
-
+import android.widget.TextView;
 import com.android.internal.os.BatteryStatsHelper;
 import com.android.settings.R;
-import com.android.settings.SettingsActivity;
+import com.android.settings.Utils;
+import com.android.settingslib.BatteryInfo;
+import com.android.settingslib.graph.UsageView;
 
 /**
  * Custom preference for displaying power consumption as a bar and an icon on the left for the
@@ -38,73 +38,41 @@
 
     protected static final String BATTERY_HISTORY_FILE = "tmp_bat_history.bin";
 
-    private BatteryStats mStats;
-    private Intent mBatteryBroadcast;
-
-    private BatteryHistoryChart mChart;
     private BatteryStatsHelper mHelper;
+    private BatteryInfo mBatteryInfo;
 
     public BatteryHistoryPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
+        setLayoutResource(R.layout.battery_usage_graph);
     }
-    
+
     @Override
     protected void onClick() {
-        if (!isEnabled()) {
-            return;
-        }
         mHelper.storeStatsHistoryInFile(BATTERY_HISTORY_FILE);
         Bundle args = new Bundle();
         args.putString(BatteryHistoryDetail.EXTRA_STATS, BATTERY_HISTORY_FILE);
-        args.putParcelable(BatteryHistoryDetail.EXTRA_BROADCAST,
-                mHelper.getBatteryBroadcast());
-        if (getContext() instanceof SettingsActivity) {
-            SettingsActivity sa = (SettingsActivity) getContext();
-            sa.startPreferencePanel(BatteryHistoryDetail.class.getName(), args,
-                    R.string.history_details_title, null, null, 0);
-        }
+        args.putParcelable(BatteryHistoryDetail.EXTRA_BROADCAST, mHelper.getBatteryBroadcast());
+        Utils.startWithFragment(getContext(), BatteryHistoryDetail.class.getName(), args,
+                null, 0, R.string.history_details_title, null);
     }
 
     public void setStats(BatteryStatsHelper batteryStats) {
-        // Clear out the chart to receive new data.
-        mChart = null;
         mHelper = batteryStats;
-        mStats = batteryStats.getStats();
-        mBatteryBroadcast = batteryStats.getBatteryBroadcast();
-        if (getLayoutResource() != R.layout.battery_history_chart) {
-            // Now we should have some data, set the layout we want.
-            setLayoutResource(R.layout.battery_history_chart);
-        }
+        final long elapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000;
+        mBatteryInfo = BatteryInfo.getBatteryInfo(getContext(), batteryStats.getBatteryBroadcast(),
+                batteryStats.getStats(), elapsedRealtimeUs);
         notifyChanged();
     }
 
-    BatteryStats getStats() {
-        return mStats;
-    }
-
     @Override
     public void onBindViewHolder(PreferenceViewHolder view) {
-        super.onBindViewHolder(view);
-
-        if (mStats == null) {
+        if (mBatteryInfo == null) {
             return;
         }
-        BatteryHistoryChart chart = (BatteryHistoryChart) view.findViewById(
-                R.id.battery_history_chart);
-        if (mChart == null) {
-            // First time: use and initialize this chart.
-            chart.setStats(mStats, mBatteryBroadcast);
-            mChart = chart;
-        } else {
-            // All future times: forget the newly inflated chart, re-use the
-            // already initialized chart from last time.
-            ViewGroup parent = (ViewGroup) chart.getParent();
-            int index = parent.indexOfChild(chart);
-            parent.removeViewAt(index);
-            if (mChart.getParent() != null) {
-                ((ViewGroup) mChart.getParent()).removeView(mChart);
-            }
-            parent.addView(mChart, index);
-        }
+        view.setDividerAllowedAbove(true);
+        ((TextView) view.findViewById(R.id.charge)).setText(mBatteryInfo.batteryPercentString);
+        ((TextView) view.findViewById(R.id.estimation)).setText(mBatteryInfo.remainingLabel);
+        UsageView usageView = (UsageView) view.findViewById(R.id.battery_usage);
+        mBatteryInfo.bindHistory(usageView);
     }
 }
diff --git a/src/com/android/settings/fuelgauge/BatterySaverPreference.java b/src/com/android/settings/fuelgauge/BatterySaverPreference.java
new file mode 100644
index 0000000..9e0f39b
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/BatterySaverPreference.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2016 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.fuelgauge;
+
+import android.content.Context;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.provider.Settings;
+import android.provider.Settings.Global;
+import android.support.v7.preference.Preference;
+import android.util.AttributeSet;
+import android.view.View;
+import com.android.settings.R;
+import com.android.settings.Utils;
+
+public class BatterySaverPreference extends Preference {
+
+    private PowerManager mPowerManager;
+
+    public BatterySaverPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void performClick(View view) {
+        Utils.startWithFragment(getContext(), getFragment(), null, null, 0, 0, getTitle());
+    }
+
+    @Override
+    public void onAttached() {
+        super.onAttached();
+        mPowerManager = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE);
+        mObserver.onChange(true);
+        getContext().getContentResolver().registerContentObserver(
+                Settings.Global.getUriFor(Global.LOW_POWER_MODE_TRIGGER_LEVEL), true, mObserver);
+        getContext().getContentResolver().registerContentObserver(
+                Settings.Global.getUriFor(Global.LOW_POWER_MODE), true, mObserver);
+    }
+
+    @Override
+    public void onDetached() {
+        super.onDetached();
+        getContext().getContentResolver().unregisterContentObserver(mObserver);
+    }
+
+    private void updateSwitch() {
+        final Context context = getContext();
+        final boolean mode = mPowerManager.isPowerSaveMode();
+        int format = mode ? R.string.battery_saver_on_summary
+                : R.string.battery_saver_off_summary;
+        int percent = Settings.Global.getInt(context.getContentResolver(),
+                Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
+        int percentFormat = percent > 0 ? R.string.battery_saver_desc_turn_on_auto_pct
+                : R.string.battery_saver_desc_turn_on_auto_never;
+        setSummary(context.getString(format, context.getString(percentFormat,
+                Utils.formatPercentage(percent))));
+    }
+
+    private final ContentObserver mObserver = new ContentObserver(new Handler()) {
+        @Override
+        public void onChange(boolean selfChange) {
+            updateSwitch();
+        }
+    };
+
+}
diff --git a/src/com/android/settings/fuelgauge/PowerGaugePreference.java b/src/com/android/settings/fuelgauge/PowerGaugePreference.java
index 5b39a14..b0bf4b4 100644
--- a/src/com/android/settings/fuelgauge/PowerGaugePreference.java
+++ b/src/com/android/settings/fuelgauge/PowerGaugePreference.java
@@ -20,30 +20,37 @@
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.support.v7.preference.PreferenceViewHolder;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.TextView;
-
-import com.android.settings.AppProgressPreference;
+import com.android.settings.R;
+import com.android.settings.TintablePreference;
 import com.android.settings.Utils;
 
 /**
  * Custom preference for displaying power consumption as a bar and an icon on
  * the left for the subsystem/app type.
  */
-public class PowerGaugePreference extends AppProgressPreference {
+public class PowerGaugePreference extends TintablePreference {
+    private final int mIconSize;
+
     private BatteryEntry mInfo;
     private final CharSequence mContentDescription;
+    private CharSequence mProgress;
 
     public PowerGaugePreference(Context context, Drawable icon, CharSequence contentDescription,
             BatteryEntry info) {
         super(context, null);
         setIcon(icon != null ? icon : new ColorDrawable(0));
+        setWidgetLayoutResource(R.layout.preference_widget_summary);
         mInfo = info;
         mContentDescription = contentDescription;
+        mIconSize = context.getResources().getDimensionPixelSize(R.dimen.app_icon_size);
     }
 
     public void setPercent(double percentOfMax, double percentOfTotal) {
-        setProgress((int) Math.ceil(percentOfMax));
-        setSummary(Utils.formatPercentage((int) (percentOfTotal + 0.5)));
+        mProgress = Utils.formatPercentage((int) (percentOfTotal + 0.5));
+        notifyChanged();
     }
 
     BatteryEntry getInfo() {
@@ -53,7 +60,10 @@
     @Override
     public void onBindViewHolder(PreferenceViewHolder view) {
         super.onBindViewHolder(view);
+        ImageView icon = (ImageView) view.findViewById(android.R.id.icon);
+        icon.setLayoutParams(new LinearLayout.LayoutParams(mIconSize, mIconSize));
 
+        ((TextView) view.findViewById(R.id.widget_summary)).setText(mProgress);
         if (mContentDescription != null) {
             final TextView titleView = (TextView) view.findViewById(android.R.id.title);
             titleView.setContentDescription(mContentDescription);
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index d7b6849..a0d276f 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -65,7 +65,6 @@
     private static final String KEY_BATTERY_HISTORY = "battery_history";
 
     private static final int MENU_STATS_TYPE = Menu.FIRST;
-    private static final int MENU_BATTERY_SAVER = Menu.FIRST + 2;
     private static final int MENU_HIGH_POWER_APPS = Menu.FIRST + 3;
     private static final int MENU_HELP = Menu.FIRST + 4;
 
@@ -134,9 +133,6 @@
                     .setAlphabeticShortcut('t');
         }
 
-        MenuItem batterySaver = menu.add(0, MENU_BATTERY_SAVER, 0, R.string.battery_saver);
-        batterySaver.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
-
         menu.add(0, MENU_HIGH_POWER_APPS, 0, R.string.high_power_apps);
         super.onCreateOptionsMenu(menu, inflater);
     }
@@ -158,10 +154,6 @@
                 }
                 refreshStats();
                 return true;
-            case MENU_BATTERY_SAVER:
-                sa.startPreferencePanel(BatterySaverSettings.class.getName(), null,
-                        R.string.battery_saver, null, null, 0);
-                return true;
             case MENU_HIGH_POWER_APPS:
                 Bundle args = new Bundle();
                 args.putString(ManageApplications.EXTRA_CLASSNAME,
@@ -280,6 +272,7 @@
 
     protected void refreshStats() {
         super.refreshStats();
+        PowerWhitelistBackend powerWhiteist = PowerWhitelistBackend.getInstance();
         updatePreference(mHistPref);
         mAppListGroup.removeAll();
         mAppListGroup.setOrderingAsAdded(false);
@@ -352,6 +345,12 @@
                 pref.setTitle(entry.getLabel());
                 pref.setOrder(i + 1);
                 pref.setPercent(percentOfMax, percentOfTotal);
+                if (sipper.drainType == DrainType.APP) {
+                    pref.setSummary(powerWhiteist.isWhitelisted(entry.defaultPackageName)
+                            || powerWhiteist.isSysWhitelisted(entry.defaultPackageName)
+                            ? getString(R.string.not_battery_optimizing)
+                            : null);
+                }
                 if (sipper.uidObj != null) {
                     pref.setKey(Integer.toString(sipper.uidObj.getUid()));
                 }
diff --git a/src/com/android/settings/tts/TextToSpeechSettings.java b/src/com/android/settings/tts/TextToSpeechSettings.java
index 7504218..dcf50e8 100644
--- a/src/com/android/settings/tts/TextToSpeechSettings.java
+++ b/src/com/android/settings/tts/TextToSpeechSettings.java
@@ -64,6 +64,9 @@
     /** Preference key for the TTS rate selection dialog. */
     private static final String KEY_DEFAULT_RATE = "tts_default_rate";
 
+    /** Preference key for the TTS reset speech rate preference. */
+    private static final String KEY_RESET_SPEECH_RATE = "reset_speech_rate";
+
     /** Preference key for the TTS status field. */
     private static final String KEY_STATUS = "tts_status";
 
@@ -87,6 +90,7 @@
     private PreferenceCategory mEnginePreferenceCategory;
     private SeekBarPreference mDefaultRatePref;
     private SwitchPreference mHigherRateSwitchPref;
+    private Preference mResetSpeechRate;
     private Preference mPlayExample;
     private Preference mEngineStatus;
 
@@ -171,6 +175,9 @@
         mPlayExample.setOnPreferenceClickListener(this);
         mPlayExample.setEnabled(false);
 
+        mResetSpeechRate = findPreference(KEY_RESET_SPEECH_RATE);
+        mResetSpeechRate.setOnPreferenceClickListener(this);
+
         mEnginePreferenceCategory = (PreferenceCategory) findPreference(
                 KEY_ENGINE_PREFERENCE_SECTION);
         mDefaultRatePref = (SeekBarPreference) findPreference(KEY_DEFAULT_RATE);
@@ -459,24 +466,13 @@
     @Override
     public boolean onPreferenceChange(Preference preference, Object objValue) {
         if (KEY_DEFAULT_RATE.equals(preference.getKey())) {
-            // Default rate
-            mDefaultRate = ((Integer) objValue).intValue();
-            try {
-                android.provider.Settings.Secure.putInt(getContentResolver(),
-                        TTS_DEFAULT_RATE, mDefaultRate);
-                if (mTts != null) {
-                    mTts.setSpeechRate(mDefaultRate / 100.0f);
-                }
-                if (DBG) Log.d(TAG, "TTS default rate changed, now " + mDefaultRate);
-            } catch (NumberFormatException e) {
-                Log.e(TAG, "could not persist default TTS rate setting", e);
-            }
+            updateSpeechRate(((Integer) objValue).intValue());
         }
         return true;
     }
 
     /**
-     * Called when mPlayExample is clicked
+     * Called when mPlayExample or mResetSpeechRate is clicked.
      */
     @Override
     public boolean onPreferenceClick(Preference preference) {
@@ -485,11 +481,29 @@
             // the actual speaking
             speakSampleText();
             return true;
+        } else if (preference == mResetSpeechRate) {
+          mDefaultRatePref.setProgress(TextToSpeech.Engine.DEFAULT_RATE);
+          updateSpeechRate(TextToSpeech.Engine.DEFAULT_RATE);
+          return true;
         }
-
         return false;
     }
 
+    private void updateSpeechRate(int speechRate) {
+        mDefaultRate = speechRate;
+        try {
+            android.provider.Settings.Secure.putInt(getContentResolver(),
+                    TTS_DEFAULT_RATE, mDefaultRate);
+            if (mTts != null) {
+                mTts.setSpeechRate(mDefaultRate / 100.0f);
+            }
+            if (DBG) Log.d(TAG, "TTS default rate changed, now " + mDefaultRate);
+        } catch (NumberFormatException e) {
+            Log.e(TAG, "could not persist default TTS rate setting", e);
+        }
+        return;
+    }
+
     private void updateWidgetState(boolean enable) {
         mPlayExample.setEnabled(enable);
         mDefaultRatePref.setEnabled(enable);
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 6a50a6d..8ff26f7 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -104,7 +104,6 @@
     private static final String KEY_USER_ME = "user_me";
     private static final String KEY_ADD_USER = "user_add";
     private static final String KEY_EMERGENCY_INFO = "emergency_info";
-    private static final String KEY_LOCK_SCREEN_SETTINGS = "lock_screen_settings";
 
     private static final String ACTION_EDIT_EMERGENCY_INFO = "android.settings.EDIT_EMERGENGY_INFO";
 
@@ -237,14 +236,6 @@
         mLockScreenSettings = (PreferenceGroup) findPreference("lock_screen_settings");
         mAddUserWhenLocked = (RestrictedSwitchPreference) findPreference("add_users_when_locked");
         mEmergencyInfoPreference = findPreference(KEY_EMERGENCY_INFO);
-        if(emergencyInfoActivityPresent()) {
-            mEmergencyInfoPreference.setOnPreferenceClickListener(this);
-        } else {
-            // Remove this view if the emergency info package is not found.
-            PreferenceCategory lockScreenSettingsCategory =
-                    (PreferenceCategory) findPreference(KEY_LOCK_SCREEN_SETTINGS);
-            lockScreenSettingsCategory.removePreference(mEmergencyInfoPreference);
-        }
         loadProfile();
         setHasOptionsMenu(true);
         IntentFilter filter = new IntentFilter(Intent.ACTION_USER_REMOVED);
@@ -843,6 +834,12 @@
             mAddUserWhenLocked.setDisabledByAdmin(
                     mUserCaps.mDisallowAddUser ? mUserCaps.mEnforcedAdmin : null);
         }
+
+        if (emergencyInfoActivityPresent()) {
+            mEmergencyInfoPreference.setOnPreferenceClickListener(this);
+            mEmergencyInfoPreference.setOrder(Preference.DEFAULT_ORDER);
+            preferenceScreen.addPreference(mEmergencyInfoPreference);
+        }
     }
 
     private int getMaxRealUsers() {