Merge "Apply policy transparency to HotspotCondition and WiFi settings..." into nyc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 2eb2760..3ceeedf 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1558,6 +1558,7 @@
         <activity android:name="ConfirmDeviceCredentialActivity$InternalActivity"
             android:exported="false"
             android:permission="android.permission.MANAGE_USERS"
+            android:resizeableActivity="false"
             android:theme="@android:style/Theme.NoDisplay">
             <intent-filter android:priority="1">
                 <action android:name="android.app.action.CONFIRM_DEVICE_CREDENTIAL_WITH_USER" />
diff --git a/res/layout/fingerprint_enroll_finish_base.xml b/res/layout/fingerprint_enroll_finish_base.xml
index 03447b3..15ee22a 100644
--- a/res/layout/fingerprint_enroll_finish_base.xml
+++ b/res/layout/fingerprint_enroll_finish_base.xml
@@ -49,20 +49,25 @@
             android:visibility="gone" />
 
         <View
-            android:layout_height="0dp"
+            android:layout_height="24dp"
             android:layout_width="match_parent"
             android:layout_weight="1"/>
 
         <ImageView
             android:id="@+id/fingerprint_in_app_indicator"
-            android:layout_width="@dimen/fingerprint_in_app_indicator_size"
-            android:layout_height="@dimen/fingerprint_in_app_indicator_size"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:layout_weight="5"
+            android:minHeight="@dimen/fingerprint_in_app_indicator_min_size"
+            android:minWidth="@dimen/fingerprint_in_app_indicator_min_size"
+            android:maxHeight="@dimen/fingerprint_in_app_indicator_max_size"
+            android:maxWidth="@dimen/fingerprint_in_app_indicator_max_size"
             android:layout_gravity="center_horizontal"
             android:contentDescription="@android:string/fingerprint_icon_content_description"
             android:src="@drawable/fp_app_indicator" />
 
         <View
-            android:layout_height="0dp"
+            android:layout_height="24dp"
             android:layout_width="match_parent"
             android:layout_weight="1"/>
 
diff --git a/res/layout/preference_importance_slider.xml b/res/layout/preference_importance_slider.xml
index 677a32b..dc7c9db 100644
--- a/res/layout/preference_importance_slider.xml
+++ b/res/layout/preference_importance_slider.xml
@@ -15,47 +15,64 @@
 -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:minHeight="?android:attr/listPreferredItemHeight"
-        android:gravity="center_vertical"
-        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-        android:orientation="vertical"
-        android:clickable="false"
-        android:focusable="false" >
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:minHeight="?android:attr/listPreferredItemHeight"
+              android:gravity="center_vertical"
+              android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+              android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+              android:paddingTop="8dp"
+              android:paddingBottom="8dp"
+              android:orientation="vertical"
+              android:clickable="false"
+              android:focusable="false" >
 
-        <FrameLayout
+    <TextView
+            android:id="@android:id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:singleLine="true"
+            android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+            android:textColor="?android:attr/textColorPrimary"
+            android:ellipsize="marquee"
+            android:fadingEdge="horizontal" />
+
+    <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" >
+
+        <ImageView
+                android:id="@+id/auto_importance"
+                android:src="@drawable/notification_auto_importance"
+                android:layout_gravity="center_vertical|start"
+                android:layout_width="48dp"
+                android:layout_height="48dp" />
+
+        <SeekBar
+                android:id="@*android:id/seekbar"
+                android:layout_marginStart="56dp"
+                android:layout_marginEnd="32dp"
+                android:layout_gravity="center_vertical"
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content" >
+                android:layout_height="48dp"
+                android:focusable="true"
+                android:background="#00ffffff"
+                android:progressBackgroundTint="@color/importance_secondary_slider_color"
+                android:thumbTint="@color/importance_disabled_slider_color"
+                android:progressTint="@color/importance_disabled_slider_color"
+                style="@android:style/Widget.Material.SeekBar.Discrete"
+                android:tickMarkTint="@android:color/black" />
 
-            <ImageView
-                    android:id="@+id/low_importance"
-                    android:src="@*android:drawable/ic_notification_block"
-                    android:layout_gravity="center_vertical|start"
-                    android:layout_width="24dp"
-                    android:layout_height="24dp"
-                    android:tint="@color/importance_icon_tint" />
+    </FrameLayout>
 
-            <SeekBar
-                    android:id="@*android:id/seekbar"
-                    android:layout_marginStart="56dp"
-                    android:layout_marginEnd="56dp"
-                    android:layout_gravity="center_vertical"
-                    android:layout_width="match_parent"
-                    android:layout_height="48dp"
-                    android:focusable="true"
-                    android:background="#00ffffff"
-                    style="@android:style/Widget.Material.SeekBar.Discrete"
-                    android:tickMarkTint="@android:color/black"/>
-
-            <ImageView
-                    android:id="@+id/max_importance"
-                    android:src="@*android:drawable/ic_notification_alert"
-                    android:layout_gravity="center_vertical|end"
-                    android:layout_width="24dp"
-                    android:layout_height="24dp"
-                    android:tint="@color/importance_icon_tint" />
-
-        </FrameLayout>
+    <TextView
+            android:id="@android:id/summary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignStart="@android:id/title"
+            android:textAlignment="viewStart"
+            android:textAppearance="@android:style/TextAppearance.Material.Body1"
+            android:textColor="?android:attr/textColorSecondary"
+            android:maxLines="10"
+            android:minLines="3" />
 </LinearLayout>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 89b2d15..a9756ad 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -125,6 +125,10 @@
 
     <color name="seek_bar_preference_preview_text">#fff</color>
 
+    <color name="importance_slider_color">@*android:color/material_deep_teal_500</color>
+    <color name="importance_disabled_slider_color">@*android:color/material_grey_300</color>
+    <color name="importance_secondary_slider_color">#858383</color>
+
     <color name="usage_graph_dots">#B0BEC5</color>
 
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 0ddb5d8..eb06105 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -228,7 +228,9 @@
     <dimen name="fingerprint_animation_size">88dp</dimen>
     <dimen name="fingerprint_progress_bar_size">192dp</dimen>
     <dimen name="fingerprint_enrolling_content_margin_top">36dp</dimen>
-    <dimen name="fingerprint_in_app_indicator_size">120dp</dimen>
+    <dimen name="fingerprint_in_app_indicator_size">124dp</dimen>
+    <dimen name="fingerprint_in_app_indicator_min_size">124dp</dimen>
+    <dimen name="fingerprint_in_app_indicator_max_size">264dp</dimen>
 
     <dimen name="setup_fingerprint_ring_radius">80dip</dimen>
     <dimen name="setup_fingerprint_progress_bar_size">168dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2675e15..3eb6d3d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5979,22 +5979,25 @@
     <string name="notification_importance_none">Not set</string>
 
     <!-- [CHAR LIMIT=100] Notification Importance slider: blocked importance level description -->
-    <string name="notification_importance_blocked">Blocked: Never show these notifications</string>
+    <string name="notification_importance_blocked">Never show notifications from this app</string>
 
     <!-- [CHAR LIMIT=100] Notification Importance slider: min importance level description -->
-    <string name="notification_importance_min">Min: Silently show at the bottom of the notification list</string>
+    <string name="notification_importance_min">No full screen interruption, peeking, sound, or vibration. Show at the bottom of the notification list. Hide from lock screen and status bar.</string>
 
     <!-- [CHAR LIMIT=100] Notification Importance slider: low importance level description -->
-    <string name="notification_importance_low">Low: Silently show these notifications</string>
+    <string name="notification_importance_low">No full screen interruption, peeking, sound, or vibration.</string>
 
     <!-- [CHAR LIMIT=100] Notification Importance slider: normal importance level description -->
-    <string name="notification_importance_default">Normal: Allow these notification to make sounds</string>
+    <string name="notification_importance_default">No full screen interruption or peeking.</string>
 
     <!-- [CHAR LIMIT=100] Notification Importance slider: high importance level description -->
-    <string name="notification_importance_high">High: Peek onto the screen and allow sound</string>
+    <string name="notification_importance_high">Always peek. No full screen interruption.</string>
 
     <!-- [CHAR LIMIT=100] Notification Importance slider: max importance level description -->
-    <string name="notification_importance_max">Urgent: Show at the top of the notifications list, peek onto the screen and allow sound</string>
+    <string name="notification_importance_max">Always peek, and allow full screen interruption. Show at the top of the notification list.</string>
+
+    <!-- [CHAR LIMIT=100] Notification Importance slider: max importance level description -->
+    <string name="notification_importance_unspecified">App determines importance for each notification</string>
 
     <!-- [CHAR LIMIT=60] Notification importance reset button -->
     <string name="importance_reset">Reset</string>
@@ -6486,6 +6489,8 @@
     <string name="notifications_priority">Do Not Disturb overridden</string>
     <!-- App notification summary divider [CHAR LIMIT=40] -->
     <string name="notifications_summary_divider">\u00A0/\u00A0</string>
+    <!-- App notification summary for advanced controls -->
+    <string name="notification_summary_level">Level %d</string>
 
    <!-- Permissions preference summary [CHAR LIMIT=40] -->
    <plurals name="permissions_summary">
@@ -7238,6 +7243,9 @@
     <!-- Button that leads to list of apps with unrestricted data access [CHAR LIMIT=60] -->
     <string name="unrestricted_data_saver">Unrestricted data access</string>
 
+    <!-- Description of message shown when app is blacklisted for background data access [CHAR LIMIT=NONE] -->
+    <string name="restrict_background_blacklisted">Background data is turned off</string>
+
     <!-- Summary for the Data Saver feature being on [CHAR LIMIT=NONE] -->
     <string name="data_saver_on">On</string>
 
diff --git a/res/xml/app_notification_settings.xml b/res/xml/app_notification_settings.xml
index 8bd0c88..fd2f33e 100644
--- a/res/xml/app_notification_settings.xml
+++ b/res/xml/app_notification_settings.xml
@@ -32,30 +32,22 @@
             android:summary="@string/show_silently_summary"
             android:order="3" />
     <!-- Slider -->
-    <com.android.settingslib.RestrictedPreference
-            android:key="importance_title"
-            android:title="@string/notification_importance_title"
-            android:order="4"/>
     <com.android.settings.notification.ImportanceSeekBarPreference
             android:key="importance"
-            android:order="5"/>
-
-    <com.android.settings.applications.LayoutPreference
-            android:key="importance_reset_button"
-            android:layout="@layout/two_buttons_panel"
-            android:order="6" />
+            android:title="@string/notification_importance_title"
+            android:order="4"/>
 
     <!-- Visibility Override -->
     <DropDownPreference
             android:key="visibility_override"
             android:title="@string/app_notification_visibility_override_title"
-            android:order="7" />
+            android:order="5" />
 
     <!-- Bypass DND -->
     <com.android.settingslib.RestrictedSwitchPreference
             android:key="bypass_dnd"
             android:title="@string/app_notification_override_dnd_title"
             android:summary="@string/app_notification_override_dnd_summary"
