Merge "Cleaned up the deprecated APIs" into udc-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3efb218..6c268aa 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -10894,10 +10894,13 @@
 
     <!-- [CHAR LIMIT=32] Name of MTE page in "Developer Options" and heading of page. -->
     <string name="development_memtag_page_title">Memory Tagging Extension</string>
-    <!-- [CHAR LIMIT=52] Label for button to turn on / off MTE protection.-->
+    <!-- [CHAR LIMIT=NONE] Explanation shown under heading of the page.-->
     <string name="development_memtag_intro">Memory Tagging Extension (MTE) makes it easier to find memory safety issues in your app and make native code in it more secure.</string>
+    <!-- [CHAR LIMIT=NONE] Further explanation shown at the bottom of the page.-->
     <string name="development_memtag_footer">Turning on MTE might cause slower device performance.</string>
+    <!-- [CHAR LIMIT=NONE] String for link to learn more about MTE.-->
     <string name="development_memtag_learn_more">Learn more about MTE</string>
+    <!-- [CHAR LIMIT=52] Label for button to turn on / off MTE protection.-->
     <string name="development_memtag_toggle">Enable MTE until you turn it off</string>
     <!-- [CHAR LIMIT=NONE] Message shown in dialog prompting user to reboot device to turn on MTE.-->
     <string name="development_memtag_reboot_message_on">You\u0027ll need to restart your device to turn on MTE.</string>
diff --git a/res/xml/bubble_notification_settings.xml b/res/xml/bubble_notification_settings.xml
index 7cf8e53..3e137d7 100644
--- a/res/xml/bubble_notification_settings.xml
+++ b/res/xml/bubble_notification_settings.xml
@@ -27,6 +27,7 @@
             android:key="bubbles_illustration"
             settings:searchable="false"
             app:lottie_rawRes="@raw/lottie_bubbles"
+            app:lottie_cacheComposition="false"
             settings:dynamicColor="true"
             settings:controller="com.android.settings.notification.BubbleNotificationIllustrationPreferenceController"/>
 
diff --git a/src/com/android/settings/notification/zen/ZenModeAddBypassingAppsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeAddBypassingAppsPreferenceController.java
index 5cffb9c..9664610 100644
--- a/src/com/android/settings/notification/zen/ZenModeAddBypassingAppsPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModeAddBypassingAppsPreferenceController.java
@@ -53,6 +53,7 @@
 public class ZenModeAddBypassingAppsPreferenceController extends AbstractPreferenceController
         implements PreferenceControllerMixin {
 
+    public static final String KEY_NO_APPS = "add_none";
     private static final String KEY = "zen_mode_non_bypassing_apps_list";
     private static final String KEY_ADD = "zen_mode_bypassing_apps_add";
     private final NotificationBackend mNotificationBackend;
@@ -118,9 +119,7 @@
         }
 
         ApplicationsState.AppFilter filter = ApplicationsState.FILTER_ALL_ENABLED;
-        List<ApplicationsState.AppEntry> apps = mAppSession.rebuild(filter,
-                ApplicationsState.ALPHA_COMPARATOR);
-        updateAppList(apps);
+        mAppSession.rebuild(filter, ApplicationsState.ALPHA_COMPARATOR);
     }
 
     // Set the icon for the given preference to the entry icon from cache if available, or look
@@ -153,57 +152,63 @@
             mPreferenceScreen.addPreference(mPreferenceCategory);
         }
 
