Merge "Import translations. DO NOT MERGE ANYWHERE" into sc-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 5c651b9..4f12b79 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7163,15 +7163,13 @@
     <!-- Title for Guest user [CHAR LIMIT=35] -->
     <string name="user_guest">Guest</string>
     <!-- Label for item to exit guest mode [CHAR LIMIT=35] -->
-    <string name="user_clear_guest_menu">Clear guest data</string>
-    <!-- Label for item to exit guest mode [CHAR LIMIT=35] -->
-    <string name="user_exit_guest_menu">End guest session</string>
+    <string name="user_exit_guest_title">Remove guest</string>
     <!-- Title of dialog to user to confirm exiting guest. [CHAR LIMIT=50] -->
-    <string name="user_exit_guest_confirm_title">End guest session?</string>
+    <string name="user_exit_guest_confirm_title">Remove guest?</string>
     <!-- Message to user to confirm exiting guest. [CHAR LIMIT=none] -->
     <string name="user_exit_guest_confirm_message">All apps and data in this session will be deleted.</string>
     <!-- Label for button in confirmation dialog when exiting guest session [CHAR LIMIT=35] -->
-    <string name="user_exit_guest_dialog_remove">End session</string>
+    <string name="user_exit_guest_dialog_remove">Remove</string>
 
     <!-- Title of preference to enable calling[CHAR LIMIT=40] -->
     <string name="user_enable_calling">Turn on phone calls</string>
@@ -8820,6 +8818,22 @@
     <string name="notif_type_alerting">Alerting notifications</string>
     <string name="notif_type_silent">Silent notifications</string>
 
+    <!-- Per notification listener, launches a list of apps whose notifications this listener cannot see -->
+    <string name="notif_listener_excluded_title">Apps that are not bridged to this listener</string>
+
+    <!-- Per notification listener, when the listener can see notifications from all apps -->
+    <string name="notif_listener_excluded_summary_zero">All apps are bridged</string>
+
+    <!-- Per notification listener, a summary of how many apps this listener cannot see
+     notifications from -->
+    <plurals name="notif_listener_excluded_summary_nonzero">
+        <item quantity="one">%d app is not bridged</item>
+        <item quantity="other">%d apps are not bridged</item>
+    </plurals>
+
+    <!-- Per notification listener, a list of apps whose notifications this listener cannot see -->
+    <string name="notif_listener_excluded_app_title">Bridged apps</string>
+
     <!-- Title for managing VR (virtual reality) helper services. [CHAR LIMIT=50] -->
     <string name="vr_listeners_title">VR helper services</string>
 
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 398fa4d..67d857f 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -592,11 +592,6 @@
             android:title="@string/show_notification_channel_warnings"
             android:summary="@string/show_notification_channel_warnings_summary" />
 
-        <SwitchPreference
-            android:key="asst_feedback_indicator"
-            android:title="@string/asst_feedback_indicator_title"
-            settings:controller="com.android.settings.notification.AssistantFeedbackPreferenceController" />
-
         <com.android.settingslib.widget.LayoutPreference
             android:key="asst_importance_reset"
             android:title="@string/asst_importance_reset_title"
diff --git a/res/xml/notification_access_bridged_apps_settings.xml b/res/xml/notification_access_bridged_apps_settings.xml
new file mode 100644
index 0000000..590a468
--- /dev/null
+++ b/res/xml/notification_access_bridged_apps_settings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2021 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.
+  -->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:key="nonbridged_apps"
+    android:title="@string/notif_listener_excluded_app_title"
+    settings:controller="com.android.settings.applications.specialaccess.notificationaccess.BridgedAppsPreferenceController"
+    settings:searchable="false">
+</PreferenceScreen>
diff --git a/res/xml/notification_access_permission_details.xml b/res/xml/notification_access_permission_details.xml
index f7d928d..edac955 100644
--- a/res/xml/notification_access_permission_details.xml
+++ b/res/xml/notification_access_permission_details.xml
@@ -41,11 +41,11 @@
         style="@style/SettingsMultiSelectListPreference"
         settings:controller="com.android.settings.applications.specialaccess.notificationaccess.TypeFilterPreferenceController"/>/>
 