-            android:order="8" />
+            android:order="6" />
 
 </PreferenceScreen>
diff --git a/res/xml/tts_settings.xml b/res/xml/tts_settings.xml
index 05ed6e7..ab57649 100644
--- a/res/xml/tts_settings.xml
+++ b/res/xml/tts_settings.xml
@@ -47,6 +47,11 @@
             android:title="@string/tts_reset_speech_rate_title"
             android:summary="@string/tts_reset_speech_rate_summary" />
 
+        <Preference android:key="reset_speech_pitch"
+            android:persistent="false"
+            android:title="@string/tts_reset_speech_pitch_title"
+            android:summary="@string/tts_reset_speech_pitch_summary" />
+
         <Preference android:key="tts_play_example"
             android:persistent="false"
             android:title="@string/tts_play_example_title"
diff --git a/src/com/android/settings/ConfirmLockPassword.java b/src/com/android/settings/ConfirmLockPassword.java
index ca4be6c..a1bc3dd 100644
--- a/src/com/android/settings/ConfirmLockPassword.java
+++ b/src/com/android/settings/ConfirmLockPassword.java
@@ -267,6 +267,11 @@
                 handleAttemptLockout(deadline);
             } else {
                 resetState();
+                mErrorTextView.setText("");
+                if (isProfileChallenge()) {
+                    updateErrorMessage(mLockPatternUtils.getCurrentFailedPasswordAttempts(
+                            mEffectiveUserId));
+                }
             }
             mCredentialCheckResultTracker.setListener(this);
         }