-        List<Preference> appsWithNoBypassingDndNotificationChannels = new ArrayList<>();
-        for (ApplicationsState.AppEntry entry : apps) {
-            String pkg = entry.info.packageName;
-            final int appChannels = mNotificationBackend.getChannelCount(pkg, entry.info.uid);
+        boolean doAnyAppsPassCriteria = false;
+        for (ApplicationsState.AppEntry app : apps) {
+            String pkg = app.info.packageName;
+            final String key = getKey(pkg, app.info.uid);
+            final int appChannels = mNotificationBackend.getChannelCount(pkg, app.info.uid);
             final int appChannelsBypassingDnd = mNotificationBackend
-                    .getNotificationChannelsBypassingDnd(pkg, entry.info.uid).getList().size();
+                    .getNotificationChannelsBypassingDnd(pkg, app.info.uid).getList().size();
             if (appChannelsBypassingDnd == 0 && appChannels > 0) {
-                final String key = ZenModeAllBypassingAppsPreferenceController.getKey(pkg);
-                Preference pref = mPreferenceCategory.findPreference("");
-                if (pref == null) {
+                doAnyAppsPassCriteria = true;
+            }
+
+            Preference pref = mPreferenceCategory.findPreference(key);
+
+            if (pref == null) {
+                if (appChannelsBypassingDnd == 0 && appChannels > 0) {
+                    // does not exist but should
                     pref = new AppPreference(mPrefContext);
                     pref.setKey(key);
                     pref.setOnPreferenceClickListener(preference -> {
                         Bundle args = new Bundle();
-                        args.putString(AppInfoBase.ARG_PACKAGE_NAME, entry.info.packageName);
-                        args.putInt(AppInfoBase.ARG_PACKAGE_UID, entry.info.uid);
+                        args.putString(AppInfoBase.ARG_PACKAGE_NAME, app.info.packageName);
+                        args.putInt(AppInfoBase.ARG_PACKAGE_UID, app.info.uid);
                         new SubSettingLauncher(mContext)
                                 .setDestination(AppChannelsBypassingDndSettings.class.getName())
                                 .setArguments(args)
                                 .setResultListener(mHostFragment, 0)
-                                .setUserHandle(new UserHandle(UserHandle.getUserId(entry.info.uid)))
+                                .setUserHandle(new UserHandle(UserHandle.getUserId(app.info.uid)))
                                 .setSourceMetricsCategory(
                                         SettingsEnums.NOTIFICATION_ZEN_MODE_OVERRIDING_APP)
                                 .launch();
                         return true;
                     });
+                    pref.setTitle(BidiFormatter.getInstance().unicodeWrap(app.label));
+                    updateIcon(pref, app);
+                    mPreferenceCategory.addPreference(pref);
                 }
-                pref.setTitle(BidiFormatter.getInstance().unicodeWrap(entry.label));
-                updateIcon(pref, entry);
-                appsWithNoBypassingDndNotificationChannels.add(pref);
+            } else if (appChannelsBypassingDnd != 0 || appChannels == 0) {
+                // exists but shouldn't anymore
+                mPreferenceCategory.removePreference(pref);
             }
         }
 
-        if (appsWithNoBypassingDndNotificationChannels.size() == 0) {
-            Preference pref = mPreferenceCategory.findPreference(
-                    ZenModeAllBypassingAppsPreferenceController.KEY_NO_APPS);
+        Preference pref = mPreferenceCategory.findPreference(KEY_NO_APPS);
+        if (!doAnyAppsPassCriteria) {
             if (pref == null) {
                 pref = new Preference(mPrefContext);
-                pref.setKey(ZenModeAllBypassingAppsPreferenceController.KEY_NO_APPS);
-                pref.setTitle(R.string.zen_mode_bypassing_apps_subtext_none);
+                pref.setKey(KEY_NO_APPS);
+                pref.setTitle(R.string.zen_mode_bypassing_apps_none);
             }
             mPreferenceCategory.addPreference(pref);
+        } else if (pref != null) {
+            mPreferenceCategory.removePreference(pref);
         }
+    }
 
-        if (ZenModeAllBypassingAppsPreferenceController.hasAppListChanged(
-                appsWithNoBypassingDndNotificationChannels, mPreferenceCategory)) {
-            mPreferenceCategory.removeAll();
-            for (Preference prefToAdd : appsWithNoBypassingDndNotificationChannels) {
-                mPreferenceCategory.addPreference(prefToAdd);
-            }
-        }
+    static String getKey(String pkg, int uid) {
+        return "add|" + pkg + "|" + uid;
     }
 
     private final ApplicationsState.Callbacks mAppSessionCallbacks =
@@ -211,12 +216,12 @@
 
                 @Override
                 public void onRunningStateChanged(boolean running) {
-                    updateAppList();
+
                 }
 
                 @Override
                 public void onPackageListChanged() {
-                    updateAppList();
+
                 }
 
                 @Override
@@ -231,7 +236,7 @@
 
                 @Override
                 public void onPackageSizeChanged(String packageName) {
-                    updateAppList();
+
                 }
 
                 @Override
@@ -239,7 +244,7 @@
 
                 @Override
                 public void onLauncherInfoChanged() {
-                    updateAppList();
+
                 }
 
                 @Override
diff --git a/src/com/android/settings/notification/zen/ZenModeAllBypassingAppsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeAllBypassingAppsPreferenceController.java
index 4cbfacb..f4b7036 100644
--- a/src/com/android/settings/notification/zen/ZenModeAllBypassingAppsPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModeAllBypassingAppsPreferenceController.java
@@ -44,7 +44,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Objects;
 
 
 /**
@@ -52,7 +51,7 @@
  */
 public class ZenModeAllBypassingAppsPreferenceController extends AbstractPreferenceController
         implements PreferenceControllerMixin {
-    public static final String KEY_NO_APPS = getKey("none");
+    public static final String KEY_NO_APPS = "all_none";
     private static final String KEY = "zen_mode_bypassing_apps_list";
 
     private final NotificationBackend mNotificationBackend;
@@ -109,9 +108,7 @@
         }
 
         ApplicationsState.AppFilter filter = ApplicationsState.FILTER_ALL_ENABLED;
-        List<ApplicationsState.AppEntry> apps = mAppSession.rebuild(filter,
-                ApplicationsState.ALPHA_COMPARATOR);
-        updateAppList(apps);
+        mAppSession.rebuild(filter, ApplicationsState.ALPHA_COMPARATOR);
     }
 
     // Set the icon for the given preference to the entry icon from cache if available, or look
@@ -138,17 +135,21 @@
             return;
         }
 
