Merge "Add Work Challenge Notifications Setting" into nyc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 49c6790..634d684 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -609,6 +609,8 @@
             </intent-filter>
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                 android:value="com.android.settings.inputmethod.AvailableVirtualKeyboardFragment" />
+            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+                android:value="true" />
         </activity>
 
         <activity android:name="Settings$ManageAssistActivity"
@@ -2782,14 +2784,13 @@
                   android:exported="true">
             <intent-filter android:priority="1">
                 <action android:name="android.settings.MANAGE_DEFAULT_APPS_SETTINGS" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-            <intent-filter>
                 <action android:name="android.settings.HOME_SETTINGS" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                        android:value="com.android.settings.applications.AdvancedAppSettings" />
+            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+                        android:value="true" />
         </activity>
 
         <service
diff --git a/res/layout/bugreport_options_dialog.xml b/res/layout/bugreport_options_dialog.xml
index ac98d18..d937bc3 100644
--- a/res/layout/bugreport_options_dialog.xml
+++ b/res/layout/bugreport_options_dialog.xml
@@ -18,7 +18,11 @@
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="horizontal" >
+    android:orientation="horizontal"
+    android:paddingStart="20dp"
+    android:paddingEnd="24dp"
+    android:paddingTop="15dp"
+    >
 
     <CheckedTextView
         android:id="@+id/bugreport_option_interactive_title"
@@ -29,7 +33,6 @@
         android:ellipsize="marquee"
         android:gravity="center_vertical"
         android:paddingEnd="?android:attr/dialogPreferredPadding"
-        android:paddingStart="20dp"
         android:text="@*android:string/bugreport_option_interactive_title"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:textColor="?android:attr/textColorAlertDialogListItem" />
@@ -40,8 +43,8 @@
         android:layout_height="wrap_content"
         android:layout_below="@+id/bugreport_option_interactive_title"
         android:maxLines="10"
-        android:paddingBottom="8dp"
-        android:paddingStart="52dp"
+        android:paddingBottom="10dp"
+        android:paddingStart="32dp"
         android:paddingEnd="?android:attr/dialogPreferredPadding"
         android:text="@*android:string/bugreport_option_interactive_summary"
         android:textAppearance="?android:attr/textAppearanceListItemSecondary"
@@ -57,7 +60,6 @@
         android:ellipsize="marquee"
         android:gravity="center_vertical"
         android:paddingEnd="?android:attr/dialogPreferredPadding"
-        android:paddingStart="20dp"
         android:text="@*android:string/bugreport_option_full_title"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:textColor="?android:attr/textColorAlertDialogListItem" />
@@ -68,8 +70,8 @@
         android:layout_height="wrap_content"
         android:layout_below="@+id/bugreport_option_full_title"
         android:maxLines="10"
-        android:paddingBottom="8dp"
-        android:paddingStart="52dp"
+        android:paddingBottom="10dp"
+        android:paddingStart="32dp"
         android:paddingEnd="?android:attr/dialogPreferredPadding"
         android:text="@*android:string/bugreport_option_full_summary"
         android:textAppearance="?android:attr/textAppearanceListItemSecondary"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 08e49ad..e900832 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5988,9 +5988,6 @@
     <!-- [CHAR LIMIT=180] Notification importance summary -->
     <string name="show_silently_summary">Don\'t make sound, vibrate, or peek these notifications into view on the current screen.</string>
 
-    <!-- Default Apps > Default notification assistant -->
-    <string name="default_notification_assistant">Notification assistant</string>
-
     <!-- Sound & notification > Advanced section: Title for managing notification listeners option. [CHAR LIMIT=30] -->
     <string name="manage_notification_access_title">Notification access</string>
 
diff --git a/res/xml/advanced_apps.xml b/res/xml/advanced_apps.xml
index 99e81a6..99da745 100644
--- a/res/xml/advanced_apps.xml
+++ b/res/xml/advanced_apps.xml
@@ -66,11 +66,6 @@
             android:title="@string/sms_application_title"
             settings:keywords="@string/keywords_more_default_sms_app" />
 
-        <com.android.settings.applications.DefaultNotificationAssistantPreference
-            android:key="default_notification_asst_app"
-            android:title="@string/default_notification_assistant" />
-
-
     </PreferenceCategory>
 
     <com.android.settings.WorkOnlyCategory
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index 5537926..ccc158f 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -702,7 +702,12 @@
                 dialog.show(getChildFragmentManager(), TAG_UNIFICATION_DIALOG);
             } else {
                 mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileChallengeUserId, true);