diff --git a/src/com/android/settings/DeviceAdminAdd.java b/src/com/android/settings/DeviceAdminAdd.java
index ddee6aa..9d4d895 100644
--- a/src/com/android/settings/DeviceAdminAdd.java
+++ b/src/com/android/settings/DeviceAdminAdd.java
@@ -245,6 +245,12 @@
         if (DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN.equals(getIntent().getAction())) {
             mRefreshing = false;
             if (mDPM.isAdminActive(who)) {
+                if (mDPM.isRemovingAdmin(who, android.os.Process.myUserHandle().getIdentifier())) {
+                    Log.w(TAG, "Requested admin is already being removed: " + who);
+                    finish();
+                    return;
+                }
+
                 ArrayList<DeviceAdminInfo.PolicyInfo> newPolicies = mDeviceAdmin.getUsedPolicies();
                 for (int i = 0; i < newPolicies.size(); i++) {
                     DeviceAdminInfo.PolicyInfo pi = newPolicies.get(i);
diff --git a/src/com/android/settings/PreviewPagerAdapter.java b/src/com/android/settings/PreviewPagerAdapter.java
index 20d1761..7e4ebf3 100644
--- a/src/com/android/settings/PreviewPagerAdapter.java
+++ b/src/com/android/settings/PreviewPagerAdapter.java
@@ -45,19 +45,23 @@
     /** Interpolator to use when cross-fading between previews. */
     private static final Interpolator FADE_OUT_INTERPOLATOR = new AccelerateInterpolator();
 
-    private final FrameLayout[] mPreviewFrames;
+    private FrameLayout[] mPreviewFrames;
+
+    private boolean mIsLayoutRtl;
 
     private Runnable mAnimationEndAction;
 
     private int mAnimationCounter;
 
-    public PreviewPagerAdapter(Context context, int[] previewSampleResIds,
-                               Configuration[] configurations) {
+    public PreviewPagerAdapter(Context context, boolean isLayoutRtl,
+            int[] previewSampleResIds, Configuration[] configurations) {
+        mIsLayoutRtl = isLayoutRtl;
         mPreviewFrames = new FrameLayout[previewSampleResIds.length];
 
         for (int i = 0; i < previewSampleResIds.length; ++i) {
-            mPreviewFrames[i] = new FrameLayout(context);
-            mPreviewFrames[i].setLayoutParams(new LinearLayout.LayoutParams(
+            int p = mIsLayoutRtl ? previewSampleResIds.length - 1 - i : i;
+            mPreviewFrames[p] = new FrameLayout(context);
+            mPreviewFrames[p].setLayoutParams(new LinearLayout.LayoutParams(
                     LinearLayout.LayoutParams.MATCH_PARENT,
                     LinearLayout.LayoutParams.MATCH_PARENT));
 
@@ -69,10 +73,10 @@
 
                 final LayoutInflater configInflater = LayoutInflater.from(configContext);
                 final View sampleView = configInflater.inflate(previewSampleResIds[i],
-                        mPreviewFrames[i], false);
+                        mPreviewFrames[p], false);
                 sampleView.setAlpha(0);
                 sampleView.setVisibility(View.INVISIBLE);
-                mPreviewFrames[i].addView(sampleView);
+                mPreviewFrames[p].addView(sampleView);
             }
         }
     }
diff --git a/src/com/android/settings/PreviewSeekBarPreferenceFragment.java b/src/com/android/settings/PreviewSeekBarPreferenceFragment.java
index a7763f7..ff9e035 100644
--- a/src/com/android/settings/PreviewSeekBarPreferenceFragment.java
+++ b/src/com/android/settings/PreviewSeekBarPreferenceFragment.java
@@ -21,6 +21,7 @@
 import android.os.Bundle;
 import android.support.v4.view.ViewPager;
 import android.support.v4.view.ViewPager.OnPageChangeListener;
+import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -29,9 +30,11 @@
 import android.widget.SeekBar;
 import android.widget.SeekBar.OnSeekBarChangeListener;
 import android.widget.TextView;
+
 import com.android.settings.widget.DotsPageIndicator;
 import com.android.settings.widget.LabeledSeekBar;
 
+import java.util.Locale;
 
 /**
  * Preference fragment shows a preview and a seek bar to adjust a specific settings.
@@ -146,6 +149,7 @@
 
         final Context context = getPrefContext();
         final Configuration origConfig = context.getResources().getConfiguration();
+        final boolean isLayoutRtl = origConfig.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
         Configuration[] configurations = new Configuration[mEntries.length];
         for (int i = 0; i < mEntries.length; ++i) {
             configurations[i] = createConfig(origConfig, i);
@@ -153,9 +157,10 @@
 
         mPreviewPager = (ViewPager) content.findViewById(R.id.preview_pager);
         if (mPreviewPager != null) {
-            mPreviewPagerAdapter = new PreviewPagerAdapter(context, mPreviewSampleResIds,
-                    configurations);
+            mPreviewPagerAdapter = new PreviewPagerAdapter(context, isLayoutRtl,
+                    mPreviewSampleResIds, configurations);
             mPreviewPager.setAdapter(mPreviewPagerAdapter);
+            mPreviewPager.setCurrentItem(isLayoutRtl ? mPreviewSampleResIds.length - 1 : 0);
             mPreviewPager.addOnPageChangeListener(mPreviewPageChangeListener);
 
             mPageIndicator = (DotsPageIndicator) content.findViewById(R.id.page_indicator);
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 6b9bdb3..53c97b5 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -564,12 +564,7 @@
             // Run the Index update only if we have some space
             if (!Utils.isLowStorage(this)) {
                 long indexStartTime = System.currentTimeMillis();
-                AsyncTask.execute(new Runnable() {
-                    @Override
-                    public void run() {
-                        Index.getInstance(getApplicationContext()).update();
-                    }
-                });
+                Index.getInstance(getApplicationContext()).update();
                 if (DEBUG_TIMING) Log.d(LOG_TAG, "Index.update() took "
                         + (System.currentTimeMillis() - indexStartTime) + " ms");
             } else {
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 46a3d9b..e439bed 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -347,11 +347,12 @@
         // If there's no profile photo, assign a default avatar
         if (avatarDataStream == null) {
             assignDefaultPhoto(context, userId);
-        } else {
-            UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
-            Bitmap icon = BitmapFactory.decodeStream(avatarDataStream);
-            um.setUserIcon(userId, icon);
+            return;
         }
+
+        UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        Bitmap icon = BitmapFactory.decodeStream(avatarDataStream);
+        um.setUserIcon(userId, icon);
         try {
             avatarDataStream.close();
         } catch (IOException ioe) { }
diff --git a/src/com/android/settings/accounts/AccountSettings.java b/src/com/android/settings/accounts/AccountSettings.java
index 927ad23..852d33a 100644
--- a/src/com/android/settings/accounts/AccountSettings.java
+++ b/src/com/android/settings/accounts/AccountSettings.java
@@ -251,7 +251,11 @@
             ProfileData profileData = mProfiles.valueAt(i);
             if (preference == profileData.workModeSwitch) {
                 final int userId = profileData.userInfo.id;
-                mUm.setQuietModeEnabled(userId, !((boolean) newValue));
+                if ((boolean) newValue) {
+                    mUm.trySetQuietModeDisabled(userId, null);
+                } else {
+                    mUm.setQuietModeEnabled(userId, true);
+                }
                 return true;
             }
         }
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
index 035b504..3679699 100755
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -51,7 +51,9 @@
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
+import android.service.notification.NotificationListenerService.Ranking;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.Preference.OnPreferenceClickListener;
 import android.support.v7.preference.PreferenceCategory;
@@ -71,6 +73,7 @@
 import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;
+
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.internal.os.BatterySipper;
 import com.android.internal.os.BatteryStatsHelper;
@@ -79,6 +82,7 @@
 import com.android.settings.DeviceAdminAdd;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
+import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.Utils;
 import com.android.settings.applications.PermissionsSummaryHelper.PermissionsResultCallback;
 import com.android.settings.datausage.AppDataUsage;
@@ -144,6 +148,8 @@
     private static final String KEY_BATTERY = "battery";
     private static final String KEY_MEMORY = "memory";
 
+    private static final String NOTIFICATION_TUNER_SETTING = "show_importance_slider";
+
     private final HashSet<String> mHomePackages = new HashSet<String>();
 
     private boolean mInitialized;
@@ -737,14 +743,19 @@
     }
 
     private void startAppInfoFragment(Class<?> fragment, CharSequence title) {
+        startAppInfoFragment(fragment, title, this, mAppEntry);
+    }
+
+    public static void startAppInfoFragment(Class<?> fragment, CharSequence title,
+            SettingsPreferenceFragment caller, AppEntry appEntry) {
         // start new fragment to display extended information
         Bundle args = new Bundle();
-        args.putString(ARG_PACKAGE_NAME, mAppEntry.info.packageName);
-        args.putInt(ARG_PACKAGE_UID, mAppEntry.info.uid);
+        args.putString(ARG_PACKAGE_NAME, appEntry.info.packageName);
+        args.putInt(ARG_PACKAGE_UID, appEntry.info.uid);
         args.putBoolean(AppHeader.EXTRA_HIDE_INFO_BUTTON, true);
 
-        SettingsActivity sa = (SettingsActivity) getActivity();
-        sa.startPreferencePanel(fragment.getName(), args, -1, title, this, SUB_INFO_FRAGMENT);
+        SettingsActivity sa = (SettingsActivity) caller.getActivity();
+        sa.startPreferencePanel(fragment.getName(), args, -1, title, caller, SUB_INFO_FRAGMENT);
     }
 
     /*
@@ -1016,13 +1027,22 @@
     }
 
     public static CharSequence getNotificationSummary(AppRow appRow, Context context) {
+        boolean showSlider = Settings.Secure.getInt(
+                context.getContentResolver(), NOTIFICATION_TUNER_SETTING, 0) == 1;
         List<String> summaryAttributes = new ArrayList<>();
         StringBuffer summary = new StringBuffer();
-        if (appRow.banned) {
-            summaryAttributes.add(context.getString(R.string.notifications_disabled));
-        } else if (appRow.appImportance > NotificationListenerService.Ranking.IMPORTANCE_NONE
-                && appRow.appImportance < NotificationListenerService.Ranking.IMPORTANCE_DEFAULT) {
-            summaryAttributes.add(context.getString(R.string.notifications_silenced));
+        if (showSlider) {
+            if (appRow.appImportance != Ranking.IMPORTANCE_UNSPECIFIED) {
+                summaryAttributes.add(context.getString(
+                        R.string.notification_summary_level, appRow.appImportance));
+            }
+        } else {
+            if (appRow.banned) {
+                summaryAttributes.add(context.getString(R.string.notifications_disabled));
+            } else if (appRow.appImportance > Ranking.IMPORTANCE_NONE
+                    && appRow.appImportance < Ranking.IMPORTANCE_DEFAULT) {
+                summaryAttributes.add(context.getString(R.string.notifications_silenced));
+            }
         }
         final boolean lockscreenSecure = new LockPatternUtils(context).isSecure(
                 UserHandle.myUserId());
diff --git a/src/com/android/settings/dashboard/conditional/WorkModeCondition.java b/src/com/android/settings/dashboard/conditional/WorkModeCondition.java
index f46b495..3d9958b 100644
--- a/src/com/android/settings/dashboard/conditional/WorkModeCondition.java
+++ b/src/com/android/settings/dashboard/conditional/WorkModeCondition.java
@@ -90,7 +90,7 @@
     @Override
     public void onActionClick(int index) {
         if (index == 0) {
-            mUm.setQuietModeEnabled(mUserHandle.getIdentifier(), false);
+            mUm.trySetQuietModeDisabled(mUserHandle.getIdentifier(), null);
             setActive(false);
         } else {
             throw new IllegalArgumentException("Unexpected index " + index);
diff --git a/src/com/android/settings/datausage/AppDataUsage.java b/src/com/android/settings/datausage/AppDataUsage.java
index 701b8c4..037614e 100644
--- a/src/com/android/settings/datausage/AppDataUsage.java
+++ b/src/com/android/settings/datausage/AppDataUsage.java
@@ -39,6 +39,8 @@
 import android.util.ArraySet;
 import android.view.View;
 import android.widget.AdapterView;
+
+import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.settings.AppHeader;
 import com.android.settings.R;
@@ -78,6 +80,7 @@
 
     private Drawable mIcon;
     private CharSequence mLabel;
+    private String mPackageName;
     private INetworkStatsSession mStatsSession;
     private CycleAdapter mCycleAdapter;
 
@@ -143,6 +146,7 @@
                     ApplicationInfo info = pm.getApplicationInfo(mPackages.valueAt(0), 0);
                     mIcon = info.loadIcon(pm);
                     mLabel = info.loadLabel(pm);
+                    mPackageName = info.packageName;
                 } catch (PackageManager.NameNotFoundException e) {
                 }
             }
@@ -186,6 +190,7 @@
             final PackageManager pm = getPackageManager();
             mIcon = Utils.getUserIcon(getActivity(), um, info);
             mLabel = Utils.getUserLabel(getActivity(), info);
+            mPackageName = getActivity().getPackageName();
             removePreference(KEY_UNRESTRICTED_DATA);
             removePreference(KEY_APP_SETTINGS);
             removePreference(KEY_RESTRICT_BACKGROUND);
@@ -211,10 +216,11 @@
     @Override
     public boolean onPreferenceChange(Preference preference, Object newValue) {
         if (preference == mRestrictBackground) {
-            setAppRestrictBackground(!(Boolean) newValue);
+            mDataSaverBackend.setIsBlacklisted(mAppItem.key, mPackageName, !(Boolean) newValue);
+            updatePrefs();        // TODO: should have been notified by NPMS instead
             return true;
         } else if (preference == mUnrestrictedData) {
-            mDataSaverBackend.setIsWhitelisted(mAppItem.key, (Boolean) newValue);
+            mDataSaverBackend.setIsWhitelisted(mAppItem.key, mPackageName, (Boolean) newValue);
             return true;
         }
         return false;
@@ -282,13 +288,6 @@
         return (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
     }
 
-    private void setAppRestrictBackground(boolean restrictBackground) {
-        final int uid = mAppItem.key;
-        services.mPolicyManager.setUidPolicy(
-                uid, restrictBackground ? POLICY_REJECT_METERED_BACKGROUND : POLICY_NONE);
-        updatePrefs();        // TODO: should have been notified by NPMS instead
-    }
-
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
diff --git a/src/com/android/settings/datausage/AppStateDataUsageBridge.java b/src/com/android/settings/datausage/AppStateDataUsageBridge.java
index 1aff496..0b535d0 100644
--- a/src/com/android/settings/datausage/AppStateDataUsageBridge.java
+++ b/src/com/android/settings/datausage/AppStateDataUsageBridge.java
@@ -37,20 +37,24 @@
         final int N = apps.size();
         for (int i = 0; i < N; i++) {
             AppEntry app = apps.get(i);
-            app.extraInfo = new DataUsageState(mDataSaverBackend.isWhitelisted(app.info.uid));
+            app.extraInfo = new DataUsageState(mDataSaverBackend.isWhitelisted(app.info.uid),
+                    mDataSaverBackend.isBlacklisted(app.info.uid));
         }
     }
 
     @Override
     protected void updateExtraInfo(AppEntry app, String pkg, int uid) {
-        app.extraInfo = new DataUsageState(mDataSaverBackend.isWhitelisted(uid));
+        app.extraInfo = new DataUsageState(mDataSaverBackend.isWhitelisted(uid),
+                mDataSaverBackend.isBlacklisted(uid));
     }
 
     public static class DataUsageState {
         public boolean isDataSaverWhitelisted;
+        public boolean isDataSaverBlacklisted;
 
-        public DataUsageState(boolean isDataSaverWhitelisted) {
+        public DataUsageState(boolean isDataSaverWhitelisted, boolean isDataSaverBlacklisted) {
             this.isDataSaverWhitelisted = isDataSaverWhitelisted;
+            this.isDataSaverBlacklisted = isDataSaverBlacklisted;
         }
     }
 }
diff --git a/src/com/android/settings/datausage/DataSaverBackend.java b/src/com/android/settings/datausage/DataSaverBackend.java
index c38a05c..55521a8 100644
--- a/src/com/android/settings/datausage/DataSaverBackend.java
+++ b/src/com/android/settings/datausage/DataSaverBackend.java
@@ -24,8 +24,14 @@
 import android.util.Log;
 import android.util.SparseBooleanArray;
 
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
+
 import java.util.ArrayList;
 
+import static android.net.NetworkPolicyManager.POLICY_NONE;
+import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
+
 public class DataSaverBackend {
 
     private static final String TAG = "DataSaverBackend";
@@ -37,6 +43,7 @@
     private final INetworkPolicyManager mIPolicyManager;
     private final ArrayList<Listener> mListeners = new ArrayList<>();
     private SparseBooleanArray mWhitelist;
+    private SparseBooleanArray mBlacklist;
 
     // TODO: Staticize into only one.
     public DataSaverBackend(Context context) {
@@ -67,13 +74,14 @@
 
     public void setDataSaverEnabled(boolean enabled) {
         mPolicyManager.setRestrictBackground(enabled);
+        MetricsLogger.action(mContext, MetricsEvent.ACTION_DATA_SAVER_MODE, enabled ? 1 : 0);
     }
 
     public void refreshWhitelist() {
         loadWhitelist();
     }
 
-    public void setIsWhitelisted(int uid, boolean whitelisted) {
+    public void setIsWhitelisted(int uid, String packageName, boolean whitelisted) {
         mWhitelist.put(uid, whitelisted);
         try {
             if (whitelisted) {
@@ -84,6 +92,7 @@
         } catch (RemoteException e) {
             Log.w(TAG, "Can't reach policy manager", e);
         }
+        MetricsLogger.action(mContext, MetricsEvent.ACTION_DATA_SAVER_WHITELIST, packageName);
     }
 
     public boolean isWhitelisted(int uid) {
@@ -116,6 +125,35 @@
         }
     }
 
+    public void refreshBlacklist() {
+        loadBlacklist();
+    }
+
+    public void setIsBlacklisted(int uid, String packageName, boolean blacklisted) {
+        mPolicyManager.setUidPolicy(
+                uid, blacklisted ? POLICY_REJECT_METERED_BACKGROUND : POLICY_NONE);
+        if (blacklisted) {
+            MetricsLogger.action(mContext, MetricsEvent.ACTION_DATA_SAVER_BLACKLIST, packageName);
+        }
+    }
+
+    public boolean isBlacklisted(int uid) {
+        if (mBlacklist == null) {
+            loadBlacklist();
+        }
+        return mBlacklist.get(uid);
+    }
+
+    private void loadBlacklist() {
+        mBlacklist = new SparseBooleanArray();
+        try {
+            for (int uid : mIPolicyManager.getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) {
+                mBlacklist.put(uid, true);
+            }
+        } catch (RemoteException e) {
+        }
+    }
+
     private void handleRestrictBackgroundChanged(boolean isDataSaving) {
         for (int i = 0; i < mListeners.size(); i++) {
             mListeners.get(i).onDataSaverChanged(isDataSaving);
@@ -124,7 +162,8 @@
 
     private final INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() {
         @Override
-        public void onUidRulesChanged(int i, int i1) throws RemoteException {
+        public void onUidRulesChanged(int uid, int uidRules) throws RemoteException {
+            // TODO: update UI accordingly
         }
 
         @Override
diff --git a/src/com/android/settings/datausage/DataSaverSummary.java b/src/com/android/settings/datausage/DataSaverSummary.java
index e8c8cdd..591f2c5 100644
--- a/src/com/android/settings/datausage/DataSaverSummary.java
+++ b/src/com/android/settings/datausage/DataSaverSummary.java
@@ -70,6 +70,7 @@
     public void onResume() {
         super.onResume();
         mDataSaverBackend.refreshWhitelist();
+        mDataSaverBackend.refreshBlacklist();
         mDataSaverBackend.addListener(this);
         mSession.resume();
         mDataUsageBridge.resume();
diff --git a/src/com/android/settings/datausage/UnrestrictedDataAccess.java b/src/com/android/settings/datausage/UnrestrictedDataAccess.java
index c9014c0..c8df0ba 100644
--- a/src/com/android/settings/datausage/UnrestrictedDataAccess.java
+++ b/src/com/android/settings/datausage/UnrestrictedDataAccess.java
@@ -24,10 +24,15 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
+
 import com.android.internal.logging.MetricsProto.MetricsEvent;
+import com.android.settings.AppHeader;
 import com.android.settings.R;
+import com.android.settings.SettingsActivity;
 import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.applications.AppInfoBase;
 import com.android.settings.applications.AppStateBaseBridge;
+import com.android.settings.applications.InstalledAppDetails;
 import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.applications.ApplicationsState.AppEntry;
@@ -40,6 +45,7 @@
 
     private static final int MENU_SHOW_SYSTEM = Menu.FIRST + 42;
     private static final String EXTRA_SHOW_SYSTEM = "show_system";
+
     private ApplicationsState mApplicationsState;
     private AppStateDataUsageBridge mDataUsageBridge;
     private ApplicationsState.Session mSession;
@@ -144,11 +150,11 @@
     }
 
     @Override
-    public void onRebuildComplete(ArrayList<ApplicationsState.AppEntry> apps) {
+    public void onRebuildComplete(ArrayList<AppEntry> apps) {
         cacheRemoveAllPrefs(getPreferenceScreen());
         final int N = apps.size();
         for (int i = 0; i < N; i++) {
-            ApplicationsState.AppEntry entry = apps.get(i);
+            AppEntry entry = apps.get(i);
             String key = entry.info.packageName + "|" + entry.info.uid;
             AccessPreference preference = (AccessPreference) getCachedPreference(key);
             if (preference == null) {
@@ -200,33 +206,62 @@
         if (preference instanceof AccessPreference) {
             AccessPreference accessPreference = (AccessPreference) preference;
             boolean whitelisted = newValue == Boolean.TRUE;
-            mDataSaverBackend.setIsWhitelisted(accessPreference.mEntry.info.uid, whitelisted);
-            ((AppStateDataUsageBridge.DataUsageState) accessPreference.mEntry.extraInfo)
-                    .isDataSaverWhitelisted = whitelisted;
+            mDataSaverBackend.setIsWhitelisted(accessPreference.mEntry.info.uid,
+                    accessPreference.mEntry.info.packageName, whitelisted);
+            accessPreference.mState.isDataSaverWhitelisted = whitelisted;
             return true;
         }
         return false;
     }
 
     private class AccessPreference extends SwitchPreference {
-        private final ApplicationsState.AppEntry mEntry;
+        private final AppEntry mEntry;
+        private final DataUsageState mState;
 
-        public AccessPreference(Context context, ApplicationsState.AppEntry entry) {
+        public AccessPreference(final Context context, AppEntry entry) {
             super(context);
             mEntry = entry;
+            mState = (DataUsageState) mEntry.extraInfo;
             mEntry.ensureLabel(getContext());
-            setTitle(entry.label);
-            final DataUsageState state = (DataUsageState) entry.extraInfo;
-            setChecked(state != null && state.isDataSaverWhitelisted);
+            setState();
             if (mEntry.icon != null) {
                 setIcon(mEntry.icon);
             }
+            setOnPreferenceClickListener( new OnPreferenceClickListener() {
+
+                @Override
+                public boolean onPreferenceClick(Preference pref) {
+                    if (mState.isDataSaverBlacklisted) {
+                        InstalledAppDetails.startAppInfoFragment(AppDataUsage.class,
+                                context.getString(R.string.app_data_usage),
+                                UnrestrictedDataAccess.this,
+                                mEntry);
+                        return false;
+                    }
+                    return true;
+                }});
+        }
+
+        // Sets UI state based on whitelist/blacklist status.
+        private void setState() {
+            setTitle(mEntry.label);
+            // TODO: state is cached, so if blacklist/whitelist changes, it's not updated.
+            // For example, if the initial state is blacklisted, the user taps the preference,
+            // removes the blacklist, and then taps back, the state is not refreshed.
+            // The proper fix for this problem is to implement onUidRulesChanged() on
+            // DataSaverBackend and update the UI accordingly.
+            if (mState != null) {
+                setChecked(mState.isDataSaverWhitelisted);
+                if (mState.isDataSaverBlacklisted) {
+                    setSummary(R.string.restrict_background_blacklisted);
+                }
+                // TODO: might need to reset summary once it listens to onUidRulesChanged()
+            }
         }
 
         public void reuse() {
-            setTitle(mEntry.label);
-            final DataUsageState state = (DataUsageState) mEntry.extraInfo;
-            setChecked(state != null && state.isDataSaverWhitelisted);
+            setState();
+            notifyChanged();
         }
 
         @Override
@@ -243,7 +278,10 @@
                     }
                 });
             }
+            holder.findViewById(android.R.id.widget_frame)
+                    .setVisibility(mState.isDataSaverBlacklisted ? View.INVISIBLE : View.VISIBLE);
             super.onBindViewHolder(holder);
         }
     }
+
 }
diff --git a/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java b/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
index 1de3fcc..d35f895 100644
--- a/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
+++ b/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
@@ -16,9 +16,15 @@
 
 package com.android.settings.inputmethod;
 
+import android.annotation.DrawableRes;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
 import android.content.res.Configuration;
 import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
@@ -40,8 +46,6 @@
 public final class AvailableVirtualKeyboardFragment extends SettingsPreferenceFragment
         implements InputMethodPreference.OnSavePreferenceListener {
 
-    private static final Drawable NO_ICON = new ColorDrawable(Color.TRANSPARENT);
-
     private final ArrayList<InputMethodPreference> mInputMethodPreferenceList = new ArrayList<>();
     private InputMethodSettingValuesWrapper mInputMethodSettingValues;
     private InputMethodManager mImm;
@@ -85,27 +89,68 @@
         return MetricsEvent.ENABLE_VIRTUAL_KEYBOARDS;
     }
 
+    @Nullable
+    private static Drawable loadDrawable(@NonNull final PackageManager packageManager,
+            @NonNull final String packageName, @DrawableRes final int resId,
+            @NonNull final ApplicationInfo applicationInfo) {
+        if (resId == 0) {
+            return null;
+        }
+        try {
+            return packageManager.getDrawable(packageName, resId, applicationInfo);
+        } catch (Exception e){
+            return null;
+        }
+    }
+
+    @NonNull
+    private static Drawable getInputMethodIcon(@NonNull final PackageManager packageManager,
+            @NonNull final InputMethodInfo imi) {
+        final ServiceInfo si = imi.getServiceInfo();
+        final ApplicationInfo ai = si.applicationInfo;
+        final String packageName = imi.getPackageName();
+        if (si == null || ai == null || packageName == null) {
+            return new ColorDrawable(Color.TRANSPARENT);
+        }
+        // We do not use ServiceInfo#loadLogo() and ServiceInfo#loadIcon here since those methods
+        // internally have some fallback rules, which we want to do manually.
+        Drawable drawable = loadDrawable(packageManager, packageName, si.logo, ai);
+        if (drawable != null) {
+            return drawable;
+        }
+        drawable = loadDrawable(packageManager, packageName, si.icon, ai);
+        if (drawable != null) {
+            return drawable;
+        }
+        // We do not use ApplicationInfo#loadLogo() and ApplicationInfo#loadIcon here since those
+        // methods internally have some fallback rules, which we want to do manually.
+        drawable = loadDrawable(packageManager, packageName, ai.logo, ai);
+        if (drawable != null) {
+            return drawable;
+        }
+        drawable = loadDrawable(packageManager, packageName, ai.icon, ai);
+        if (drawable != null) {
+            return drawable;
+        }
+        return new ColorDrawable(Color.TRANSPARENT);
+    }
+
     private void updateInputMethodPreferenceViews() {
         mInputMethodSettingValues.refreshAllInputMethodAndSubtypes();
         // Clear existing "InputMethodPreference"s
         mInputMethodPreferenceList.clear();
         List<String> permittedList = mDpm.getPermittedInputMethodsForCurrentUser();
         final Context context = getPrefContext();
+        final PackageManager packageManager = getActivity().getPackageManager();
         final List<InputMethodInfo> imis = mInputMethodSettingValues.getInputMethodList();
         final int N = (imis == null ? 0 : imis.size());
         for (int i = 0; i < N; ++i) {
             final InputMethodInfo imi = imis.get(i);
             final boolean isAllowedByOrganization = permittedList == null
                     || permittedList.contains(imi.getPackageName());
-            Drawable icon;
-            try {
-                icon = getActivity().getPackageManager().getApplicationIcon(imi.getPackageName());
-            } catch (Exception e) {
-                icon = NO_ICON;
-            }
             final InputMethodPreference pref = new InputMethodPreference(
                     context, imi, true, isAllowedByOrganization, this);
-            pref.setIcon(icon);
+            pref.setIcon(getInputMethodIcon(packageManager, imi));
             mInputMethodPreferenceList.add(pref);
         }
         final Collator collator = Collator.getInstance();
diff --git a/src/com/android/settings/inputmethod/SpellCheckersSettings.java b/src/com/android/settings/inputmethod/SpellCheckersSettings.java
index bc2a5c0..3309af2 100644
--- a/src/com/android/settings/inputmethod/SpellCheckersSettings.java
+++ b/src/com/android/settings/inputmethod/SpellCheckersSettings.java
@@ -113,7 +113,7 @@
         mSwitchBar.setChecked(isSpellCheckerEnabled);
 
         final SpellCheckerSubtype currentScs;
-        if (mCurrentSci == null) {
+        if (mCurrentSci != null) {
             currentScs = mTsm.getCurrentSpellCheckerSubtype(
                     false /* allowImplicitlySelectedSubtype */);
         } else {
diff --git a/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java b/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java
index fe81a81..3b36de6 100644
--- a/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java
+++ b/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java
@@ -113,7 +113,7 @@
             InputMethodAndSubtypeUtil.removeUnnecessaryNonPersistentPreference(pref);
             pref.updatePreferenceViews();
         }
-        mAddVirtualKeyboardScreen.setIcon(R.drawable.ic_add);
+        mAddVirtualKeyboardScreen.setIcon(R.drawable.ic_add_24dp);
         mAddVirtualKeyboardScreen.setOrder(N);
         getPreferenceScreen().addPreference(mAddVirtualKeyboardScreen);
     }
diff --git a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
index a78c60d..2ce4e72 100644
--- a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
+++ b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.graphics.Canvas;
+import android.os.Bundle;
 import android.support.v4.view.MotionEventCompat;
 import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.helper.ItemTouchHelper;
@@ -36,6 +37,7 @@
 import com.android.settings.R;
 
 import java.text.NumberFormat;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
@@ -45,6 +47,7 @@
         extends RecyclerView.Adapter<LocaleDragAndDropAdapter.CustomViewHolder> {
 
     private static final String TAG = "LocaleDragAndDropAdapter";
+    private static final String CFGKEY_SELECTED_LOCALES = "selectedLocales";
     private final Context mContext;
     private final List<LocaleStore.LocaleInfo> mFeedItemList;
     private final ItemTouchHelper mItemTouchHelper;
@@ -105,6 +108,7 @@
             private static final int SELECTION_LOST = 0;
             private static final int SELECTION_UNCHANGED = -1;
             private int mSelectionStatus = SELECTION_UNCHANGED;
+
             @Override
             public void onChildDraw(Canvas c, RecyclerView recyclerView,
                     RecyclerView.ViewHolder viewHolder, float dX, float dY,
@@ -148,7 +152,6 @@
     public void onBindViewHolder(final CustomViewHolder holder, int i) {
         final LocaleStore.LocaleInfo feedItem = mFeedItemList.get(i);
         final LocaleDragCell dragCell = holder.getLocaleDragCell();
-
         String label = feedItem.getFullNameNative();
         dragCell.setLabel(label);
         dragCell.setLocalized(feedItem.isTranslated());
@@ -156,7 +159,7 @@
         dragCell.setShowCheckbox(mRemoveMode);
         dragCell.setShowMiniLabel(!mRemoveMode);
         dragCell.setShowHandle(!mRemoveMode && mDragEnabled);
-        dragCell.setChecked(false);
+        dragCell.setChecked(mRemoveMode ? feedItem.getChecked() : false);
         dragCell.setTag(feedItem);
         dragCell.getCheckbox()
                 .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@@ -286,4 +289,40 @@
     private void setDragEnabled(boolean enabled) {
         mDragEnabled = enabled;
     }
+
+    /**
+     * Saves the list of checked locales to preserve status when the list is destroyed.
+     * (for instance when the device is rotated)
+     * @param outInstanceState Bundle in which to place the saved state
+     */
+    public void saveState(Bundle outInstanceState) {
+        if (outInstanceState != null) {
+            final ArrayList<String> selectedLocales = new ArrayList<>();
+            for (LocaleStore.LocaleInfo li : mFeedItemList) {
+                if (li.getChecked()) {
+                    selectedLocales.add(li.getId());
+                }
+            }
+            outInstanceState.putStringArrayList(CFGKEY_SELECTED_LOCALES, selectedLocales);
+        }
+    }
+
+    /**
+     * Restores the list of checked locales to preserve status when the list is recreated.
+     * (for instance when the device is rotated)
+     * @param savedInstanceState Bundle with the data saved by {@link #saveState(Bundle)}
+     */
+    public void restoreState(Bundle savedInstanceState) {
+        if (savedInstanceState != null && mRemoveMode) {
+            final ArrayList<String> selectedLocales =
+                    savedInstanceState.getStringArrayList(CFGKEY_SELECTED_LOCALES);
+            if (selectedLocales == null || selectedLocales.isEmpty()) {
+                return;
+            }
+            for (LocaleStore.LocaleInfo li : mFeedItemList) {
+                li.setChecked(selectedLocales.contains(li.getId()));
+            }
+            notifyItemRangeChanged(0, mFeedItemList.size());
+        }
+    }
 }
diff --git a/src/com/android/settings/localepicker/LocaleListEditor.java b/src/com/android/settings/localepicker/LocaleListEditor.java
index 63649d7..3287d39 100644
--- a/src/com/android/settings/localepicker/LocaleListEditor.java
+++ b/src/com/android/settings/localepicker/LocaleListEditor.java
@@ -31,6 +31,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.LinearLayout;
+
 import com.android.internal.app.LocalePicker;
 import com.android.internal.app.LocalePickerWithRegion;
 import com.android.internal.app.LocaleStore;
@@ -48,12 +49,15 @@
 public class LocaleListEditor extends SettingsPreferenceFragment
         implements LocalePickerWithRegion.LocaleSelectedListener {
 
+    private static final String CFGKEY_REMOVE_MODE = "localeRemoveMode";
+    private static final String CFGKEY_REMOVE_DIALOG = "showingLocaleRemoveDialog";
     private static final int MENU_ID_REMOVE = Menu.FIRST + 1;
 
     private LocaleDragAndDropAdapter mAdapter;
     private Menu mMenu;
-    private boolean mRemoveMode;
     private View mAddLanguage;
+    private boolean mRemoveMode;
+    private boolean mShowingRemoveDialog;
 
     @Override
     protected int getMetricsCategory() {
@@ -83,14 +87,44 @@
     }
 
     @Override
+    public void onViewStateRestored(Bundle savedInstanceState) {
+        super.onViewStateRestored(savedInstanceState);
+        if (savedInstanceState != null) {
+            mRemoveMode = savedInstanceState.getBoolean(CFGKEY_REMOVE_MODE, false);
+            mShowingRemoveDialog = savedInstanceState.getBoolean(CFGKEY_REMOVE_DIALOG, false);
+        }
+        setRemoveMode(mRemoveMode);
+        mAdapter.restoreState(savedInstanceState);
+
+        if (mShowingRemoveDialog) {
+            showRemoveLocaleWarningDialog();
+        }
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putBoolean(CFGKEY_REMOVE_MODE, mRemoveMode);
+        outState.putBoolean(CFGKEY_REMOVE_DIALOG, mShowingRemoveDialog);
+        mAdapter.saveState(outState);
+    }
+
+    @Override
     public boolean onOptionsItemSelected(MenuItem menuItem) {
-        if (menuItem.getItemId() == MENU_ID_REMOVE) {
-            if (mRemoveMode) {
-                removeLocaleWarningDialog();
-            } else {
-                setRemoveMode(true);
-            }
-            return true;
+        switch (menuItem.getItemId()) {
+            case MENU_ID_REMOVE:
+                if (mRemoveMode) {
+                    showRemoveLocaleWarningDialog();
+                } else {
+                    setRemoveMode(true);
+                }
+                return true;
+            case android.R.id.home:
+                if (mRemoveMode) {
+                    setRemoveMode(false);
+                    return true;
+                }
+                break;
         }
         return super.onOptionsItemSelected(menuItem);
     }
@@ -98,12 +132,15 @@
     private void setRemoveMode(boolean mRemoveMode) {
         this.mRemoveMode = mRemoveMode;
         mAdapter.setRemoveMode(mRemoveMode);
-        mMenu.findItem(MENU_ID_REMOVE).setShowAsAction(
-                mRemoveMode ? MenuItem.SHOW_AS_ACTION_ALWAYS : MenuItem.SHOW_AS_ACTION_NEVER);
         mAddLanguage.setVisibility(mRemoveMode ? View.INVISIBLE : View.VISIBLE);
+        updateVisibilityOfRemoveMenu();
     }
 
-    private void removeLocaleWarningDialog() {
+    // Show the appropriate warning when the user tries to remove locales.
+    // Shows no warning if there is no locale checked, shows a warning
+    // about removing all the locales if all of them are checked, and
+    // a "regular" warning otherwise.
+    private void showRemoveLocaleWarningDialog() {
         int checkedCount = mAdapter.getCheckedCount();
 
         // Nothing checked, just exit remove mode without a warning dialog
@@ -114,6 +151,7 @@
 
         // All locales selected, warning dialog, can't remove them all
         if (checkedCount == mAdapter.getItemCount()) {
+            mShowingRemoveDialog = true;
             new AlertDialog.Builder(getActivity())
                     .setTitle(R.string.dlg_remove_locales_error_title)
                     .setMessage(R.string.dlg_remove_locales_error_message)
@@ -122,6 +160,12 @@
                         public void onClick(DialogInterface dialog, int which) {
                         }
                     })
+                    .setOnDismissListener(new DialogInterface.OnDismissListener() {
+                        @Override
+                        public void onDismiss(DialogInterface dialog) {
+                            mShowingRemoveDialog = false;
+                        }
+                    })
                     .create()
                     .show();
             return;
@@ -129,21 +173,38 @@
 
         final String title = getResources().getQuantityString(R.plurals.dlg_remove_locales_title,
                 checkedCount);
+        mShowingRemoveDialog = true;
         new AlertDialog.Builder(getActivity())
                 .setTitle(title)
                 .setMessage(R.string.dlg_remove_locales_message)
                 .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialog, int which) {
-                        setRemoveMode(!mRemoveMode);
+                        setRemoveMode(false);
                     }
                 })
                 .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialog, int which) {
+                        // This is a sensitive area to change.
+                        // removeChecked() triggers a system update and "kills" the frame.
+                        // This means that saveState + restoreState are called before
+                        // setRemoveMode is called.
+                        // So we want that mRemoveMode and dialog status have the right values
+                        // before that save.
+                        // We can't just call setRemoveMode(false) before calling removeCheched
+                        // because that unchecks all items and removeChecked would have nothing
+                        // to remove.
+                        mRemoveMode = false;
+                        mShowingRemoveDialog = false;
                         mAdapter.removeChecked();
-                        setRemoveMode(!mRemoveMode);
-                        updateVisibilityOfRemoveMenu();
+                        setRemoveMode(false);
+                    }
+                })
+                .setOnDismissListener(new DialogInterface.OnDismissListener() {
+                    @Override
+                    public void onDismiss(DialogInterface dialog) {
+                        mShowingRemoveDialog = false;
                     }
                 })
                 .create()