-    <PreferenceCategory
-        android:key="advanced"
-        android:order="50"
-        settings:initialExpandedChildrenCount="0">
+        <Preference
+            android:key="bridged_apps"
+            android:title="@string/notif_listener_excluded_app_title"
+            android:fragment="com.android.settings.applications.specialaccess.notificationaccess.BridgedAppsSettings"
+            settings:searchable="false"
+            settings:controller="com.android.settings.applications.specialaccess.notificationaccess.BridgedAppsPreferenceController" />
 
-
-    </PreferenceCategory>
 </PreferenceScreen>
\ No newline at end of file
diff --git a/src/com/android/settings/applications/specialaccess/notificationaccess/BridgedAppsPreferenceController.java b/src/com/android/settings/applications/specialaccess/notificationaccess/BridgedAppsPreferenceController.java
new file mode 100644
index 0000000..9186bdb1
--- /dev/null
+++ b/src/com/android/settings/applications/specialaccess/notificationaccess/BridgedAppsPreferenceController.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2021 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.specialaccess.notificationaccess;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.VersionedPackage;
+import android.os.UserHandle;
+import android.service.notification.NotificationListenerFilter;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+
+import com.android.settings.applications.AppStateBaseBridge;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.notification.NotificationBackend;
+import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.ApplicationsState.AppEntry;
+import com.android.settingslib.applications.ApplicationsState.AppFilter;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+
+import java.util.ArrayList;
+import java.util.Set;
+import java.util.TreeSet;
+
+
+public class BridgedAppsPreferenceController extends BasePreferenceController implements
+        LifecycleObserver, ApplicationsState.Callbacks,
+        AppStateBaseBridge.Callback {
+
+    private ApplicationsState mApplicationsState;
+    private ApplicationsState.Session mSession;
+    private AppFilter mFilter;
+    private PreferenceScreen mScreen;
+
+    private ComponentName mCn;
+    private int mUserId;
+    private NotificationBackend mNm;
+    private NotificationListenerFilter mNlf;
+
+    public BridgedAppsPreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    public BridgedAppsPreferenceController setAppState(ApplicationsState appState) {
+        mApplicationsState = appState;
+        return this;
+    }
+
+    public BridgedAppsPreferenceController setCn(ComponentName cn) {
+        mCn = cn;
+        return this;
+    }
+
+    public BridgedAppsPreferenceController setUserId(int userId) {
+        mUserId = userId;
+        return this;
+    }
+
+    public BridgedAppsPreferenceController setNm(NotificationBackend nm) {
+        mNm = nm;
+        return this;
+    }
+
+    public BridgedAppsPreferenceController setFilter(AppFilter filter) {
+        mFilter = filter;
+        return this;
+    }
+
+    public BridgedAppsPreferenceController setSession(Lifecycle lifecycle) {
+        mSession = mApplicationsState.newSession(this, lifecycle);
+        return this;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        mScreen = screen;
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+
+    @Override
+    public void onExtraInfoUpdated() {
+        rebuild();
+    }
+
+    @Override
+    public void onRunningStateChanged(boolean running) {
+
+    }
+
+    @Override
+    public void onPackageListChanged() {
+        rebuild();
+    }
+
+    @Override
+    public void onRebuildComplete(ArrayList<AppEntry> apps) {
+        if (apps == null) {
+            return;
+        }
+        mNlf = mNm.getListenerFilter(mCn, mUserId);
+
+        // Create apps key set for removing useless preferences
+        final Set<String> appsKeySet = new TreeSet<>();
+        // Add or update preferences
+        final int N = apps.size();
+        for (int i = 0; i < N; i++) {
+            final AppEntry entry = apps.get(i);
+            if (!shouldAddPreference(entry)) {
+                continue;
+            }
+            final String prefKey = entry.info.packageName + "|" + entry.info.uid;
+            appsKeySet.add(prefKey);
+            SwitchPreference preference = mScreen.findPreference(prefKey);
+            if (preference == null) {
+                preference = new SwitchPreference(mScreen.getContext());
+                preference.setIcon(entry.icon);
+                preference.setTitle(entry.label);
+                preference.setKey(prefKey);
+                mScreen.addPreference(preference);
+            }
+            preference.setOrder(i);
+            preference.setChecked(mNlf.isPackageAllowed(
+                    new VersionedPackage(entry.info.packageName, entry.info.uid)));
+            preference.setOnPreferenceChangeListener(this::onPreferenceChange);
+        }
+
+        // Remove preferences that are no longer existing in the updated list of apps
+        removeUselessPrefs(appsKeySet);
+    }
+
+    @Override
+    public void onPackageIconChanged() {
+        rebuild();
+    }
+
+    @Override
+    public void onPackageSizeChanged(String packageName) {
+
+    }
+
+    @Override
+    public void onAllSizesComputed() {
+    }
+
+    @Override
+    public void onLauncherInfoChanged() {
+    }
+
+    @Override
+    public void onLoadEntriesCompleted() {
+        rebuild();
+    }
+
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if (preference instanceof SwitchPreference) {
+            String packageName = preference.getKey().substring(0, preference.getKey().indexOf("|"));
+            int uid = Integer.parseInt(preference.getKey().substring(
+                    preference.getKey().indexOf("|") + 1));
+            boolean allowlisted = newValue == Boolean.TRUE;
+            mNlf = mNm.getListenerFilter(mCn, mUserId);
+            if (allowlisted) {
+                mNlf.removePackage(new VersionedPackage(packageName, uid));
+            } else {
+                mNlf.addPackage(new VersionedPackage(packageName, uid));
+            }
+            mNm.setListenerFilter(mCn, mUserId, mNlf);
+            return true;
+        }
+        return false;
+    }
+
+    public void rebuild() {
+        final ArrayList<AppEntry> apps = mSession.rebuild(mFilter,
+                ApplicationsState.ALPHA_COMPARATOR);
+        if (apps != null) {
+            onRebuildComplete(apps);
+        }
+    }
+
+    private void removeUselessPrefs(final Set<String> appsKeySet) {
+        final int prefCount = mScreen.getPreferenceCount();
+        String prefKey;
+        if (prefCount > 0) {
+            for (int i = prefCount - 1; i >= 0; i--) {
+                Preference pref = mScreen.getPreference(i);
+                prefKey = pref.getKey();
+                if (!appsKeySet.contains(prefKey)) {
+                    mScreen.removePreference(pref);
+                }
+            }
+        }
+    }
+
+    @VisibleForTesting
+    static boolean shouldAddPreference(AppEntry app) {
+        return app != null && UserHandle.isApp(app.info.uid);
+    }
+}
diff --git a/src/com/android/settings/applications/specialaccess/notificationaccess/BridgedAppsSettings.java b/src/com/android/settings/applications/specialaccess/notificationaccess/BridgedAppsSettings.java
new file mode 100644
index 0000000..d396a01
--- /dev/null
+++ b/src/com/android/settings/applications/specialaccess/notificationaccess/BridgedAppsSettings.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2021 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.specialaccess.notificationaccess;
+
+import static com.android.settings.applications.AppInfoBase.ARG_PACKAGE_NAME;
+
+import android.app.Application;
+import android.app.settings.SettingsEnums;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.notification.NotificationBackend;
+import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.ApplicationsState.AppFilter;
+
+public class BridgedAppsSettings extends DashboardFragment {
+
+    private static final String TAG = "BridgedAppsSettings";
+
+    private static final int MENU_SHOW_SYSTEM = Menu.FIRST + 42;
+    private static final String EXTRA_SHOW_SYSTEM = "show_system";
+
+    private boolean mShowSystem;
+    private AppFilter mFilter;
+
+    private int mUserId;
+    private ComponentName mComponentName;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        mShowSystem = icicle != null && icicle.getBoolean(EXTRA_SHOW_SYSTEM);
+
+        use(BridgedAppsPreferenceController.class).setNm(new NotificationBackend());
+    }
+
+    @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;
+
+                use(BridgedAppsPreferenceController.class).setFilter(mFilter).rebuild();
+
+                break;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putBoolean(EXTRA_SHOW_SYSTEM, mShowSystem);
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+    }
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        mFilter = mShowSystem ? ApplicationsState.FILTER_ALL_ENABLED
+                : ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER;
+
+        final Bundle args = getArguments();
+        Intent intent = (args == null) ?
+                getIntent() : (Intent) args.getParcelable("intent");
+        String cn = args.getString(Settings.EXTRA_NOTIFICATION_LISTENER_COMPONENT_NAME);
+        if (cn != null) {
+            mComponentName = ComponentName.unflattenFromString(cn);
+        }
+        if (intent != null && intent.hasExtra(Intent.EXTRA_USER_HANDLE)) {
+            mUserId = ((UserHandle) intent.getParcelableExtra(
+                    Intent.EXTRA_USER_HANDLE)).getIdentifier();
+        } else {
+            mUserId = UserHandle.myUserId();
+        }
+
+        use(BridgedAppsPreferenceController.class)
+                .setAppState(ApplicationsState.getInstance(
+                        (Application) context.getApplicationContext()))
+                .setCn(mComponentName)
+                .setUserId(mUserId)
+                .setSession(getSettingsLifecycle())
+                .setFilter(mFilter)
+                .rebuild();
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.NOTIFICATION_ACCESS_BRIDGED_APPS;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.notification_access_bridged_apps_settings;
+    }
+}
diff --git a/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetails.java b/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetails.java
index 9f4b693..41a6efa 100644
--- a/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetails.java
+++ b/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetails.java
@@ -32,15 +32,19 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.service.notification.NotificationListenerFilter;
 import android.service.notification.NotificationListenerService;
 import android.util.Log;
 import android.util.Slog;
 