-        List<Preference> appsBypassingDnd = new ArrayList<>();
+        boolean doAnyAppsPassCriteria = false;
         for (ApplicationsState.AppEntry app : apps) {
             String pkg = app.info.packageName;
+            final String key = getKey(pkg, app.info.uid);
             final int appChannels = mNotificationBackend.getChannelCount(pkg, app.info.uid);
             final int appChannelsBypassingDnd = mNotificationBackend
                     .getNotificationChannelsBypassingDnd(pkg, app.info.uid).getList().size();
             if (appChannelsBypassingDnd > 0) {
-                final String key = getKey(pkg);
-                // re-use previously created preference when possible
-                Preference pref = mPreferenceCategory.findPreference(key);
-                if (pref == null) {
+                doAnyAppsPassCriteria = true;
+            }
+
+            Preference pref = mPreferenceCategory.findPreference(key);
+            if (pref == null) {
+                if (appChannelsBypassingDnd > 0) {
+                    // does not exist but should
                     pref = new AppPreference(mPrefContext);
                     pref.setKey(key);
                     pref.setOnPreferenceClickListener(preference -> {
@@ -165,59 +166,40 @@
                                 .launch();
                         return true;
                     });
+                    pref.setTitle(BidiFormatter.getInstance().unicodeWrap(app.label));
+                    updateIcon(pref, app);
+                    if (appChannels > appChannelsBypassingDnd) {
+                        pref.setSummary(R.string.zen_mode_bypassing_apps_summary_some);
+                    } else {
+                        pref.setSummary(R.string.zen_mode_bypassing_apps_summary_all);
+                    }
+                    mPreferenceCategory.addPreference(pref);
                 }
-                pref.setTitle(BidiFormatter.getInstance().unicodeWrap(app.label));
-                updateIcon(pref, app);
-                if (appChannels > appChannelsBypassingDnd) {
-                    pref.setSummary(R.string.zen_mode_bypassing_apps_summary_some);
-                } else {
-                    pref.setSummary(R.string.zen_mode_bypassing_apps_summary_all);
-                }
-
-                appsBypassingDnd.add(pref);
+            }
+            else if (appChannelsBypassingDnd == 0) {
+                // exists but shouldn't anymore
+                mPreferenceCategory.removePreference(pref);
             }
         }
 
-        if (appsBypassingDnd.size() == 0) {
-            Preference pref = mPreferenceCategory.findPreference(KEY_NO_APPS);
+        Preference pref = mPreferenceCategory.findPreference(KEY_NO_APPS);
+        if (!doAnyAppsPassCriteria) {
             if (pref == null) {
                 pref = new Preference(mPrefContext);
                 pref.setKey(KEY_NO_APPS);
                 pref.setTitle(R.string.zen_mode_bypassing_apps_none);
             }
-            appsBypassingDnd.add(pref);
+            mPreferenceCategory.addPreference(pref);
+        } else if (pref != null) {
+            mPreferenceCategory.removePreference(pref);
         }
-
-        if (hasAppListChanged(appsBypassingDnd, mPreferenceCategory)) {
-            mPreferenceCategory.removeAll();
-            for (Preference prefToAdd : appsBypassingDnd) {
-                mPreferenceCategory.addPreference(prefToAdd);
-            }
-        }
-    }
-
-    static boolean hasAppListChanged(List<Preference> newAppPreferences,
-            PreferenceCategory preferenceCategory) {
-        if (newAppPreferences.size() != preferenceCategory.getPreferenceCount()) {
-            return true;
-        }
-
-        for (int i = 0; i < newAppPreferences.size(); i++) {
-            Preference newAppPref = newAppPreferences.get(i);
-            Preference pref = preferenceCategory.getPreference(i);
-            if (!Objects.equals(newAppPref.getKey(), pref.getKey())) {
-                return true;
-            }
-        }
-        return false;
-
     }
 
     /**
      * Create a unique key to idenfity an AppPreference
      */
-    static String getKey(String pkg) {
-        return pkg;
+    static String getKey(String pkg, int uid) {
+        return "all|" + pkg + "|" + uid;
     }
 
     private final ApplicationsState.Callbacks mAppSessionCallbacks =
@@ -225,12 +207,10 @@
 
                 @Override
                 public void onRunningStateChanged(boolean running) {
-                    updateAppList();
                 }
 
                 @Override
                 public void onPackageListChanged() {
-                    updateAppList();
                 }
 
                 @Override
@@ -240,12 +220,10 @@
 
                 @Override
                 public void onPackageIconChanged() {
-                    updateAppList();
                 }
 
                 @Override
                 public void onPackageSizeChanged(String packageName) {
-                    updateAppList();
                 }
 
                 @Override
@@ -253,7 +231,6 @@
 
                 @Override
                 public void onLauncherInfoChanged() {
-                    updateAppList();
                 }
 
                 @Override
diff --git a/src/com/android/settings/spa/SettingsSpaEnvironment.kt b/src/com/android/settings/spa/SettingsSpaEnvironment.kt
index 55c0f83..87a916a 100644
--- a/src/com/android/settings/spa/SettingsSpaEnvironment.kt
+++ b/src/com/android/settings/spa/SettingsSpaEnvironment.kt
@@ -40,9 +40,9 @@
 import com.android.settings.spa.system.AppLanguagesPageProvider
 import com.android.settings.spa.system.LanguageAndInputPageProvider
 import com.android.settings.spa.system.SystemMainPageProvider
-import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProviderRepository
 import com.android.settingslib.spa.framework.common.SpaEnvironment
+import com.android.settingslib.spa.framework.common.createSettingsPage
 import com.android.settingslib.spaprivileged.template.app.TogglePermissionAppListProvider
 import com.android.settingslib.spaprivileged.template.app.TogglePermissionAppListTemplate
 
@@ -83,7 +83,7 @@
                 NetworkAndInternetPageProvider,
                 ) + togglePermissionAppListTemplate.createPageProviders(),
             rootPages = listOf(
-                SettingsPage.create(HomePageProvider.name),
+                HomePageProvider.createSettingsPage()
             ),
         )
     }
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeAddBypassingAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeAddBypassingAppsPreferenceControllerTest.java
index 52f2c51..2569ca3 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeAddBypassingAppsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModeAddBypassingAppsPreferenceControllerTest.java
@@ -138,8 +138,9 @@
 
         Preference pref = prefCaptor.getValue();
         assertThat(pref.getKey()).isEqualTo(
-                ZenModeAllBypassingAppsPreferenceController.getKey(
-                        appWithChannelsNoneBypassing.info.packageName));
+                ZenModeAddBypassingAppsPreferenceController.getKey(
+                        appWithChannelsNoneBypassing.info.packageName,
+                        appWithChannelsNoneBypassing.info.uid));
     }
 
     @Test
@@ -159,6 +160,6 @@
 
         Preference pref = prefCaptor.getValue();
         assertThat(pref.getKey()).isEqualTo(
-                ZenModeAllBypassingAppsPreferenceController.KEY_NO_APPS);
+                ZenModeAddBypassingAppsPreferenceController.KEY_NO_APPS);
     }
 }