@@ -208,8 +269,14 @@
     // Hide the "Remove" menu if there is only one locale in the list, show it otherwise
     // This is called when the menu is first created, and then one add / remove locale
     private void updateVisibilityOfRemoveMenu() {
+        if (mMenu == null) {
+            return;
+        }
+
         final MenuItem menuItemRemove = mMenu.findItem(MENU_ID_REMOVE);
         if (menuItemRemove != null) {
+            menuItemRemove.setShowAsAction(
+                    mRemoveMode ? MenuItem.SHOW_AS_ACTION_ALWAYS : MenuItem.SHOW_AS_ACTION_NEVER);
             menuItemRemove.setVisible(mAdapter.getItemCount() > 1);
         }
     }
diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java
index 144c841..5113dc6 100644
--- a/src/com/android/settings/notification/AppNotificationSettings.java
+++ b/src/com/android/settings/notification/AppNotificationSettings.java
@@ -72,8 +72,6 @@
 
         addPreferencesFromResource(R.xml.app_notification_settings);
         mImportance = (ImportanceSeekBarPreference) findPreference(KEY_IMPORTANCE);
-        mImportanceReset = (LayoutPreference) findPreference(KEY_IMPORTANCE_RESET);
-        mImportanceTitle = (RestrictedPreference) findPreference(KEY_IMPORTANCE_TITLE);
         mPriority =
                 (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BYPASS_DND);
         mVisibilityOverride =