+import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
+import com.android.settings.applications.AppInfoBase;
 import com.android.settings.applications.manageapplications.ManageApplications;
+import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.notification.NotificationBackend;
 import com.android.settingslib.RestrictedLockUtils;
@@ -52,6 +56,8 @@
 public class NotificationAccessDetails extends DashboardFragment {
     private static final String TAG = "NotifAccessDetails";
 
+    private NotificationBackend mNm = new NotificationBackend();
+    private NotificationListenerFilter mNlf;
     private ComponentName mComponentName;
     private CharSequence mServiceName;
     protected PackageInfo mPackageInfo;
@@ -131,6 +137,33 @@
         if (!refreshUi()) {
             setIntentAndFinish(true /* appChanged */);
         }
+        Preference apps = getPreferenceScreen().findPreference(
+                use(BridgedAppsPreferenceController.class).getPreferenceKey());
+        if (apps != null) {
+            mNlf = mNm.getListenerFilter(mComponentName, mUserId);
+            int nonBridgedCount = mNlf.getDisallowedPackages().size();
+            apps.setSummary(nonBridgedCount == 0 ?
+                    getString(R.string.notif_listener_excluded_summary_zero)
+                    : getResources().getQuantityString(
+                            R.plurals.notif_listener_excluded_summary_nonzero,
+                            nonBridgedCount, nonBridgedCount));
+
+            apps.setOnPreferenceClickListener(preference -> {
+                final Bundle args = new Bundle();
+                args.putString(AppInfoBase.ARG_PACKAGE_NAME, mPackageName);
+                args.putString(Settings.EXTRA_NOTIFICATION_LISTENER_COMPONENT_NAME,
+                        mComponentName.flattenToString());
+
+                new SubSettingLauncher(getContext())
+                        .setDestination(BridgedAppsSettings.class.getName())
+                        .setSourceMetricsCategory(getMetricsCategory())
+                        .setTitleRes(R.string.notif_listener_excluded_app_title)
+                        .setArguments(args)
+                        .setUserHandle(UserHandle.of(mUserId))
+                        .launch();
+                return true;
+            });
+        }
     }
 
     protected void setIntentAndFinish(boolean appChanged) {
diff --git a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
index ee99e09..a6a211e 100644
--- a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
+++ b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java
@@ -550,8 +550,11 @@
             voiceNetworkTypeName = getNetworkTypeName(actualVoiceNetworkType);
         }
 