-                createPreferenceHierarchy();
+                Bundle extras = new Bundle();
+                extras.putInt(Intent.EXTRA_USER_ID, mProfileChallengeUserId);
+                startFragment(this,
+                        "com.android.settings.ChooseLockGeneric$ChooseLockGenericFragment",
+                        R.string.lock_settings_picker_title_profile,
+                        SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
             }
         } else if (KEY_SHOW_PASSWORD.equals(key)) {
             Settings.System.putInt(getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD,
diff --git a/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivity.java b/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivity.java
index bc31c3b..0d580ba 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivity.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivity.java
@@ -19,6 +19,7 @@
 import android.app.Fragment;
 import android.os.Bundle;
 import android.support.v4.widget.DrawerLayout;
+import android.text.TextUtils;
 import android.view.Menu;
 import android.view.MenuItem;
 
@@ -52,6 +53,12 @@
     @Override
     public void startPreferencePanel(String fragmentClass, Bundle args, int titleRes,
             CharSequence titleText, Fragment resultTo, int resultRequestCode) {
+        if (!TextUtils.isEmpty(titleText)) {
+            setTitle(titleText);
+        } else if (titleRes > 0) {
+            setTitle(getString(titleRes));
+        }
+
         args.putInt(SettingsPreferenceFragment.HELP_URI_RESOURCE_KEY, 0);
         startPreferenceFragment(Fragment.instantiate(this, fragmentClass, args), true);
     }
diff --git a/src/com/android/settings/applications/DefaultNotificationAssistantPreference.java b/src/com/android/settings/applications/DefaultNotificationAssistantPreference.java
deleted file mode 100644
index 53fc391..0000000
--- a/src/com/android/settings/applications/DefaultNotificationAssistantPreference.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.applications;
-
-import android.app.ActivityManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.provider.Settings;
-import android.service.notification.NotificationAssistantService;
-import android.util.AttributeSet;
-import android.util.Slog;
-import com.android.settings.AppListPreference;
-import com.android.settings.R;
-import com.android.settings.notification.ManagedServiceSettings;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class DefaultNotificationAssistantPreference extends AppListPreference {
-    private static final String TAG = "DefaultNotiAssist";
-
-    private PackageManager mPm;
-    private final ManagedServiceSettings.Config mConfig;
-    private final Context mContext;
-
-    public DefaultNotificationAssistantPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        mContext = context;
-        mPm = context.getPackageManager();
-        mConfig = getConfig();
-        setShowItemNone(true);
-        updateList(getServices());
-    }
-
-    @Override
-    protected boolean persistString(String value) {
-        Settings.Secure.putString(mContext.getContentResolver(), mConfig.setting, value);
-        setSummary(getEntry());
-        return true;
-    }
-
-    private void updateList(List<ServiceInfo> services) {
-        final ComponentName[] assistants = new ComponentName[services.size()];
-        for (int i = 0; i < services.size(); i++) {
-            assistants[i] = new ComponentName(services.get(i).packageName, services.get(i).name);
-        }
-        final String assistant =
-                Settings.Secure.getString(mContext.getContentResolver(), mConfig.setting);
-        setComponentNames(assistants, assistant == null ? null
-                : ComponentName.unflattenFromString(assistant));
-    }
-
-    private List<ServiceInfo> getServices() {
-        List<ServiceInfo> services = new ArrayList<>();
-        final int user = ActivityManager.getCurrentUser();
-
-        List<ResolveInfo> installedServices = mPm.queryIntentServicesAsUser(
-                new Intent(mConfig.intentAction),
-                PackageManager.GET_SERVICES | PackageManager.GET_META_DATA,
-                user);
-
-        for (int i = 0, count = installedServices.size(); i < count; i++) {
-            ResolveInfo resolveInfo = installedServices.get(i);
-            ServiceInfo info = resolveInfo.serviceInfo;
-
-            if (!mConfig.permission.equals(info.permission)) {
-                Slog.w(mConfig.tag, "Skipping " + mConfig.noun + " service "
-                        + info.packageName + "/" + info.name
-                        + ": it does not require the permission "
-                        + mConfig.permission);
-                continue;
-            }
-            services.add(info);
-        }
-        return services;
-    }
-
-    private ManagedServiceSettings.Config getConfig() {
-        final ManagedServiceSettings.Config c = new ManagedServiceSettings.Config();
-        c.tag = TAG;
-        c.setting = Settings.Secure.ENABLED_NOTIFICATION_ASSISTANT;
-        c.intentAction = NotificationAssistantService.SERVICE_INTERFACE;
-        c.permission = android.Manifest.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE;
-        c.noun = "notification assistant";
-        c.warningDialogTitle = R.string.notification_listener_security_warning_title;
-        c.warningDialogSummary = R.string.notification_listener_security_warning_summary;
-        c.emptyText = R.string.no_notification_listeners;
-        return c;
-    }
-}
diff --git a/src/com/android/settings/dashboard/SuggestionsChecks.java b/src/com/android/settings/dashboard/SuggestionsChecks.java
index 7d617b7..3ea815c 100644
--- a/src/com/android/settings/dashboard/SuggestionsChecks.java
+++ b/src/com/android/settings/dashboard/SuggestionsChecks.java
@@ -37,7 +37,7 @@
 import com.android.settings.Settings.ZenModeAutomationSuggestionActivity;
 import com.android.settingslib.drawer.Tile;
 
-import java.util.List;
+import java.util.Collection;
 
 /**
  * The Home of all stupidly dynamic Settings Suggestions checks.
@@ -86,10 +86,10 @@
     }
 
     private boolean hasEnabledZenAutoRules() {
-        List<AutomaticZenRule> zenRules = NotificationManager.from(mContext).getAutomaticZenRules();
-        final int N = zenRules.size();
-        for (int i = 0; i < N; i++) {
-            if (zenRules.get(i).isEnabled()) {
+        Collection<AutomaticZenRule> zenRules =
+                NotificationManager.from(mContext).getAutomaticZenRules().values();
+        for (AutomaticZenRule rule : zenRules) {
+            if (rule.isEnabled()) {
                 return true;
             }
         }
diff --git a/src/com/android/settings/datausage/DataSaverSummary.java b/src/com/android/settings/datausage/DataSaverSummary.java
index fa24fa3..e8fb2fc 100644
--- a/src/com/android/settings/datausage/DataSaverSummary.java
+++ b/src/com/android/settings/datausage/DataSaverSummary.java
@@ -14,24 +14,36 @@
 
 package com.android.settings.datausage;
 
+import android.app.Application;
 import android.os.Bundle;
 import android.support.v7.preference.Preference;
-import android.util.Log;
 import android.widget.Switch;
 import com.android.settings.InstrumentedFragment;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.applications.AppStateBaseBridge.Callback;
+import com.android.settings.datausage.DataSaverBackend.Listener;
 import com.android.settings.widget.SwitchBar;
+import com.android.settings.widget.SwitchBar.OnSwitchChangeListener;
+import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.ApplicationsState.AppEntry;
+import com.android.settingslib.applications.ApplicationsState.Callbacks;
+import com.android.settingslib.applications.ApplicationsState.Session;
+
+import java.util.ArrayList;
 
 public class DataSaverSummary extends SettingsPreferenceFragment
-        implements SwitchBar.OnSwitchChangeListener, DataSaverBackend.Listener {
+        implements OnSwitchChangeListener, Listener, Callback, Callbacks {
 
     private static final String KEY_UNRESTRICTED_ACCESS = "unrestricted_access";
 
     private SwitchBar mSwitchBar;
     private DataSaverBackend mDataSaverBackend;
     private Preference mUnrestrictedAccess;
+    private ApplicationsState mApplicationsState;
+    private AppStateDataUsageBridge mDataUsageBridge;
+    private Session mSession;
 
     @Override
     public void onCreate(Bundle icicle) {
@@ -39,7 +51,11 @@
 
         addPreferencesFromResource(R.xml.data_saver);
         mUnrestrictedAccess = findPreference(KEY_UNRESTRICTED_ACCESS);
+        mApplicationsState = ApplicationsState.getInstance(
+                (Application) getContext().getApplicationContext());
         mDataSaverBackend = new DataSaverBackend(getContext());
+        mDataUsageBridge = new AppStateDataUsageBridge(mApplicationsState, this, mDataSaverBackend);
+        mSession = mApplicationsState.newSession(this);
     }
 
     @Override
@@ -53,17 +69,16 @@
     @Override
     public void onResume() {
         super.onResume();
-        mDataSaverBackend.addListener(this);
         mDataSaverBackend.refreshWhitelist();
-        int count = mDataSaverBackend.getWhitelistedCount();
-        mUnrestrictedAccess.setSummary(getResources().getQuantityString(
-                R.plurals.data_saver_unrestricted_summary, count, count));
+        mSession.resume();
+        mDataUsageBridge.resume();
     }
 
     @Override
     public void onPause() {
         super.onPause();
-        mDataSaverBackend.remListener(this);
+        mDataUsageBridge.pause();
+        mSession.pause();
     }
 
     @Override
@@ -80,4 +95,63 @@
     public void onDataSaverChanged(boolean isDataSaving) {
         mSwitchBar.setChecked(isDataSaving);
     }
+
+    @Override
+    public void onExtraInfoUpdated() {
+        int count = 0;
+        final ArrayList<AppEntry> allApps = mSession.getAllApps();
+        final int N = allApps.size();
+        for (int i = 0; i < N; i++) {
+            final AppEntry entry = allApps.get(i);
+            if (!ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER.filterApp(entry)) {
+                continue;
+            }
+            if (entry.extraInfo != null && ((AppStateDataUsageBridge.DataUsageState)
+                    entry.extraInfo).isDataSaverWhitelisted) {
+                count++;
+            }
+        }
+        mUnrestrictedAccess.setSummary(getResources().getQuantityString(
+                R.plurals.data_saver_unrestricted_summary, count, count));
+    }
+
+    @Override
+    public void onRunningStateChanged(boolean running) {
+
+    }
+
+    @Override
+    public void onPackageListChanged() {
+
+    }
+
+    @Override
+    public void onRebuildComplete(ArrayList<AppEntry> apps) {
+
+    }
+
+    @Override
+    public void onPackageIconChanged() {
+
+    }
+
+    @Override
+    public void onPackageSizeChanged(String packageName) {
+
+    }
+
+    @Override
+    public void onAllSizesComputed() {
+
+    }
+
+    @Override
+    public void onLauncherInfoChanged() {
+
+    }
+
+    @Override
+    public void onLoadEntriesCompleted() {
+
+    }
 }
diff --git a/src/com/android/settings/datausage/UnrestrictedDataAccess.java b/src/com/android/settings/datausage/UnrestrictedDataAccess.java
index a88da88..d53905f 100644
--- a/src/com/android/settings/datausage/UnrestrictedDataAccess.java
+++ b/src/com/android/settings/datausage/UnrestrictedDataAccess.java
@@ -20,32 +20,75 @@
 import android.support.v14.preference.SwitchPreference;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceViewHolder;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
 import android.view.View;
 import com.android.settings.InstrumentedFragment;
+import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.applications.AppStateBaseBridge;
 import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.ApplicationsState.AppEntry;
+import com.android.settingslib.applications.ApplicationsState.AppFilter;
 
 import java.util.ArrayList;
 
 public class UnrestrictedDataAccess extends SettingsPreferenceFragment
         implements ApplicationsState.Callbacks, AppStateBaseBridge.Callback, Preference.OnPreferenceChangeListener {
 
+    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;
     private DataSaverBackend mDataSaverBackend;
+    private boolean mShowSystem;
+    private boolean mExtraLoaded;
+    private AppFilter mFilter;
 
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
         setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getContext()));
-        getPreferenceScreen().setOrderingAsAdded(false);
         mApplicationsState = ApplicationsState.getInstance(
                 (Application) getContext().getApplicationContext());
         mDataSaverBackend = new DataSaverBackend(getContext());
         mDataUsageBridge = new AppStateDataUsageBridge(mApplicationsState, this, mDataSaverBackend);
         mSession = mApplicationsState.newSession(this);
+        mShowSystem = icicle != null && icicle.getBoolean(EXTRA_SHOW_SYSTEM);
+        mFilter = mShowSystem ? ApplicationsState.FILTER_ALL_ENABLED
+                : ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER;
+        setHasOptionsMenu(true);
+    }
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        menu.add(Menu.NONE, MENU_SHOW_SYSTEM, Menu.NONE,
+                mShowSystem ? R.string.menu_hide_system : R.string.menu_show_system);
+        super.onCreateOptionsMenu(menu, inflater);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case MENU_SHOW_SYSTEM:
+                mShowSystem = !mShowSystem;
+                item.setTitle(mShowSystem ? R.string.menu_hide_system : R.string.menu_show_system);
+                mFilter = mShowSystem ? ApplicationsState.FILTER_ALL_ENABLED
+                        : ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER;
+                if (mExtraLoaded) {
+                    rebuild();
+                }
+                break;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putBoolean(EXTRA_SHOW_SYSTEM, mShowSystem);
     }
 
     @Override
@@ -77,23 +120,15 @@
 
     @Override
     public void onExtraInfoUpdated() {
-        ArrayList<ApplicationsState.AppEntry> apps = mSession.getAllApps();
-        final int N = apps.size();
-        for (int i = 0; i < N; i++) {
-            ApplicationsState.AppEntry entry = apps.get(i);
-            String key = entry.info.packageName + "|" + entry.info.uid;
-            AccessPreference preference = (AccessPreference) findPreference(key);
-            if (preference == null) {
-                preference = new AccessPreference(getContext(), entry);
-                preference.setKey(key);
-                preference.setOnPreferenceChangeListener(this);
-                getPreferenceScreen().addPreference(preference);
-            }
-            AppStateDataUsageBridge.DataUsageState state =
-                    (AppStateDataUsageBridge.DataUsageState) entry.extraInfo;
-            preference.setChecked(state.isDataSaverWhitelisted);
+        mExtraLoaded = true;
+        rebuild();
+    }
+
+    private void rebuild() {
+        ArrayList<AppEntry> apps = mSession.rebuild(mFilter, ApplicationsState.ALPHA_COMPARATOR);
+        if (apps != null) {
+            onRebuildComplete(apps);
         }
-        setLoading(false, true);
     }
 
     @Override
@@ -108,7 +143,24 @@
 
     @Override
     public void onRebuildComplete(ArrayList<ApplicationsState.AppEntry> apps) {
-
+        cacheRemoveAllPrefs(getPreferenceScreen());
+        final int N = apps.size();
+        for (int i = 0; i < N; i++) {
+            ApplicationsState.AppEntry entry = apps.get(i);
+            String key = entry.info.packageName + "|" + entry.info.uid;
+            AccessPreference preference = (AccessPreference) getCachedPreference(key);
+            if (preference == null) {
+                preference = new AccessPreference(getContext(), entry);
+                preference.setKey(key);
+                preference.setOnPreferenceChangeListener(this);
+                getPreferenceScreen().addPreference(preference);
+            } else {
+                preference.reuse();
+            }
+            preference.setOrder(i);
+        }
+        setLoading(false, true);
+        removeCachedPrefs(getPreferenceScreen());
     }
 
     @Override
@@ -164,20 +216,31 @@
             setTitle(entry.label);
             setChecked(((AppStateDataUsageBridge.DataUsageState) entry.extraInfo)
                     .isDataSaverWhitelisted);
+            if (mEntry.icon != null) {
+                setIcon(mEntry.icon);
+            }
+        }
+
+        public void reuse() {
+            setTitle(mEntry.label);
+            setChecked(((AppStateDataUsageBridge.DataUsageState) mEntry.extraInfo)
+                    .isDataSaverWhitelisted);
         }
 
         @Override
         public void onBindViewHolder(PreferenceViewHolder holder) {
-            holder.itemView.post(new Runnable() {
-                @Override
-                public void run() {
-                    // Ensure we have an icon before binding.
-                    mApplicationsState.ensureIcon(mEntry);
-                    // This might trigger us to bind again, but it gives an easy way to only load the icon
-                    // once its needed, so its probably worth it.
-                    setIcon(mEntry.icon);
-                }
-            });
+            if (mEntry.icon == null) {
+                holder.itemView.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        // Ensure we have an icon before binding.
+                        mApplicationsState.ensureIcon(mEntry);
+                        // This might trigger us to bind again, but it gives an easy way to only
+                        // load the icon once its needed, so its probably worth it.
+                        setIcon(mEntry.icon);
+                    }
+                });
+            }
             super.onBindViewHolder(holder);
         }
     }
diff --git a/src/com/android/settings/notification/NotificationStation.java b/src/com/android/settings/notification/NotificationStation.java
index b871848..75acdc3 100644
--- a/src/com/android/settings/notification/NotificationStation.java
+++ b/src/com/android/settings/notification/NotificationStation.java
@@ -87,7 +87,7 @@
         }
     };
 
-    private NotificationListenerService mListener = new NotificationListenerService() {
+    private final NotificationListenerService mListener = new NotificationListenerService() {
         @Override
         public void onNotificationPosted(StatusBarNotification sbn, RankingMap ranking) {
             logd("onNotificationPosted: %s", sbn.getNotification());
@@ -135,22 +135,16 @@
         mPm = mContext.getPackageManager();
         mNoMan = INotificationManager.Stub.asInterface(
                 ServiceManager.getService(Context.NOTIFICATION_SERVICE));
-        try {
-            mListener.registerAsSystemService(mContext, new ComponentName(mContext.getPackageName(),
-                    this.getClass().getCanonicalName()), ActivityManager.getCurrentUser());
-        } catch (RemoteException e) {
-            Log.e(TAG, "Cannot register listener", e);
-        }
     }
 
     @Override
-    public void onDetach() {
+    public void onPause() {
         try {
             mListener.unregisterAsSystemService();
         } catch (RemoteException e) {
             Log.e(TAG, "Cannot unregister listener", e);
         }
-        super.onDetach();
+        super.onPause();
     }
 
     @Override
@@ -171,6 +165,12 @@
     public void onResume() {
         logd("onResume()");
         super.onResume();
+        try {
+            mListener.registerAsSystemService(mContext, new ComponentName(mContext.getPackageName(),
+                    this.getClass().getCanonicalName()), ActivityManager.getCurrentUser());
+        } catch (RemoteException e) {
+            Log.e(TAG, "Cannot register listener", e);
+        }
         refreshList();
     }
 
@@ -205,17 +205,17 @@
     }
 
     private static String getTitleString(Notification n) {
-        String title = null;
+        CharSequence title = null;
         if (n.extras != null) {
-            title = n.extras.getString(Notification.EXTRA_TITLE);
+            title = n.extras.getCharSequence(Notification.EXTRA_TITLE);
             if (TextUtils.isEmpty(title)) {
-                title = n.extras.getString(Notification.EXTRA_TEXT);
+                title = n.extras.getCharSequence(Notification.EXTRA_TEXT);
             }
         }
         if (TextUtils.isEmpty(title) && !TextUtils.isEmpty(n.tickerText)) {
-            title = n.tickerText.toString();
+            title = n.tickerText;
         }
-        return title;
+        return String.valueOf(title);
     }
 
     private static String formatPendingIntent(PendingIntent pi) {
diff --git a/src/com/android/settings/notification/ZenModeAutomationSettings.java b/src/com/android/settings/notification/ZenModeAutomationSettings.java
index df19c60..f1546aa 100644
--- a/src/com/android/settings/notification/ZenModeAutomationSettings.java
+++ b/src/com/android/settings/notification/ZenModeAutomationSettings.java
@@ -46,7 +46,9 @@
 
 import java.lang.ref.WeakReference;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Comparator;
+import java.util.Map;
 
 public class ZenModeAutomationSettings extends ZenModeSettingsBase {
 
@@ -111,15 +113,15 @@
                 AutomaticZenRule rule = new AutomaticZenRule(ruleName, ri.serviceComponent,
                         ri.defaultConditionId, NotificationManager.INTERRUPTION_FILTER_PRIORITY,
                         true);
-                AutomaticZenRule savedRule = addZenRule(rule);
-                if (savedRule != null) {
-                    startActivity(getRuleIntent(ri.settingsAction, null, savedRule.getId()));
+                String savedRuleId = addZenRule(rule);
+                if (savedRuleId != null) {
+                    startActivity(getRuleIntent(ri.settingsAction, null, savedRuleId));
                 }
             }
         }.show();
     }
 
-    private void showDeleteRuleDialog(final String ruleId, final String ruleName) {
+    private void showDeleteRuleDialog(final String ruleId, final CharSequence ruleName) {
         new AlertDialog.Builder(mContext)
                 .setMessage(getString(R.string.zen_mode_delete_rule_confirmation, ruleName))
                 .setNegativeButton(R.string.cancel, null)
@@ -147,8 +149,9 @@
         return intent;
     }
 
-    private AutomaticZenRule[] sortedRules() {
-        final AutomaticZenRule[] rt = mRules.toArray(new AutomaticZenRule[mRules.size()]);
+    private Map.Entry<String,AutomaticZenRule>[] sortedRules() {
+        final Map.Entry<String,AutomaticZenRule>[] rt =
+                mRules.toArray(new Map.Entry[mRules.size()]);
         Arrays.sort(rt, RULE_COMPARATOR);
         return rt;
     }
@@ -156,8 +159,8 @@
     private void updateControls() {
         final PreferenceScreen root = getPreferenceScreen();
         root.removeAll();
-        final AutomaticZenRule[] sortedRules = sortedRules();
-        for (AutomaticZenRule sortedRule : sortedRules) {
+        final Map.Entry<String,AutomaticZenRule>[] sortedRules = sortedRules();
+        for (Map.Entry<String,AutomaticZenRule> sortedRule : sortedRules) {
             ZenRulePreference pref = new ZenRulePreference(getPrefContext(), sortedRule);
             if (pref.appExists) {
                 root.addPreference(pref);
@@ -247,15 +250,17 @@
         return null;
     }
 
-    private static final Comparator<AutomaticZenRule> RULE_COMPARATOR =
-            new Comparator<AutomaticZenRule>() {
+    private static final Comparator<Map.Entry<String,AutomaticZenRule>> RULE_COMPARATOR =
+            new Comparator<Map.Entry<String,AutomaticZenRule>>() {
         @Override
-        public int compare(AutomaticZenRule lhs, AutomaticZenRule rhs) {
-            int byDate = Long.compare(lhs.getCreationTime(), rhs.getCreationTime());
+        public int compare(Map.Entry<String,AutomaticZenRule> lhs,
+                Map.Entry<String,AutomaticZenRule> rhs) {
+            int byDate = Long.compare(lhs.getValue().getCreationTime(),
+                    rhs.getValue().getCreationTime());
             if (byDate != 0) {
                 return byDate;
             } else {
-                return key(lhs).compareTo(key(rhs));
+                return key(lhs.getValue()).compareTo(key(rhs.getValue()));
             }
         }
 
@@ -263,20 +268,22 @@
             final int type = ZenModeConfig.isValidScheduleConditionId(rule.getConditionId()) ? 1
                     : ZenModeConfig.isValidEventConditionId(rule.getConditionId()) ? 2
                     : 3;
-            return type + rule.getName();
+            return type + rule.getName().toString();
         }
     };
 
     private class ZenRulePreference extends Preference {
-        final String mName;
+        final CharSequence mName;
         final String mId;
         final boolean appExists;
 
-        public ZenRulePreference(Context context, final AutomaticZenRule rule) {
+        public ZenRulePreference(Context context,
+                final Map.Entry<String, AutomaticZenRule> ruleEntry) {
             super(context);
 
+            final AutomaticZenRule rule = ruleEntry.getValue();
             mName = rule.getName();
-            mId = rule.getId();
+            mId = ruleEntry.getKey();
 
             final boolean isSchedule = ZenModeConfig.isValidScheduleConditionId(
                     rule.getConditionId());
diff --git a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
index 501a260..d251580 100644
--- a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
+++ b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
@@ -123,7 +123,7 @@
                 if (zenMode == mRule.getInterruptionFilter()) return false;
                 if (DEBUG) Log.d(TAG, "onPrefChange zenMode=" + zenMode);
                 mRule.setInterruptionFilter(zenMode);
-                setZenRule(mRule);
+                setZenRule(mId, mRule);
                 return true;
             }
         });
@@ -166,7 +166,7 @@
         MetricsLogger.action(mContext, MetricsEvent.ACTION_ZEN_ENABLE_RULE, enabled);
         if (DEBUG) Log.d(TAG, "onSwitchChanged enabled=" + enabled);
         mRule.setEnabled(enabled);
-        setZenRule(mRule);
+        setZenRule(mId, mRule);
         if (enabled) {
             final int toastText = getEnabledToastText();
             if (toastText != 0) {
@@ -182,7 +182,7 @@
 
     protected void updateRule(Uri newConditionId) {
         mRule.setConditionId(newConditionId);
-        setZenRule(mRule);
+        setZenRule(mId, mRule);
     }
 
     @Override
@@ -219,7 +219,7 @@
             @Override
             public void onOk(String ruleName) {
                 mRule.setName(ruleName);
-                setZenRule(mRule);
+                setZenRule(mId, mRule);
             }
         }.show();
     }
@@ -243,7 +243,7 @@
                     public void onClick(DialogInterface dialog, int which) {
                         MetricsLogger.action(mContext, MetricsEvent.ACTION_ZEN_DELETE_RULE_OK);
                         mDeleting = true;
-                        removeZenRule(mRule.getId());
+                        removeZenRule(mId);
                     }
                 })
                 .show();
diff --git a/src/com/android/settings/notification/ZenModeSettingsBase.java b/src/com/android/settings/notification/ZenModeSettingsBase.java
index ec1426d..7864244 100644
--- a/src/com/android/settings/notification/ZenModeSettingsBase.java
+++ b/src/com/android/settings/notification/ZenModeSettingsBase.java
@@ -31,7 +31,10 @@
 
 import com.android.settings.RestrictedSettingsFragment;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 abstract public class ZenModeSettingsBase extends RestrictedSettingsFragment {
     protected static final String TAG = "ZenModeSettings";
@@ -41,7 +44,7 @@
     private final SettingsObserver mSettingsObserver = new SettingsObserver();
 
     protected Context mContext;
-    protected List<AutomaticZenRule> mRules;
+    protected Set<Map.Entry<String, AutomaticZenRule>> mRules;
     protected int mZenMode;
 
     abstract protected void onZenModeChanged();
@@ -92,16 +95,17 @@
         }
     }
 
-    protected AutomaticZenRule addZenRule(AutomaticZenRule rule) {
+    protected String addZenRule(AutomaticZenRule rule) {
+        String id = NotificationManager.from(mContext).addAutomaticZenRule(rule);
         final AutomaticZenRule savedRule =
-                NotificationManager.from(mContext).addAutomaticZenRule(rule);
+                NotificationManager.from(mContext).getAutomaticZenRule(id);
         maybeRefreshRules(savedRule != null, true);
-        return savedRule;
+        return id;
     }
 
-    protected boolean setZenRule(AutomaticZenRule rule) {
+    protected boolean setZenRule(String id, AutomaticZenRule rule) {
         final boolean success =
-                NotificationManager.from(mContext).updateAutomaticZenRule(rule);
+                NotificationManager.from(mContext).updateAutomaticZenRule(id, rule);
         maybeRefreshRules(success, true);
         return success;
     }
@@ -127,8 +131,10 @@
         NotificationManager.from(mContext).setZenMode(zenMode, conditionId, TAG);
     }
 
-    private List<AutomaticZenRule> getZenModeRules() {
-        return NotificationManager.from(mContext).getAutomaticZenRules();
+    private Set<Map.Entry<String, AutomaticZenRule>> getZenModeRules() {
+        Map<String, AutomaticZenRule> ruleMap
+                = NotificationManager.from(mContext).getAutomaticZenRules();
+        return ruleMap.entrySet();
     }
 
     private final class SettingsObserver extends ContentObserver {
diff --git a/src/com/android/settings/notification/ZenRuleNameDialog.java b/src/com/android/settings/notification/ZenRuleNameDialog.java
index 2c0ee42..f69198b 100644
--- a/src/com/android/settings/notification/ZenRuleNameDialog.java
+++ b/src/com/android/settings/notification/ZenRuleNameDialog.java
@@ -31,10 +31,10 @@
 
     private final AlertDialog mDialog;
     private final EditText mEditText;
-    private final String mOriginalRuleName;
+    private final CharSequence mOriginalRuleName;
     private final boolean mIsNew;
 
-    public ZenRuleNameDialog(Context context, String ruleName) {
+    public ZenRuleNameDialog(Context context, CharSequence ruleName) {
         mIsNew = ruleName == null;
         mOriginalRuleName = ruleName;
         final View v = LayoutInflater.from(context).inflate(R.layout.zen_rule_name, null, false);
@@ -52,7 +52,7 @@
                     public void onClick(DialogInterface dialog, int which) {
                         final String newName = trimmedText();
                         if (!mIsNew && mOriginalRuleName != null
-                                && mOriginalRuleName.equalsIgnoreCase(newName)) {
+                                && mOriginalRuleName.equals(newName)) {
                             return;  // no change to an existing rule, just dismiss
                         }
                         onOk(newName);
diff --git a/src/com/android/settings/search/Ranking.java b/src/com/android/settings/search/Ranking.java
index e961474..94b010c 100644
--- a/src/com/android/settings/search/Ranking.java
+++ b/src/com/android/settings/search/Ranking.java
@@ -116,7 +116,6 @@
 
         // Other wireless settinfs
         sRankMap.put(WirelessSettings.class.getName(), RANK_WIRELESS);
-        sRankMap.put(WifiCallingSettings.class.getName(), RANK_WIRELESS);
 
         // Home
         sRankMap.put(HomeSettings.class.getName(), RANK_HOME);
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index 6aeb2a6..73784b2 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -320,13 +320,6 @@
                         LegalSettings.class.getName(),
                         R.drawable.ic_settings_about));
 
-        sResMap.put(WifiCallingSettings.class.getName(),
-                new SearchIndexableResource(
-                        Ranking.getRankForClassName(WifiCallingSettings.class.getName()),
-                        R.xml.wifi_calling_settings,
-                        WifiCallingSettings.class.getName(),
-                        R.drawable.ic_settings_wireless));
-
         sResMap.put(ZenModeVisualInterruptionSettings.class.getName(),
                 new SearchIndexableResource(
                         Ranking.getRankForClassName(
diff --git a/src/com/android/settings/wifi/p2p/WifiP2pPersistentGroup.java b/src/com/android/settings/wifi/p2p/WifiP2pPersistentGroup.java
index 1869e60..520be8e 100644
--- a/src/com/android/settings/wifi/p2p/WifiP2pPersistentGroup.java
+++ b/src/com/android/settings/wifi/p2p/WifiP2pPersistentGroup.java
@@ -28,12 +28,7 @@
     public WifiP2pPersistentGroup(Context context, WifiP2pGroup group) {
         super(context);
         mGroup = group;
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder view) {
         setTitle(mGroup.getNetworkName());
-        super.onBindViewHolder(view);
     }
 
     int getNetworkId() {