diff --git a/src/com/android/settings/notification/ConfigureNotificationSettings.java b/src/com/android/settings/notification/ConfigureNotificationSettings.java
index c342ba0..9acac06 100644
--- a/src/com/android/settings/notification/ConfigureNotificationSettings.java
+++ b/src/com/android/settings/notification/ConfigureNotificationSettings.java
@@ -213,7 +213,7 @@
             Log.i(TAG, "Preference not found: " + KEY_LOCK_SCREEN_PROFILE_NOTIFICATIONS);
             return;
         }
-
+        mLockscreenProfile.setUserId(mProfileChallengeUserId);
         ArrayList<CharSequence> entries = new ArrayList<>();
         ArrayList<CharSequence> values = new ArrayList<>();
         entries.add(getString(R.string.lock_screen_notifications_summary_disable_profile));
diff --git a/src/com/android/settings/notification/ImportanceSeekBarPreference.java b/src/com/android/settings/notification/ImportanceSeekBarPreference.java
index aff9688..46f9b3f 100644
--- a/src/com/android/settings/notification/ImportanceSeekBarPreference.java
+++ b/src/com/android/settings/notification/ImportanceSeekBarPreference.java
@@ -20,10 +20,16 @@
 import com.android.settings.SeekBarPreference;
 
 import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.service.notification.NotificationListenerService;
 import android.support.v7.preference.PreferenceViewHolder;
 import android.util.AttributeSet;