-        if (overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE
-                || overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA) {
+        final boolean isOverrideNwTypeNrAdvancedOrNsa =
+                overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED
+                        || overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA;
+        if (actualDataNetworkType == TelephonyManager.NETWORK_TYPE_LTE
+                && isOverrideNwTypeNrAdvancedOrNsa) {
             dataNetworkTypeName = "NR NSA";
         }
 
diff --git a/src/com/android/settings/fuelgauge/FakeUid.java b/src/com/android/settings/fuelgauge/FakeUid.java
index 309f259..db35e73 100644
--- a/src/com/android/settings/fuelgauge/FakeUid.java
+++ b/src/com/android/settings/fuelgauge/FakeUid.java
@@ -361,6 +361,11 @@
     }
 
     @Override
+    public long[] getCustomMeasuredEnergiesMicroJoules() {
+        return null;
+    }
+
+    @Override
     public long getMobileRadioApWakeupCount(int which) {
         return 0;
     }
diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java
index f4377ea..8a7e737 100644
--- a/src/com/android/settings/notification/NotificationBackend.java
+++ b/src/com/android/settings/notification/NotificationBackend.java
@@ -49,6 +49,7 @@
 import android.text.format.DateUtils;
 import android.util.IconDrawableFactory;
 import android.util.Log;