+import android.view.View;
 import android.widget.ImageView;
 import android.widget.SeekBar;
+import android.widget.TextView;
 
 /**
  * A slider preference that controls notification importance.
@@ -34,12 +40,23 @@
 
     private Callback mCallback;
     private int mMinProgress;
-    private boolean mSystemApp;
+    private TextView mSummaryTextView;
+    private String mSummary;
+    private SeekBar mSeekBar;
+    private ColorStateList mActiveSliderTint;
+    private ColorStateList mInactiveSliderTint;
+    private boolean mAutoOn;
+    private Handler mHandler;
 
     public ImportanceSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
         setLayoutResource(R.layout.preference_importance_slider);
+        mActiveSliderTint = ColorStateList.valueOf(
+                context.getColor(R.color.importance_slider_color));
+        mInactiveSliderTint = ColorStateList.valueOf(
+                context.getColor(R.color.importance_disabled_slider_color));
+        mHandler = new Handler();
     }
 
     public ImportanceSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr) {
@@ -63,20 +80,67 @@
         notifyChanged();
     }
 
-    public void setSystemApp(boolean systemApp) {
-        mSystemApp = systemApp;
+    @Override
+    public void setProgress(int progress) {
+        mSummary = getProgressSummary(progress);
+        super.setProgress(progress);
+    }
+
+    public void setAutoOn(boolean autoOn) {
+        mAutoOn = autoOn;
         notifyChanged();
     }
 
     @Override
     public void onBindViewHolder(PreferenceViewHolder view) {
         super.onBindViewHolder(view);
-        if (mSystemApp) {
-            ((ImageView) view.findViewById(R.id.low_importance)).getDrawable().setTint(
-                    getContext().getColor(R.color.importance_disabled_tint));
+        mSummaryTextView = (TextView) view.findViewById(com.android.internal.R.id.summary);
+        mSeekBar = (SeekBar) view.findViewById(
+                com.android.internal.R.id.seekbar);
+
+        final ImageView autoButton = (ImageView) view.findViewById(R.id.auto_importance);
+        applyAutoUi(autoButton);
+        autoButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                applyAuto(autoButton);
+            }
+        });
+    }
+
+    private void applyAuto(ImageView autoButton) {
+        mAutoOn = !mAutoOn;
+        if (!mAutoOn) {
+            setProgress(NotificationListenerService.Ranking.IMPORTANCE_DEFAULT);
+            mCallback.onImportanceChanged(
+                    NotificationListenerService.Ranking.IMPORTANCE_DEFAULT, true);
+        } else {
+            mCallback.onImportanceChanged(
+                    NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED, true);
         }
-        view.setDividerAllowedAbove(false);
-        view.setDividerAllowedBelow(false);
+        applyAutoUi(autoButton);
+    }
+
+    private void applyAutoUi(ImageView autoButton) {
+        mSeekBar.setEnabled(!mAutoOn);
+
+        final ColorStateList tint = mAutoOn ? mInactiveSliderTint : mActiveSliderTint;
+        Drawable icon = autoButton.getDrawable().mutate();
+        icon.setTintList(tint);
+        autoButton.setImageDrawable(icon);
+        mSeekBar.setProgressTintList(tint);
+        mSeekBar.setThumbTintList(tint);
+
+        if (mAutoOn) {
+            mSummary = getProgressSummary(
+                    NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED);
+        }
+        mSummaryTextView.setText(mSummary);
+    }
+
+    @Override
+    public CharSequence getSummary() {
+        return mSummary;
     }
 
     @Override
@@ -86,12 +150,49 @@
             seekBar.setProgress(mMinProgress);
             progress = mMinProgress;
         }
-        if (fromTouch) {
-            mCallback.onImportanceChanged(progress);
+        if (mSummaryTextView != null) {
+            mSummary = getProgressSummary(progress);
+            mSummaryTextView.setText(mSummary);
+        }
+        mCallback.onImportanceChanged(progress, fromTouch);
+    }
+
+    private String getProgressSummary(int progress) {
+        switch (progress) {
+            case NotificationListenerService.Ranking.IMPORTANCE_NONE:
+                return getContext().getString(R.string.notification_importance_blocked);
+            case NotificationListenerService.Ranking.IMPORTANCE_MIN:
+                return getContext().getString(R.string.notification_importance_min);
+            case NotificationListenerService.Ranking.IMPORTANCE_LOW:
+                return getContext().getString(R.string.notification_importance_low);
+            case NotificationListenerService.Ranking.IMPORTANCE_DEFAULT:
+                return getContext().getString(R.string.notification_importance_default);
+            case NotificationListenerService.Ranking.IMPORTANCE_HIGH:
+                return getContext().getString(R.string.notification_importance_high);
+            case NotificationListenerService.Ranking.IMPORTANCE_MAX:
+                return getContext().getString(R.string.notification_importance_max);
+            default:
+                return getContext().getString(R.string.notification_importance_unspecified);
         }
     }
 
+    @Override
+    protected void notifyChanged() {
+        mHandler.post(mNotifyChanged);
+    }
+
+    private void postNotifyChanged() {
+        super.notifyChanged();
+    }
+
+    private final Runnable mNotifyChanged = new Runnable() {
+        @Override
+        public void run() {
+            postNotifyChanged();
+        }
+    };
+
     public interface Callback {
-        void onImportanceChanged(int progress);
+        void onImportanceChanged(int progress, boolean fromTouch);
     }
 }
diff --git a/src/com/android/settings/notification/NotificationLockscreenPreference.java b/src/com/android/settings/notification/NotificationLockscreenPreference.java
index cd3e30c..8c89968 100644
--- a/src/com/android/settings/notification/NotificationLockscreenPreference.java
+++ b/src/com/android/settings/notification/NotificationLockscreenPreference.java
@@ -18,11 +18,14 @@
 
 import com.android.settings.R;
 import com.android.settings.RestrictedListPreference;
+import com.android.settings.Utils;
 
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.util.AttributeSet;
 import android.view.View;
@@ -38,6 +41,7 @@
     private Listener mListener;
     private boolean mShowRemoteInput;
     private boolean mRemoteInputCheckBoxEnabled = true;
+    private int mUserId = UserHandle.myUserId();
 
     public NotificationLockscreenPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -48,6 +52,20 @@
     }
 
     @Override
+    protected void onClick() {
+        final Context context = getContext();
+        if (!Utils.startQuietModeDialogIfNecessary(context, UserManager.get(context), mUserId)) {
+            // Call super to create preference dialog only when work mode is on
+            // startQuietModeDialogIfNecessary will return false if mUserId is not a managed user
+            super.onClick();
+        }
+    }
+
+    public void setUserId(int userId) {
+        mUserId = userId;
+    }
+
+    @Override
     protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
             DialogInterface.OnClickListener innerListener) {
 
diff --git a/src/com/android/settings/notification/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java
index 314c2f8..e034965 100644
--- a/src/com/android/settings/notification/NotificationSettingsBase.java
+++ b/src/com/android/settings/notification/NotificationSettingsBase.java
@@ -20,9 +20,7 @@
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.applications.AppInfoBase;
 import com.android.settingslib.RestrictedLockUtils;
-import com.android.settingslib.RestrictedPreference;
 import com.android.settingslib.RestrictedSwitchPreference;
-import com.android.settings.applications.LayoutPreference;
 
 import android.app.Notification;
 import android.content.Context;
@@ -38,8 +36,6 @@
 import android.support.v7.preference.Preference;
 import android.text.TextUtils;
 import android.util.Log;
-import android.view.View;
-import android.widget.Button;
 import android.widget.Toast;
 
 import java.util.ArrayList;
@@ -54,8 +50,6 @@
     protected static final String KEY_BYPASS_DND = "bypass_dnd";
     protected static final String KEY_VISIBILITY_OVERRIDE = "visibility_override";
     protected static final String KEY_IMPORTANCE = "importance";
-    protected static final String KEY_IMPORTANCE_TITLE = "importance_title";
-    protected static final String KEY_IMPORTANCE_RESET = "importance_reset_button";
     protected static final String KEY_BLOCK = "block";
     protected static final String KEY_SILENT = "silent";
 
@@ -68,8 +62,6 @@
     protected String mPkg;
     protected PackageInfo mPkgInfo;
     protected ImportanceSeekBarPreference mImportance;
-    protected RestrictedPreference mImportanceTitle;
-    protected LayoutPreference mImportanceReset;
     protected RestrictedSwitchPreference mPriority;
     protected DropDownPreference mVisibilityOverride;
     protected RestrictedSwitchPreference mBlock;
@@ -147,9 +139,6 @@
         if (mPriority != null) {
             mPriority.setDisabledByAdmin(mSuspendedAppsAdmin);
         }
-        if (mImportanceTitle != null) {
-            mImportanceTitle.setDisabledByAdmin(mSuspendedAppsAdmin);
-        }
         if (mBlock != null) {
             mBlock.setDisabledByAdmin(mSuspendedAppsAdmin);
         }
@@ -163,54 +152,22 @@
             setVisible(mBlock, false);
             setVisible(mSilent, false);
             mImportance.setDisabledByAdmin(mSuspendedAppsAdmin);
-            mImportanceTitle.setDisabledByAdmin(mSuspendedAppsAdmin);
-            if (importance == Ranking.IMPORTANCE_UNSPECIFIED) {
-                mImportance.setVisible(false);
-                mImportanceReset.setVisible(false);
-                mImportanceTitle.setOnPreferenceClickListener(showEditableImportance);
-            } else {
-                mImportanceTitle.setOnPreferenceClickListener(null);
-            }
-
-            mImportanceTitle.setSummary(getProgressSummary(importance));
-            mImportance.setSystemApp(isSystemApp);
             mImportance.setMinimumProgress(
                     isSystemApp ? Ranking.IMPORTANCE_MIN : Ranking.IMPORTANCE_NONE);
             mImportance.setMax(Ranking.IMPORTANCE_MAX);
             mImportance.setProgress(importance);
+            mImportance.setAutoOn(importance == Ranking.IMPORTANCE_UNSPECIFIED);
             mImportance.setCallback(new ImportanceSeekBarPreference.Callback() {
                 @Override
-                public void onImportanceChanged(int progress) {
-                    mBackend.setImportance(mPkg, mUid, progress);
-                    mImportanceTitle.setSummary(getProgressSummary(progress));
+                public void onImportanceChanged(int progress, boolean fromUser) {
+                    if (fromUser) {
+                        mBackend.setImportance(mPkg, mUid, progress);
+                    }
                     updateDependents(progress);
                 }
             });
-
-            Button button = (Button) mImportanceReset.findViewById(R.id.left_button);
-            button.setText(R.string.importance_reset);
-            button.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    if (mSuspendedAppsAdmin != null) {
-                        RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
-                                getActivity(), mSuspendedAppsAdmin);
-                        return;
-                    }
-
-                    mBackend.setImportance(mPkg, mUid, Ranking.IMPORTANCE_UNSPECIFIED);
-                    mImportanceReset.setVisible(false);
-                    mImportance.setVisible(false);
-                    mImportanceTitle.setOnPreferenceClickListener(showEditableImportance);
-                    mImportanceTitle.setSummary(getProgressSummary(Ranking.IMPORTANCE_UNSPECIFIED));
-                    updateDependents(Ranking.IMPORTANCE_UNSPECIFIED);
-                }
-            });
-            mImportanceReset.findViewById(R.id.right_button).setVisibility(View.INVISIBLE);
         } else {
             setVisible(mImportance, false);
-            setVisible(mImportanceReset, false);
-            setVisible(mImportanceTitle, false);
             boolean blocked = importance == Ranking.IMPORTANCE_NONE || banned;
             mBlock.setChecked(blocked);
             mBlock.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@@ -240,27 +197,6 @@
         }
     }
 
-    private String getProgressSummary(int progress) {
-        switch (progress) {
-            case Ranking.IMPORTANCE_NONE:
-                return mContext.getString(R.string.notification_importance_blocked);
-            case Ranking.IMPORTANCE_MIN:
-                return mContext.getString(R.string.notification_importance_min);
-            case Ranking.IMPORTANCE_LOW:
-                return mContext.getString(R.string.notification_importance_low);
-            case Ranking.IMPORTANCE_DEFAULT:
-                return mContext.getString(R.string.notification_importance_default);
-            case Ranking.IMPORTANCE_HIGH:
-                return mContext.getString(R.string.notification_importance_high);
-            case Ranking.IMPORTANCE_MAX:
-                return mContext.getString(R.string.notification_importance_max);
-            case Ranking.IMPORTANCE_UNSPECIFIED:
-                return mContext.getString(R.string.notification_importance_none);
-            default:
-                return "";
-        }
-    }
-
     protected void setupPriorityPref(boolean priority) {
         mPriority.setDisabledByAdmin(mSuspendedAppsAdmin);
         mPriority.setChecked(priority);
@@ -363,18 +299,4 @@
         }
         return null;
     }
-
-    private Preference.OnPreferenceClickListener showEditableImportance =
-            new Preference.OnPreferenceClickListener() {
-                @Override
-                public boolean onPreferenceClick(Preference preference) {
-                    mBackend.setImportance(mPkg, mUid, Ranking.IMPORTANCE_DEFAULT);
-                    mImportance.setProgress(Ranking.IMPORTANCE_DEFAULT);
-                    mImportanceTitle.setSummary(getProgressSummary(Ranking.IMPORTANCE_DEFAULT));
-                    mImportance.setVisible(true);
-                    mImportanceReset.setVisible(true);
-                    mImportanceTitle.setOnPreferenceClickListener(null);
-                    return true;
-                }
-            };
 }
diff --git a/src/com/android/settings/search/Index.java b/src/com/android/settings/search/Index.java
index 3fd06a2..40d34bc 100644
--- a/src/com/android/settings/search/Index.java
+++ b/src/com/android/settings/search/Index.java
@@ -140,6 +140,7 @@
             IndexColumns.DATA_SUMMARY_OFF_NORMALIZED,
             IndexColumns.DATA_ENTRIES
     };
+    private static final String INDEX = "index";
 
     // Max number of saved search queries (who will be used for proposing suggestions)
     private static long MAX_SAVED_SEARCH_QUERY = 64;
@@ -177,6 +178,7 @@
         public Map<String, List<String>> nonIndexableKeys;
 
         public boolean forceUpdate = false;
+        public boolean fullIndex = true;
 
         public UpdateData() {
             dataToUpdate = new ArrayList<SearchIndexableData>();
@@ -189,6 +191,7 @@
             dataToDelete = new ArrayList<SearchIndexableData>(other.dataToDelete);
             nonIndexableKeys = new HashMap<String, List<String>>(other.nonIndexableKeys);
             forceUpdate = other.forceUpdate;
+            fullIndex = other.fullIndex;
         }
 
         public UpdateData copy() {
@@ -200,6 +203,7 @@
             dataToDelete.clear();
             nonIndexableKeys.clear();
             forceUpdate = false;
+            fullIndex = false;
         }
     }
 
@@ -213,9 +217,7 @@
      */
     public static Index getInstance(Context context) {
         if (sInstance == null) {
-            sInstance = new Index(context, BASE_AUTHORITY);
-        } else {
-            sInstance.setContext(context);
+            sInstance = new Index(context.getApplicationContext(), BASE_AUTHORITY);
         }
         return sInstance;
     }
@@ -301,24 +303,30 @@
     }
 
     public void update() {
-        final Intent intent = new Intent(SearchIndexablesContract.PROVIDER_INTERFACE);
-        List<ResolveInfo> list =
-                mContext.getPackageManager().queryIntentContentProviders(intent, 0);
+        AsyncTask.execute(new Runnable() {
+            @Override
+            public void run() {
+                final Intent intent = new Intent(SearchIndexablesContract.PROVIDER_INTERFACE);
+                List<ResolveInfo> list =
+                        mContext.getPackageManager().queryIntentContentProviders(intent, 0);
 
-        final int size = list.size();
-        for (int n = 0; n < size; n++) {
-            final ResolveInfo info = list.get(n);
-            if (!isWellKnownProvider(info)) {
-                continue;
+                final int size = list.size();
+                for (int n = 0; n < size; n++) {
+                    final ResolveInfo info = list.get(n);
+                    if (!isWellKnownProvider(info)) {
+                        continue;
+                    }
+                    final String authority = info.providerInfo.authority;
+                    final String packageName = info.providerInfo.packageName;
+
+                    addIndexablesFromRemoteProvider(packageName, authority);
+                    addNonIndexablesKeysFromRemoteProvider(packageName, authority);
+                }
+
+                mDataToProcess.fullIndex = true;
+                updateInternal();
             }
-            final String authority = info.providerInfo.authority;
-            final String packageName = info.providerInfo.packageName;
-
-            addIndexablesFromRemoteProvider(packageName, authority);
-            addNonIndexablesKeysFromRemoteProvider(packageName, authority);
-        }
-
-        updateInternal();
+        });
     }
 
     private boolean addIndexablesFromRemoteProvider(String packageName, String authority) {
@@ -472,7 +480,7 @@
      * @param includeInSearchResults true means that you want the bit "enabled" set so that the
      *                               data will be seen included into the search results
      */
-    public void updateFromClassNameResource(String className, boolean rebuild,
+    public void updateFromClassNameResource(String className, final boolean rebuild,
             boolean includeInSearchResults) {
         if (className == null) {
             throw new IllegalArgumentException("class name cannot be null!");
@@ -484,19 +492,29 @@
         }
         res.context = mContext;
         res.enabled = includeInSearchResults;
-        if (rebuild) {
-            deleteIndexableData(res);
-        }
-        addIndexableData(res);
-        mDataToProcess.forceUpdate = true;
-        updateInternal();
-        res.enabled = false;
+        AsyncTask.execute(new Runnable() {
+            @Override
+            public void run() {
+                if (rebuild) {
+                    deleteIndexableData(res);
+                }
+                addIndexableData(res);
+                mDataToProcess.forceUpdate = true;
+                updateInternal();
+                res.enabled = false;
+            }
+        });
     }
 
     public void updateFromSearchIndexableData(SearchIndexableData data) {
-        addIndexableData(data);
-        mDataToProcess.forceUpdate = true;
-        updateInternal();
+        AsyncTask.execute(new Runnable() {
+            @Override
+            public void run() {
+                addIndexableData(data);
+                mDataToProcess.forceUpdate = true;
+                updateInternal();
+            }
+        });
     }
 
     private SQLiteDatabase getReadableDatabase() {
@@ -1182,6 +1200,7 @@
             final Map<String, List<String>> nonIndexableKeys = params[0].nonIndexableKeys;
 
             final boolean forceUpdate = params[0].forceUpdate;
+            final boolean fullIndex = params[0].fullIndex;
 
             final SQLiteDatabase database = getWritableDatabase();
             if (database == null) {
@@ -1203,6 +1222,9 @@
             } finally {
                 database.endTransaction();
             }
+            if (fullIndex) {
+                setLocaleIndexed(localeStr);
+            }
 
             return null;
         }
@@ -1225,8 +1247,8 @@
                 try {
                     indexOneSearchIndexableData(database, localeStr, data, nonIndexableKeys);
                 } catch (Exception e) {
-                    Log.e(LOG_TAG,
-                            "Cannot index: " + data.className + " for locale: " + localeStr, e);
+                    Log.e(LOG_TAG, "Cannot index: " + (data != null ? data.className : data)
+                                    + " for locale: " + localeStr, e);
                 }
             }
 
@@ -1273,24 +1295,12 @@
             return database.delete(Tables.TABLE_PREFS_INDEX, whereClause, whereArgs);
         }
 
+        private void setLocaleIndexed(String locale) {
+            mContext.getSharedPreferences(INDEX, 0).edit().putBoolean(locale, true).commit();
+        }
+
         private boolean isLocaleAlreadyIndexed(SQLiteDatabase database, String locale) {
-            Cursor cursor = null;
-            boolean result = false;
-            final StringBuilder sb = new StringBuilder(IndexColumns.LOCALE);
-            sb.append(" = ");
-            DatabaseUtils.appendEscapedSQLString(sb, locale);
-            try {
-                // We care only for 1 row
-                cursor = database.query(Tables.TABLE_PREFS_INDEX, null,
-                        sb.toString(), null, null, null, null, "1");
-                final int count = cursor.getCount();
-                result = (count >= 1);
-            } finally {
-                if (cursor != null) {
-                    cursor.close();
-                }
-            }
-            return result;
+            return mContext.getSharedPreferences(INDEX, 0).getBoolean(locale, false);
         }
     }
 