+import android.util.Slog;
 
 import androidx.annotation.VisibleForTesting;
 
diff --git a/src/com/android/settings/password/ChooseLockSettingsHelper.java b/src/com/android/settings/password/ChooseLockSettingsHelper.java
index 13d3912..29330f5 100644
--- a/src/com/android/settings/password/ChooseLockSettingsHelper.java
+++ b/src/com/android/settings/password/ChooseLockSettingsHelper.java
@@ -312,7 +312,7 @@
         switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(effectiveUserId)) {
             case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
                 launched = launchConfirmationActivity(request, title, header, description,
-                        returnCredentials
+                        returnCredentials || forceVerifyPath
                                 ? ConfirmLockPattern.InternalActivity.class
                                 : ConfirmLockPattern.class, returnCredentials, external,
                                 forceVerifyPath, userId, alternateButton, allowAnyUser,
@@ -325,7 +325,7 @@
             case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
             case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
                 launched = launchConfirmationActivity(request, title, header, description,
-                        returnCredentials
+                        returnCredentials || forceVerifyPath
                                 ? ConfirmLockPassword.InternalActivity.class
                                 : ConfirmLockPassword.class, returnCredentials, external,
                                 forceVerifyPath, userId, alternateButton, allowAnyUser,
diff --git a/src/com/android/settings/users/UserDetailsSettings.java b/src/com/android/settings/users/UserDetailsSettings.java
index 5005399..53d9849 100644
--- a/src/com/android/settings/users/UserDetailsSettings.java
+++ b/src/com/android/settings/users/UserDetailsSettings.java
@@ -243,7 +243,7 @@
                 mDefaultGuestRestrictions = mUserManager.getDefaultGuestRestrictions();
                 mPhonePref.setChecked(
                         !mDefaultGuestRestrictions.getBoolean(UserManager.DISALLOW_OUTGOING_CALLS));
-                mRemoveUserPref.setTitle(R.string.user_exit_guest_menu);
+                mRemoveUserPref.setTitle(R.string.user_exit_guest_title);
             } else {
                 mPhonePref.setChecked(!mUserManager.hasUserRestriction(
                         UserManager.DISALLOW_OUTGOING_CALLS, new UserHandle(userId)));
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index fa215e7..8010f41 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -31,7 +31,6 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
-import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.AsyncTask;
@@ -165,7 +164,6 @@
     private final Object mUserLock = new Object();
     private UserManager mUserManager;
     private static SparseArray<Bitmap> sDarkDefaultUserBitmapCache = new SparseArray<>();
-    private static Bitmap sRemoveGuestBitmap = null;
 
     private MultiUserSwitchBarController mSwitchBarController;
     private EditUserInfoController mEditUserInfoController =
@@ -179,7 +177,6 @@
 
     // A place to cache the generated default avatar
     private Drawable mDefaultIconDrawable;
-    private Drawable mRemoveGuestIconDrawable;
 
     // TODO:   Replace current Handler solution to something that doesn't leak memory and works
     // TODO:   during a configuration change
@@ -387,8 +384,8 @@
     private void loadProfile() {
         if (isCurrentUserGuest()) {
             // No need to load profile information
-            mMePreference.setIcon(getEncircledRemoveGuestIcon());
-            mMePreference.setTitle(R.string.user_clear_guest_menu);
+            mMePreference.setIcon(getEncircledDefaultIcon());
+            mMePreference.setTitle(R.string.user_exit_guest_title);
             mMePreference.setSelectable(true);
             // removing a guest will result in switching back to the admin user
             mMePreference.setEnabled(canSwitchUserNow());
@@ -904,7 +901,7 @@
                 } else {
                     setPhotoId(pref, user);
                 }
-            } else if (!user.isGuest()) {
+            } else {
                 // Icon not available yet, print a placeholder
                 pref.setIcon(getEncircledDefaultIcon());
             }
@@ -1049,14 +1046,6 @@
         return mDefaultIconDrawable;
     }
 
-    private Drawable getEncircledRemoveGuestIcon() {
-        if (mRemoveGuestIconDrawable == null) {
-            mRemoveGuestIconDrawable = encircle(
-                    getRemoveGuestIconAsBitmap(getContext().getResources()));
-        }
-        return mRemoveGuestIconDrawable;
-    }
-
     private void setPhotoId(Preference pref, UserInfo user) {
         Bitmap bitmap = mUserIcons.get(user.id);
         if (bitmap != null) {
@@ -1136,23 +1125,6 @@
     }
 
     /**
-     * Returns a remove guest icon (as a {@link Bitmap})
-     *
-     * @param resources resources object to fetch the remove guest icon.
-     */
-    private static Bitmap getRemoveGuestIconAsBitmap(Resources resources) {
-        if (sRemoveGuestBitmap == null) {
-            Drawable icon = resources.getDrawable(R.drawable.ic_delete, null).mutate();
-            icon.setColorFilter(
-                    resources.getColor(com.android.internal.R.color.user_icon_default_gray, null),
-                    PorterDuff.Mode.SRC_IN);
-            icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
-            sRemoveGuestBitmap = UserIcons.convertToBitmap(icon);
-        }
-        return sRemoveGuestBitmap;
-    }
-
-    /**
      * Assign the default photo to user with {@paramref userId}
      *
      * @param context used to get the {@link UserManager}
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockSettingsHelperTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockSettingsHelperTest.java
index d082bde..053bbe0 100644
--- a/tests/robotests/src/com/android/settings/password/ChooseLockSettingsHelperTest.java
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockSettingsHelperTest.java
@@ -120,6 +120,46 @@
                 .isEqualTo(ThemeHelper.THEME_GLIF_V2);
     }
 
+    @Test
+    public void launchConfirmPattern_ForceVerify_shouldLaunchInternalActivity() {
+        final Activity activity = Robolectric.setupActivity(Activity.class);
+
+        ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(activity);
+        builder.setRequestCode(100)
+                .setForceVerifyPath(true);
+        ChooseLockSettingsHelper helper = getChooseLockSettingsHelper(builder);
+        when(helper.mLockPatternUtils.getKeyguardStoredPasswordQuality(anyInt()))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+        helper.launch();
+
+        ShadowActivity shadowActivity = Shadows.shadowOf(activity);
+        Intent startedIntent = shadowActivity.getNextStartedActivity();
+
+        assertEquals(new ComponentName("com.android.settings",
+                        ConfirmLockPattern.InternalActivity.class.getName()),
+                startedIntent.getComponent());
+    }
+
+    @Test
+    public void launchConfirmPassword_ForceVerify_shouldLaunchInternalActivity() {
+        final Activity activity = Robolectric.setupActivity(Activity.class);
+
+        ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(activity);
+        builder.setRequestCode(100)
+                .setForceVerifyPath(true);
+        ChooseLockSettingsHelper helper = getChooseLockSettingsHelper(builder);
+        when(helper.mLockPatternUtils.getKeyguardStoredPasswordQuality(anyInt()))
+                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
+        helper.launch();
+
+        ShadowActivity shadowActivity = Shadows.shadowOf(activity);
+        Intent startedIntent = shadowActivity.getNextStartedActivity();
+
+        assertEquals(new ComponentName("com.android.settings",
+                        ConfirmLockPassword.InternalActivity.class.getName()),
+                startedIntent.getComponent());
+    }
+
     private ChooseLockSettingsHelper getChooseLockSettingsHelper(
             ChooseLockSettingsHelper.Builder builder) {
         LockPatternUtils mockLockPatternUtils = mock(LockPatternUtils.class);
diff --git a/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java
index 50ddd2a..90c9172 100644
--- a/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java
@@ -363,7 +363,7 @@
         mFragment.initialize(mActivity, mArguments);
 
         verify(mRemoveUserPref).setOnPreferenceClickListener(mFragment);
-        verify(mRemoveUserPref).setTitle(R.string.user_exit_guest_menu);
+        verify(mRemoveUserPref).setTitle(R.string.user_exit_guest_title);
         verify(mFragment, never()).removePreference(KEY_REMOVE_USER);
     }
 
diff --git a/tests/unit/AndroidManifest.xml b/tests/unit/AndroidManifest.xml
index c5f082d..616e6a9 100644
--- a/tests/unit/AndroidManifest.xml
+++ b/tests/unit/AndroidManifest.xml
@@ -28,7 +28,7 @@
     <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 
-    <application>
+    <application android:debuggable="true">
         <uses-library android:name="android.test.runner" />
         <activity android:name="com.android.settings.tests.BluetoothRequestPermissionTest"
             android:exported="true"
diff --git a/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/BridgedAppsPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/BridgedAppsPreferenceControllerTest.java
new file mode 100644
index 0000000..3cdbd3a
--- /dev/null
+++ b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/BridgedAppsPreferenceControllerTest.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2021 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.specialaccess.notificationaccess;
+
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
+import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.VersionedPackage;
+import android.graphics.drawable.Drawable;
+import android.os.Looper;
+import android.service.notification.NotificationListenerFilter;
+import android.util.ArraySet;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settings.notification.NotificationBackend;
+import com.android.settingslib.applications.ApplicationsState;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+
+@RunWith(AndroidJUnit4.class)
+public class BridgedAppsPreferenceControllerTest {
+
+    private Context mContext;
+    private BridgedAppsPreferenceController mController;
+    @Mock
+    NotificationBackend mNm;
+    ComponentName mCn = new ComponentName("a", "b");
+    PreferenceScreen mScreen;
+    @Mock
+    ApplicationsState mAppState;
+    private ApplicationsState.AppEntry mAppEntry;
+    private ApplicationsState.AppEntry mAppEntry2;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = ApplicationProvider.getApplicationContext();
+
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+        PreferenceManager preferenceManager = new PreferenceManager(mContext);
+        mScreen = preferenceManager.createPreferenceScreen(mContext);
+
+        ApplicationInfo ai = new ApplicationInfo();
+        ai.packageName = "pkg";
+        ai.uid = 12300;
+        ai.sourceDir = "";
+        ApplicationInfo ai2 = new ApplicationInfo();
+        ai2.packageName = "another";
+        ai2.uid = 18800;
+        ai2.sourceDir = "";
+        mAppEntry = new ApplicationsState.AppEntry(mContext, ai, 0);
+        mAppEntry2 = new ApplicationsState.AppEntry(mContext, ai2, 1);
+
+        mAppEntry.info = ai;
+        mAppEntry.label = "hi";
+        Drawable icon = mock(Drawable.class);
+        mAppEntry.icon = icon;
+
+        mController = new BridgedAppsPreferenceController(mContext, "key");
+        mController.setCn(mCn);
+        mController.setNm(mNm);
+        mController.setUserId(0);
+        mController.setAppState(mAppState);
+        mController.displayPreference(mScreen);
+    }
+
+    @Test
+    public void onRebuildComplete_AddsToScreen() {
+        when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+        when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
+
+        ArrayList<ApplicationsState.AppEntry> entries = new ArrayList<>();
+        entries.add(mAppEntry);
+        entries.add(mAppEntry2);
+
+        mController.onRebuildComplete(entries);
+
+        assertThat(mScreen.getPreferenceCount()).isEqualTo(2);
+    }
+
+    @Test
+    public void onRebuildComplete_doesNotReaddToScreen() {
+        when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+        when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
+
+        SwitchPreference p = mock(SwitchPreference.class);
+        when(p.getKey()).thenReturn("pkg|12300");
+        mScreen.addPreference(p);
+
+        ArrayList<ApplicationsState.AppEntry> entries = new ArrayList<>();
+        entries.add(mAppEntry);
+        entries.add(mAppEntry2);
+
+        mController.onRebuildComplete(entries);
+
+        assertThat(mScreen.getPreferenceCount()).isEqualTo(2);
+    }
+
+    @Test
+    public void onRebuildComplete_removesExtras() {
+        when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+        when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
+
+        Preference p = mock(Preference.class);
+        when(p.getKey()).thenReturn("pkg|123");
+        mScreen.addPreference(p);
+
+        ArrayList<ApplicationsState.AppEntry> entries = new ArrayList<>();
+        entries.add(mAppEntry);
+        entries.add(mAppEntry2);
+
+        mController.onRebuildComplete(entries);
+
+        assertThat((Preference) mScreen.findPreference("pkg|123")).isNull();
+    }
+
+    @Test
+    public void onRebuildComplete_buildsSetting() {
+        when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+        when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
+
+        ArrayList<ApplicationsState.AppEntry> entries = new ArrayList<>();
+        entries.add(mAppEntry);
+
+        mController.onRebuildComplete(entries);
+
+        SwitchPreference actual = mScreen.findPreference("pkg|12300");
+
+        assertThat(actual.isChecked()).isTrue();
+        assertThat(actual.getTitle()).isEqualTo("hi");
+        assertThat(actual.getIcon()).isEqualTo(mAppEntry.icon);
+    }
+
+    @Test
+    public void onPreferenceChange_false() {
+        VersionedPackage vp = new VersionedPackage("pkg", 10567);
+        ArraySet<VersionedPackage> vps = new ArraySet<>();
+        vps.add(vp);
+        NotificationListenerFilter nlf = new NotificationListenerFilter(FLAG_FILTER_TYPE_ONGOING
+                | FLAG_FILTER_TYPE_CONVERSATIONS, vps);
+        when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+        when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
+
+        SwitchPreference pref = new SwitchPreference(mContext);
+        pref.setKey("pkg|567");
+
+        mController.onPreferenceChange(pref, false);
+
+        ArgumentCaptor<NotificationListenerFilter> captor =
+                ArgumentCaptor.forClass(NotificationListenerFilter.class);
+        verify(mNm).setListenerFilter(eq(mCn), eq(0), captor.capture());
+        assertThat(captor.getValue().getDisallowedPackages()).contains(
+                new VersionedPackage("pkg", 567));
+        assertThat(captor.getValue().getDisallowedPackages()).contains(
+                new VersionedPackage("pkg", 10567));
+    }
+
+    @Test
+    public void onPreferenceChange_true() {
+        VersionedPackage vp = new VersionedPackage("pkg", 567);
+        VersionedPackage vp2 = new VersionedPackage("pkg", 10567);
+        ArraySet<VersionedPackage> vps = new ArraySet<>();
+        vps.add(vp);
+        vps.add(vp2);
+        NotificationListenerFilter nlf = new NotificationListenerFilter(FLAG_FILTER_TYPE_ONGOING
+                | FLAG_FILTER_TYPE_CONVERSATIONS, vps);
+        when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+        when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
+
+        SwitchPreference pref = new SwitchPreference(mContext);
+        pref.setKey("pkg|567");
+
+        mController.onPreferenceChange(pref, true);
+
+        ArgumentCaptor<NotificationListenerFilter> captor =
+                ArgumentCaptor.forClass(NotificationListenerFilter.class);
+        verify(mNm).setListenerFilter(eq(mCn), eq(0), captor.capture());
+        assertThat(captor.getValue().getDisallowedPackages().size()).isEqualTo(1);
+        assertThat(captor.getValue().getDisallowedPackages()).contains(
+                new VersionedPackage("pkg", 10567));
+    }
+}