diff --git a/src/com/android/settings/tts/TextToSpeechSettings.java b/src/com/android/settings/tts/TextToSpeechSettings.java
index 0a48874..8c34518 100644
--- a/src/com/android/settings/tts/TextToSpeechSettings.java
+++ b/src/com/android/settings/tts/TextToSpeechSettings.java
@@ -71,6 +71,9 @@
     /** 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 reset speech pitch preference. */
+    private static final String KEY_RESET_SPEECH_PITCH = "reset_speech_pitch";
+
     /** Preference key for the TTS status field. */
     private static final String KEY_STATUS = "tts_status";
 
@@ -87,10 +90,11 @@
     private static final int VOICE_DATA_INTEGRITY_CHECK = 1977;
 
     /**
-     * Maximum speech rate value.
+     * Speech rate value.
      * This value should be kept in sync with the max value set in tts_settings xml.
      */
     private static final int MAX_SPEECH_RATE = 600;
+    private static final int MIN_SPEECH_RATE = 10;
 
     /**
      * Speech pitch value.
@@ -107,6 +111,7 @@
     private SeekBarPreference mDefaultPitchPref;
     private SeekBarPreference mDefaultRatePref;
     private Preference mResetSpeechRate;
+    private Preference mResetSpeechPitch;
     private Preference mPlayExample;
     private Preference mEngineStatus;
 
@@ -189,6 +194,8 @@
 
         mResetSpeechRate = findPreference(KEY_RESET_SPEECH_RATE);
         mResetSpeechRate.setOnPreferenceClickListener(this);
+        mResetSpeechPitch = findPreference(KEY_RESET_SPEECH_PITCH);
+        mResetSpeechPitch.setOnPreferenceClickListener(this);
 
         mEnginePreferenceCategory = (PreferenceCategory) findPreference(
                 KEY_ENGINE_PREFERENCE_SECTION);
@@ -252,24 +259,27 @@
     private void initSettings() {
         final ContentResolver resolver = getContentResolver();
 
-         // Set up the default rate and pitch.
-        try {
-            mDefaultPitch = android.provider.Settings.Secure.getInt(resolver, TTS_DEFAULT_PITCH);
-            mDefaultRate = android.provider.Settings.Secure.getInt(resolver, TTS_DEFAULT_RATE);
-        } catch (SettingNotFoundException e) {
-            // Default rate and pitch setting not found, initialize it.
-            mDefaultPitch = TextToSpeech.Engine.DEFAULT_PITCH;
-            mDefaultRate = TextToSpeech.Engine.DEFAULT_RATE;
-        }
-        mDefaultRatePref.setProgress(mDefaultRate);
+        // Set up the default rate and pitch.
+        mDefaultRate = android.provider.Settings.Secure.getInt(
+            resolver, TTS_DEFAULT_RATE, TextToSpeech.Engine.DEFAULT_RATE);
+        mDefaultPitch = android.provider.Settings.Secure.getInt(
+            resolver, TTS_DEFAULT_PITCH, TextToSpeech.Engine.DEFAULT_PITCH);
+
+        mDefaultRatePref.setProgress(getSeekBarProgressFromValue(KEY_DEFAULT_RATE, mDefaultRate));
         mDefaultRatePref.setOnPreferenceChangeListener(this);
-        mDefaultRatePref.setMax(MAX_SPEECH_RATE);
+        mDefaultRatePref.setMax(getSeekBarProgressFromValue(KEY_DEFAULT_RATE, MAX_SPEECH_RATE));
 
-        mDefaultPitchPref.setProgress(getPitchSeekBarProgressFromSpeechPitchValue(mDefaultPitch));
+        mDefaultPitchPref.setProgress(getSeekBarProgressFromValue(KEY_DEFAULT_PITCH,
+              mDefaultPitch));
         mDefaultPitchPref.setOnPreferenceChangeListener(this);
-        mDefaultPitchPref.setMax(getPitchSeekBarProgressFromSpeechPitchValue(MAX_SPEECH_PITCH));
+        mDefaultPitchPref.setMax(getSeekBarProgressFromValue(KEY_DEFAULT_PITCH,
+              MAX_SPEECH_PITCH));
 
-        mCurrentEngine = mTts.getCurrentEngine();
+        if (mTts != null) {
+            mCurrentEngine = mTts.getCurrentEngine();
+            mTts.setSpeechRate(mDefaultRate/100.0f);
+            mTts.setPitch(mDefaultPitch/100.0f);
+        }
 
         SettingsActivity activity = null;
         if (getActivity() instanceof SettingsActivity) {
@@ -292,21 +302,31 @@
     }
 
     /**
-     * The minimum pitch value should be > 0 but the minimum value of a seekbar in android
-     * is fixed at 0. Therefore, we increment the seekbar progress with MIN_SPEECH_PITCH value
-     * so that the minimum seekbar progress value is MIN_SPEECH_PITCH.
-     *     PITCH_VALUE = MIN_SPEECH_PITCH + PITCH_SEEKBAR_PROGRESS
+     * The minimum speech pitch/rate value should be > 0 but the minimum value of a seekbar in
+     * android is fixed at 0. Therefore, we increment the seekbar progress with MIN_SPEECH_VALUE
+     * so that the minimum seekbar progress value is MIN_SPEECH_PITCH/RATE.
+     *     SPEECH_VALUE = MIN_SPEECH_VALUE + SEEKBAR_PROGRESS
      */
-    private int getSpeechPitchValueFromSeekBarProgress(int progress) {
-        return MIN_SPEECH_PITCH + progress;
+    private int getValueFromSeekBarProgress(String preferenceKey, int progress) {
+        if (preferenceKey.equals(KEY_DEFAULT_RATE)) {
+            return MIN_SPEECH_RATE + progress;
+        } else if (preferenceKey.equals(KEY_DEFAULT_PITCH)) {
+            return MIN_SPEECH_PITCH + progress;
+        }
+        return progress;
     }
 
     /**
-     * Since we are appending the MIN_SPEECH_PITCH to the pitch seekbar progress, the pitch
-     * seekbar progress should be set to (pitchValue - MIN_SPEECH_PITCH).
+     * Since we are appending the MIN_SPEECH value to the speech seekbar progress, the
+     * speech seekbar progress should be set to (speechValue - MIN_SPEECH value).
      */
-    private int getPitchSeekBarProgressFromSpeechPitchValue(int pitchValue) {
-        return pitchValue - MIN_SPEECH_PITCH;
+    private int getSeekBarProgressFromValue(String preferenceKey, int value) {
+        if (preferenceKey.equals(KEY_DEFAULT_RATE)) {
+            return value - MIN_SPEECH_RATE;
+        } else if (preferenceKey.equals(KEY_DEFAULT_PITCH)) {
+            return value - MIN_SPEECH_PITCH;
+        }
+        return value;
     }
 
     /**
@@ -505,24 +525,14 @@
         if (KEY_DEFAULT_RATE.equals(preference.getKey())) {
             updateSpeechRate((Integer) objValue);
         } else if (KEY_DEFAULT_PITCH.equals(preference.getKey())) {
-            int progress = (Integer) objValue;
-            mDefaultPitch = getSpeechPitchValueFromSeekBarProgress(progress);
-            try {
-                android.provider.Settings.Secure.putInt(getContentResolver(),
-                        TTS_DEFAULT_PITCH, mDefaultPitch);
-               if (mTts != null) {
-                   mTts.setPitch(mDefaultPitch / 100.0f);
-               }
-               if (DBG) Log.d(TAG, "TTS default pitch changed, now" + mDefaultPitch);
-           } catch (NumberFormatException e) {
-               Log.e(TAG, "could not persist default TTS pitch setting", e);
-           }
+            updateSpeechPitchValue((Integer) objValue);
         }
         return true;
     }
 
     /**
-     * Called when mPlayExample or mResetSpeechRate is clicked.
+     * Called when mPlayExample, mResetSpeechRate or mResetSpeechPitch is
+     * clicked.
      */
     @Override
     public boolean onPreferenceClick(Preference preference) {
@@ -532,15 +542,24 @@
             speakSampleText();
             return true;
         } else if (preference == mResetSpeechRate) {
-          mDefaultRatePref.setProgress(TextToSpeech.Engine.DEFAULT_RATE);
-          updateSpeechRate(TextToSpeech.Engine.DEFAULT_RATE);
+          int speechRateSeekbarProgress = getSeekBarProgressFromValue(
+              KEY_DEFAULT_RATE, TextToSpeech.Engine.DEFAULT_RATE);
+          mDefaultRatePref.setProgress(speechRateSeekbarProgress);
+          updateSpeechRate(speechRateSeekbarProgress);
+          return true;
+        } else if (preference == mResetSpeechPitch) {
+          int pitchSeekbarProgress = getSeekBarProgressFromValue(
+              KEY_DEFAULT_PITCH, TextToSpeech.Engine.DEFAULT_PITCH);
+          mDefaultPitchPref.setProgress(pitchSeekbarProgress);
+          updateSpeechPitchValue(pitchSeekbarProgress);
           return true;
         }
         return false;
     }
 
-    private void updateSpeechRate(int speechRate) {
-        mDefaultRate = speechRate;
+    private void updateSpeechRate(int speechRateSeekBarProgress) {
+        mDefaultRate = getValueFromSeekBarProgress(KEY_DEFAULT_RATE,
+            speechRateSeekBarProgress);
         try {
             android.provider.Settings.Secure.putInt(getContentResolver(),
                     TTS_DEFAULT_RATE, mDefaultRate);
@@ -554,6 +573,22 @@
         return;
     }
 
+    private void updateSpeechPitchValue(int speechPitchSeekBarProgress) {
+        mDefaultPitch = getValueFromSeekBarProgress(KEY_DEFAULT_PITCH,
+            speechPitchSeekBarProgress);
+        try {
+            android.provider.Settings.Secure.putInt(getContentResolver(),
+                    TTS_DEFAULT_PITCH, mDefaultPitch);
+            if (mTts != null) {
+                mTts.setPitch(mDefaultPitch / 100.0f);
+            }
+            if (DBG) Log.d(TAG, "TTS default pitch changed, now" + mDefaultPitch);
+        } catch (NumberFormatException e) {
+            Log.e(TAG, "could not persist default TTS pitch setting", e);
+        }
+        return;
+    }
+
     private void updateWidgetState(boolean enable) {
         mPlayExample.setEnabled(enable);
         mDefaultRatePref.setEnabled(enable);