Merge "Include activity infos corresponding to archived apps in LauncherApps::getActivityList and LauncherApps::resolveActivity." into main
diff --git a/Android.bp b/Android.bp
index 0c199a6..7d5e788 100644
--- a/Android.bp
+++ b/Android.bp
@@ -323,7 +323,6 @@
             ":installd_aidl",
             ":libaudioclient_aidl",
             ":libbinder_aidl",
-            ":libbluetooth-binder-aidl",
             ":libcamera_client_aidl",
             ":libcamera_client_framework_aidl",
             ":libupdate_engine_aidl",
diff --git a/cmds/svc/src/com/android/commands/svc/NfcCommand.java b/cmds/svc/src/com/android/commands/svc/NfcCommand.java
index 020ca33..ee2af12 100644
--- a/cmds/svc/src/com/android/commands/svc/NfcCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/NfcCommand.java
@@ -16,10 +16,11 @@
 
 package com.android.commands.svc;
 
+import android.app.ActivityThread;
 import android.content.Context;
-import android.nfc.INfcAdapter;
-import android.os.RemoteException;
-import android.os.ServiceManager;
+import android.nfc.NfcAdapter;
+import android.nfc.NfcManager;
+import android.os.Looper;
 
 public class NfcCommand extends Svc.Command {
 
@@ -42,27 +43,26 @@
 
     @Override
     public void run(String[] args) {
-        INfcAdapter adapter = INfcAdapter.Stub.asInterface(
-                ServiceManager.getService(Context.NFC_SERVICE));
-
+        Looper.prepareMainLooper();
+        ActivityThread.initializeMainlineModules();
+        Context context = ActivityThread.systemMain().getSystemContext();
+        NfcManager nfcManager = context.getSystemService(NfcManager.class);
+        if (nfcManager == null) {
+            System.err.println("Got a null NfcManager, is the system running?");
+            return;
+        }
+        NfcAdapter adapter = nfcManager.getDefaultAdapter();
         if (adapter == null) {
             System.err.println("Got a null NfcAdapter, is the system running?");
             return;
         }
-
-        try {
-            if (args.length == 2 && "enable".equals(args[1])) {
-                adapter.enable();
-                return;
-            } else if (args.length == 2 && "disable".equals(args[1])) {
-                adapter.disable(true);
-                return;
-            }
-        } catch (RemoteException e) {
-            System.err.println("NFC operation failed: " + e);
+        if (args.length == 2 && "enable".equals(args[1])) {
+            adapter.enable();
+            return;
+        } else if (args.length == 2 && "disable".equals(args[1])) {
+            adapter.disable(true);
             return;
         }
-
         System.err.println(longHelp());
     }
 
diff --git a/core/api/current.txt b/core/api/current.txt
index d8ea721..4bcb7d7 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -9644,13 +9644,13 @@
     method @Deprecated @MainThread public void onDeviceAppeared(@NonNull android.companion.AssociationInfo);
     method @Deprecated @MainThread public void onDeviceDisappeared(@NonNull String);
     method @Deprecated @MainThread public void onDeviceDisappeared(@NonNull android.companion.AssociationInfo);
-    method @MainThread public void onDeviceEvent(@NonNull android.companion.AssociationInfo, int);
-    field public static final int DEVICE_EVENT_BLE_APPEARED = 0; // 0x0
-    field public static final int DEVICE_EVENT_BLE_DISAPPEARED = 1; // 0x1
-    field public static final int DEVICE_EVENT_BT_CONNECTED = 2; // 0x2
-    field public static final int DEVICE_EVENT_BT_DISCONNECTED = 3; // 0x3
-    field public static final int DEVICE_EVENT_SELF_MANAGED_APPEARED = 4; // 0x4
-    field public static final int DEVICE_EVENT_SELF_MANAGED_DISAPPEARED = 5; // 0x5
+    method @FlaggedApi("android.companion.device_presence") @MainThread public void onDeviceEvent(@NonNull android.companion.AssociationInfo, int);
+    field @FlaggedApi("android.companion.device_presence") public static final int DEVICE_EVENT_BLE_APPEARED = 0; // 0x0
+    field @FlaggedApi("android.companion.device_presence") public static final int DEVICE_EVENT_BLE_DISAPPEARED = 1; // 0x1
+    field @FlaggedApi("android.companion.device_presence") public static final int DEVICE_EVENT_BT_CONNECTED = 2; // 0x2
+    field @FlaggedApi("android.companion.device_presence") public static final int DEVICE_EVENT_BT_DISCONNECTED = 3; // 0x3
+    field @FlaggedApi("android.companion.device_presence") public static final int DEVICE_EVENT_SELF_MANAGED_APPEARED = 4; // 0x4
+    field @FlaggedApi("android.companion.device_presence") public static final int DEVICE_EVENT_SELF_MANAGED_DISAPPEARED = 5; // 0x5
     field public static final String SERVICE_INTERFACE = "android.companion.CompanionDeviceService";
   }
 
@@ -33475,7 +33475,7 @@
     field public static final String DISALLOW_MICROPHONE_TOGGLE = "disallow_microphone_toggle";
     field public static final String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts";
     field public static final String DISALLOW_MOUNT_PHYSICAL_MEDIA = "no_physical_media";
-    field public static final String DISALLOW_NEAR_FIELD_COMMUNICATION_RADIO = "no_near_field_communication_radio";
+    field @FlaggedApi("android.nfc.enable_nfc_user_restriction") public static final String DISALLOW_NEAR_FIELD_COMMUNICATION_RADIO = "no_near_field_communication_radio";
     field public static final String DISALLOW_NETWORK_RESET = "no_network_reset";
     field public static final String DISALLOW_OUTGOING_BEAM = "no_outgoing_beam";
     field public static final String DISALLOW_OUTGOING_CALLS = "no_outgoing_calls";
@@ -43127,6 +43127,7 @@
     field public static final String KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL = "show_iccid_in_sim_status_bool";
     field public static final String KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL = "show_ims_registration_status_bool";
     field public static final String KEY_SHOW_ONSCREEN_DIAL_BUTTON_BOOL = "show_onscreen_dial_button_bool";
+    field @FlaggedApi("com.android.internal.telephony.flags.hide_roaming_icon") public static final String KEY_SHOW_ROAMING_INDICATOR_BOOL = "show_roaming_indicator_bool";
     field public static final String KEY_SHOW_SIGNAL_STRENGTH_IN_SIM_STATUS_BOOL = "show_signal_strength_in_sim_status_bool";
     field public static final String KEY_SHOW_VIDEO_CALL_CHARGES_ALERT_DIALOG_BOOL = "show_video_call_charges_alert_dialog_bool";
     field public static final String KEY_SHOW_WFC_LOCATION_PRIVACY_POLICY_BOOL = "show_wfc_location_privacy_policy_bool";
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 94e1292..3bde39c 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -5607,7 +5607,8 @@
             // Use different highlighted colors for conversations' unread count
             if (p.mHighlightExpander) {
                 pillColor = Colors.flattenAlpha(getColors(p).getTertiaryAccentColor(), bgColor);
-                textColor = Colors.flattenAlpha(getColors(p).getOnAccentTextColor(), pillColor);
+                textColor = Colors.flattenAlpha(
+                        getColors(p).getOnTertiaryAccentTextColor(), pillColor);
             }
             contentView.setInt(R.id.expand_button, "setHighlightTextColor", textColor);
             contentView.setInt(R.id.expand_button, "setHighlightPillColor", pillColor);
@@ -12833,7 +12834,7 @@
         private int mPrimaryAccentColor = COLOR_INVALID;
         private int mSecondaryAccentColor = COLOR_INVALID;
         private int mTertiaryAccentColor = COLOR_INVALID;
-        private int mOnAccentTextColor = COLOR_INVALID;
+        private int mOnTertiaryAccentTextColor = COLOR_INVALID;
         private int mErrorColor = COLOR_INVALID;
         private int mContrastColor = COLOR_INVALID;
         private int mRippleAlpha = 0x33;
@@ -12908,7 +12909,7 @@
                 mPrimaryAccentColor = mPrimaryTextColor;
                 mSecondaryAccentColor = mSecondaryTextColor;
                 mTertiaryAccentColor = flattenAlpha(mPrimaryTextColor, mBackgroundColor);
-                mOnAccentTextColor = mBackgroundColor;
+                mOnTertiaryAccentTextColor = mBackgroundColor;
                 mErrorColor = mPrimaryTextColor;
                 mRippleAlpha = 0x33;
             } else {
@@ -12930,7 +12931,7 @@
                     mPrimaryAccentColor = getColor(ta, 3, COLOR_INVALID);
                     mSecondaryAccentColor = getColor(ta, 4, COLOR_INVALID);
                     mTertiaryAccentColor = getColor(ta, 5, COLOR_INVALID);
-                    mOnAccentTextColor = getColor(ta, 6, COLOR_INVALID);
+                    mOnTertiaryAccentTextColor = getColor(ta, 6, COLOR_INVALID);
                     mErrorColor = getColor(ta, 7, COLOR_INVALID);
                     mRippleAlpha = Color.alpha(getColor(ta, 8, 0x33ffffff));
                 }
@@ -12955,8 +12956,8 @@
                 if (mTertiaryAccentColor == COLOR_INVALID) {
                     mTertiaryAccentColor = mContrastColor;
                 }
-                if (mOnAccentTextColor == COLOR_INVALID) {
-                    mOnAccentTextColor = ColorUtils.setAlphaComponent(
+                if (mOnTertiaryAccentTextColor == COLOR_INVALID) {
+                    mOnTertiaryAccentTextColor = ColorUtils.setAlphaComponent(
                             ContrastColorUtil.resolvePrimaryColor(
                                     ctx, mTertiaryAccentColor, nightMode), 0xFF);
                 }
@@ -13029,8 +13030,8 @@
         }
 
         /** @return the theme's text color to be used on the tertiary accent color. */
-        public @ColorInt int getOnAccentTextColor() {
-            return mOnAccentTextColor;
+        public @ColorInt int getOnTertiaryAccentTextColor() {
+            return mOnTertiaryAccentTextColor;
         }
 
         /**
diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig
index f99615f..5a41c65 100644
--- a/core/java/android/app/admin/flags/flags.aconfig
+++ b/core/java/android/app/admin/flags/flags.aconfig
@@ -27,3 +27,17 @@
   description: "Allow holders of INTERACT_ACROSS_USERS_FULL to suspend apps in different users."
   bug: "263464464"
 }
+
+flag {
+  name: "dedicated_device_control_enabled"
+  namespace: "enterprise"
+  description: "Allow the device management role holder to control which platform features are available on dedicated devices."
+  bug: "281964214"
+}
+
+flag {
+  name: "security_log_v2_enabled"
+  namespace: "enterprise"
+  description: "Improve access to security logging in the context of Zero Trust."
+  bug: "295324350"
+}
diff --git a/core/java/android/app/servertransaction/ActivityLifecycleItem.java b/core/java/android/app/servertransaction/ActivityLifecycleItem.java
index b34f678..06bff5d 100644
--- a/core/java/android/app/servertransaction/ActivityLifecycleItem.java
+++ b/core/java/android/app/servertransaction/ActivityLifecycleItem.java
@@ -58,6 +58,11 @@
         super(in);
     }
 
+    @Override
+    boolean isActivityLifecycleItem() {
+        return true;
+    }
+
     /** A final lifecycle state that an activity should reach. */
     @LifecycleState
     public abstract int getTargetState();
diff --git a/core/java/android/app/servertransaction/ClientTransaction.java b/core/java/android/app/servertransaction/ClientTransaction.java
index 8617386..9c0cd39 100644
--- a/core/java/android/app/servertransaction/ClientTransaction.java
+++ b/core/java/android/app/servertransaction/ClientTransaction.java
@@ -45,6 +45,13 @@
  */
 public class ClientTransaction implements Parcelable, ObjectPoolItem {
 
+    /**
+     * List of transaction items that should be executed in order. Including both
+     * {@link ActivityLifecycleItem} and other {@link ClientTransactionItem}.
+     */
+    @Nullable
+    private List<ClientTransactionItem> mTransactionItems;
+
     /** A list of individual callbacks to a client. */
     @UnsupportedAppUsage
     private List<ClientTransactionItem> mActivityCallbacks;
@@ -64,9 +71,32 @@
     }
 
     /**
-     * Add a message to the end of the sequence of callbacks.
-     * @param activityCallback A single message that can contain a lifecycle request/callback.
+     * Adds a message to the end of the sequence of transaction items.
+     * @param item A single message that can contain a client activity/window request/callback.
+     * TODO(b/260873529): replace both {@link #addCallback} and {@link #setLifecycleStateRequest}.
      */
+    public void addTransactionItem(@NonNull ClientTransactionItem item) {
+        if (mTransactionItems == null) {
+            mTransactionItems = new ArrayList<>();
+        }
+        mTransactionItems.add(item);
+    }
+
+    /**
+     * Gets the list of client window requests/callbacks.
+     * TODO(b/260873529): must be non null after remove the deprecated methods.
+     */
+    @Nullable
+    public List<ClientTransactionItem> getTransactionItems() {
+        return mTransactionItems;
+    }
+
+    /**
+     * Adds a message to the end of the sequence of callbacks.
+     * @param activityCallback A single message that can contain a lifecycle request/callback.
+     * @deprecated use {@link #addTransactionItem(ClientTransactionItem)} instead.
+     */
+    @Deprecated
     public void addCallback(@NonNull ClientTransactionItem activityCallback) {
         if (mActivityCallbacks == null) {
             mActivityCallbacks = new ArrayList<>();
@@ -74,25 +104,35 @@
         mActivityCallbacks.add(activityCallback);
     }
 
-    /** Get the list of callbacks. */
+    /**
+     * Gets the list of callbacks.
+     * @deprecated use {@link #getTransactionItems()} instead.
+     */
     @Nullable
     @VisibleForTesting
     @UnsupportedAppUsage
+    @Deprecated
     public List<ClientTransactionItem> getCallbacks() {
         return mActivityCallbacks;
     }
 
-    /** Get the target state lifecycle request. */
+    /**
+     * Gets the target state lifecycle request.
+     * @deprecated use {@link #getTransactionItems()} instead.
+     */
     @VisibleForTesting(visibility = PACKAGE)
     @UnsupportedAppUsage
+    @Deprecated
     public ActivityLifecycleItem getLifecycleStateRequest() {
         return mLifecycleStateRequest;
     }
 
     /**
-     * Set the lifecycle state in which the client should be after executing the transaction.
+     * Sets the lifecycle state in which the client should be after executing the transaction.
      * @param stateRequest A lifecycle request initialized with right parameters.
+     * @deprecated use {@link #addTransactionItem(ClientTransactionItem)} instead.
      */
+    @Deprecated
     public void setLifecycleStateRequest(@NonNull ActivityLifecycleItem stateRequest) {
         mLifecycleStateRequest = stateRequest;
     }
@@ -103,6 +143,14 @@
      *                                 requested by transaction items.
      */
     public void preExecute(@NonNull ClientTransactionHandler clientTransactionHandler) {
+        if (mTransactionItems != null) {
+            final int size = mTransactionItems.size();
+            for (int i = 0; i < size; ++i) {
+                mTransactionItems.get(i).preExecute(clientTransactionHandler);
+            }
+            return;
+        }
+
         if (mActivityCallbacks != null) {
             final int size = mActivityCallbacks.size();
             for (int i = 0; i < size; ++i) {
@@ -147,6 +195,13 @@
 
     @Override
     public void recycle() {
+        if (mTransactionItems != null) {
+            int size = mTransactionItems.size();
+            for (int i = 0; i < size; i++) {
+                mTransactionItems.get(i).recycle();
+            }
+            mTransactionItems = null;
+        }
         if (mActivityCallbacks != null) {
             int size = mActivityCallbacks.size();
             for (int i = 0; i < size; i++) {
@@ -165,8 +220,15 @@
     // Parcelable implementation
 
     /** Write to Parcel. */
+    @SuppressWarnings("AndroidFrameworkEfficientParcelable") // Item class is not final.
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
+        final boolean writeTransactionItems = mTransactionItems != null;
+        dest.writeBoolean(writeTransactionItems);
+        if (writeTransactionItems) {
+            dest.writeParcelableList(mTransactionItems, flags);
+        }
+
         dest.writeParcelable(mLifecycleStateRequest, flags);
         final boolean writeActivityCallbacks = mActivityCallbacks != null;
         dest.writeBoolean(writeActivityCallbacks);
@@ -177,11 +239,20 @@
 
     /** Read from Parcel. */
     private ClientTransaction(@NonNull Parcel in) {
-        mLifecycleStateRequest = in.readParcelable(getClass().getClassLoader(), android.app.servertransaction.ActivityLifecycleItem.class);
+        final boolean readTransactionItems = in.readBoolean();
+        if (readTransactionItems) {
+            mTransactionItems = new ArrayList<>();
+            in.readParcelableList(mTransactionItems, getClass().getClassLoader(),
+                    ClientTransactionItem.class);
+        }
+
+        mLifecycleStateRequest = in.readParcelable(getClass().getClassLoader(),
+                ActivityLifecycleItem.class);
         final boolean readActivityCallbacks = in.readBoolean();
         if (readActivityCallbacks) {
             mActivityCallbacks = new ArrayList<>();
-            in.readParcelableList(mActivityCallbacks, getClass().getClassLoader(), android.app.servertransaction.ClientTransactionItem.class);
+            in.readParcelableList(mActivityCallbacks, getClass().getClassLoader(),
+                    ClientTransactionItem.class);
         }
     }
 
@@ -209,7 +280,8 @@
             return false;
         }
         final ClientTransaction other = (ClientTransaction) o;
-        return Objects.equals(mActivityCallbacks, other.mActivityCallbacks)
+        return Objects.equals(mTransactionItems, other.mTransactionItems)
+                && Objects.equals(mActivityCallbacks, other.mActivityCallbacks)
                 && Objects.equals(mLifecycleStateRequest, other.mLifecycleStateRequest)
                 && mClient == other.mClient;
     }
@@ -217,6 +289,7 @@
     @Override
     public int hashCode() {
         int result = 17;
+        result = 31 * result + Objects.hashCode(mTransactionItems);
         result = 31 * result + Objects.hashCode(mActivityCallbacks);
         result = 31 * result + Objects.hashCode(mLifecycleStateRequest);
         result = 31 * result + Objects.hashCode(mClient);
@@ -227,6 +300,22 @@
     void dump(@NonNull String prefix, @NonNull PrintWriter pw,
             @NonNull ClientTransactionHandler transactionHandler) {
         pw.append(prefix).println("ClientTransaction{");
+        if (mTransactionItems != null) {
+            pw.append(prefix).print("  transactionItems=[");
+            final String itemPrefix = prefix + "    ";
+            final int size = mTransactionItems.size();
+            if (size > 0) {
+                pw.println();
+                for (int i = 0; i < size; i++) {
+                    mTransactionItems.get(i).dump(itemPrefix, pw, transactionHandler);
+                }
+                pw.append(prefix).println("  ]");
+            } else {
+                pw.println("]");
+            }
+            pw.append(prefix).println("}");
+            return;
+        }
         pw.append(prefix).print("  callbacks=[");
         final String itemPrefix = prefix + "    ";
         final int size = mActivityCallbacks != null ? mActivityCallbacks.size() : 0;
diff --git a/core/java/android/app/servertransaction/ClientTransactionItem.java b/core/java/android/app/servertransaction/ClientTransactionItem.java
index 07e5a7d..f94e22d 100644
--- a/core/java/android/app/servertransaction/ClientTransactionItem.java
+++ b/core/java/android/app/servertransaction/ClientTransactionItem.java
@@ -72,6 +72,13 @@
         return null;
     }
 
+    /**
+     * Whether this is a {@link ActivityLifecycleItem}.
+     */
+    boolean isActivityLifecycleItem() {
+        return false;
+    }
+
     /** Dumps this transaction item. */
     void dump(@NonNull String prefix, @NonNull PrintWriter pw,
             @NonNull ClientTransactionHandler transactionHandler) {
diff --git a/core/java/android/app/servertransaction/TransactionExecutor.java b/core/java/android/app/servertransaction/TransactionExecutor.java
index 066f9fe..9f5e0dc 100644
--- a/core/java/android/app/servertransaction/TransactionExecutor.java
+++ b/core/java/android/app/servertransaction/TransactionExecutor.java
@@ -28,6 +28,7 @@
 import static android.app.servertransaction.TransactionExecutorHelper.getShortActivityName;
 import static android.app.servertransaction.TransactionExecutorHelper.getStateName;
 import static android.app.servertransaction.TransactionExecutorHelper.lastCallbackRequestingState;
+import static android.app.servertransaction.TransactionExecutorHelper.shouldExcludeLastLifecycleState;
 import static android.app.servertransaction.TransactionExecutorHelper.tId;
 import static android.app.servertransaction.TransactionExecutorHelper.transactionToString;
 
@@ -61,6 +62,9 @@
     private final PendingTransactionActions mPendingActions = new PendingTransactionActions();
     private final TransactionExecutorHelper mHelper = new TransactionExecutorHelper();
 
+    /** Keeps track of display ids whose Configuration got updated within a transaction. */
+    private final ArraySet<Integer> mConfigUpdatedDisplayIds = new ArraySet<>();
+
     /** Initialize an instance with transaction handler, that will execute all requested actions. */
     public TransactionExecutor(@NonNull ClientTransactionHandler clientTransactionHandler) {
         mTransactionHandler = clientTransactionHandler;
@@ -79,15 +83,52 @@
             Slog.d(TAG, transactionToString(transaction, mTransactionHandler));
         }
 
-        executeCallbacks(transaction);
-        executeLifecycleState(transaction);
+        if (transaction.getTransactionItems() != null) {
+            executeTransactionItems(transaction);
+        } else {
+            // TODO(b/260873529): cleanup after launch.
+            executeCallbacks(transaction);
+            executeLifecycleState(transaction);
+        }
+
+        if (!mConfigUpdatedDisplayIds.isEmpty()) {
+            // Whether this transaction should trigger DisplayListener#onDisplayChanged.
+            final ClientTransactionListenerController controller =
+                    ClientTransactionListenerController.getInstance();
+            final int displayCount = mConfigUpdatedDisplayIds.size();
+            for (int i = 0; i < displayCount; i++) {
+                final int displayId = mConfigUpdatedDisplayIds.valueAt(i);
+                controller.onDisplayChanged(displayId);
+            }
+            mConfigUpdatedDisplayIds.clear();
+        }
 
         mPendingActions.clear();
         if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
     }
 
-    /** Cycle through all states requested by callbacks and execute them at proper times. */
+    /** Cycles through all transaction items and execute them at proper times. */
     @VisibleForTesting
+    public void executeTransactionItems(@NonNull ClientTransaction transaction) {
+        final List<ClientTransactionItem> items = transaction.getTransactionItems();
+        final int size = items.size();
+        for (int i = 0; i < size; i++) {
+            final ClientTransactionItem item = items.get(i);
+            if (item.isActivityLifecycleItem()) {
+                executeLifecycleItem(transaction, (ActivityLifecycleItem) item);
+            } else {
+                executeNonLifecycleItem(transaction, item,
+                        shouldExcludeLastLifecycleState(items, i));
+            }
+        }
+    }
+
+    /**
+     * Cycle through all states requested by callbacks and execute them at proper times.
+     * @deprecated use {@link #executeTransactionItems} instead.
+     */
+    @VisibleForTesting
+    @Deprecated
     public void executeCallbacks(@NonNull ClientTransaction transaction) {
         final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
         if (callbacks == null || callbacks.isEmpty()) {
@@ -105,83 +146,78 @@
         // Index of the last callback that requests some post-execution state.
         final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);
 
-        // Keep track of display ids whose Configuration got updated with this transaction.
-        ArraySet<Integer> configUpdatedDisplays = null;
-
         final int size = callbacks.size();
         for (int i = 0; i < size; ++i) {
             final ClientTransactionItem item = callbacks.get(i);
-            final IBinder token = item.getActivityToken();
-            ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
 
-            if (token != null && r == null
-                    && mTransactionHandler.getActivitiesToBeDestroyed().containsKey(token)) {
-                // The activity has not been created but has been requested to destroy, so all
-                // transactions for the token are just like being cancelled.
-                Slog.w(TAG, "Skip pre-destroyed transaction item:\n" + item);
-                continue;
-            }
-
-            if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
+            // Skip the very last transition and perform it by explicit state request instead.
             final int postExecutionState = item.getPostExecutionState();
-
-            if (item.shouldHaveDefinedPreExecutionState()) {
-                final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
-                        item.getPostExecutionState());
-                if (closestPreExecutionState != UNDEFINED) {
-                    cycleToPath(r, closestPreExecutionState, transaction);
-                }
-            }
-
-            // Can't read flag from isolated process.
-            final boolean isSyncWindowConfigUpdateFlagEnabled = !Process.isIsolated()
-                    && syncWindowConfigUpdateFlag();
-            final Context configUpdatedContext = isSyncWindowConfigUpdateFlagEnabled
-                    ? item.getContextToUpdate(mTransactionHandler)
-                    : null;
-            final Configuration preExecutedConfig = configUpdatedContext != null
-                    ? new Configuration(configUpdatedContext.getResources().getConfiguration())
-                    : null;
-
-            item.execute(mTransactionHandler, mPendingActions);
-
-            if (configUpdatedContext != null) {
-                final Configuration postExecutedConfig = configUpdatedContext.getResources()
-                        .getConfiguration();
-                if (!areConfigurationsEqualForDisplay(postExecutedConfig, preExecutedConfig)) {
-                    if (configUpdatedDisplays == null) {
-                        configUpdatedDisplays = new ArraySet<>();
-                    }
-                    configUpdatedDisplays.add(configUpdatedContext.getDisplayId());
-                }
-            }
-
-            item.postExecute(mTransactionHandler, mPendingActions);
-            if (r == null) {
-                // Launch activity request will create an activity record.
-                r = mTransactionHandler.getActivityClient(token);
-            }
-
-            if (postExecutionState != UNDEFINED && r != null) {
-                // Skip the very last transition and perform it by explicit state request instead.
-                final boolean shouldExcludeLastTransition =
-                        i == lastCallbackRequestingState && finalState == postExecutionState;
-                cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
-            }
-        }
-
-        if (configUpdatedDisplays != null) {
-            final ClientTransactionListenerController controller =
-                    ClientTransactionListenerController.getInstance();
-            final int displayCount = configUpdatedDisplays.size();
-            for (int i = 0; i < displayCount; i++) {
-                final int displayId = configUpdatedDisplays.valueAt(i);
-                controller.onDisplayChanged(displayId);
-            }
+            final boolean shouldExcludeLastLifecycleState = postExecutionState != UNDEFINED
+                    && i == lastCallbackRequestingState && finalState == postExecutionState;
+            executeNonLifecycleItem(transaction, item, shouldExcludeLastLifecycleState);
         }
     }
 
-    /** Transition to the final state if requested by the transaction. */
+    private void executeNonLifecycleItem(@NonNull ClientTransaction transaction,
+            @NonNull ClientTransactionItem item, boolean shouldExcludeLastLifecycleState) {
+        final IBinder token = item.getActivityToken();
+        ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
+
+        if (token != null && r == null
+                && mTransactionHandler.getActivitiesToBeDestroyed().containsKey(token)) {
+            // The activity has not been created but has been requested to destroy, so all
+            // transactions for the token are just like being cancelled.
+            Slog.w(TAG, "Skip pre-destroyed transaction item:\n" + item);
+            return;
+        }
+
+        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
+        final int postExecutionState = item.getPostExecutionState();
+
+        if (item.shouldHaveDefinedPreExecutionState()) {
+            final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
+                    postExecutionState);
+            if (closestPreExecutionState != UNDEFINED) {
+                cycleToPath(r, closestPreExecutionState, transaction);
+            }
+        }
+
+        // Can't read flag from isolated process.
+        final boolean isSyncWindowConfigUpdateFlagEnabled = !Process.isIsolated()
+                && syncWindowConfigUpdateFlag();
+        final Context configUpdatedContext = isSyncWindowConfigUpdateFlagEnabled
+                ? item.getContextToUpdate(mTransactionHandler)
+                : null;
+        final Configuration preExecutedConfig = configUpdatedContext != null
+                ? new Configuration(configUpdatedContext.getResources().getConfiguration())
+                : null;
+
+        item.execute(mTransactionHandler, mPendingActions);
+
+        if (configUpdatedContext != null) {
+            final Configuration postExecutedConfig = configUpdatedContext.getResources()
+                    .getConfiguration();
+            if (!areConfigurationsEqualForDisplay(postExecutedConfig, preExecutedConfig)) {
+                mConfigUpdatedDisplayIds.add(configUpdatedContext.getDisplayId());
+            }
+        }
+
+        item.postExecute(mTransactionHandler, mPendingActions);
+        if (r == null) {
+            // Launch activity request will create an activity record.
+            r = mTransactionHandler.getActivityClient(token);
+        }
+
+        if (postExecutionState != UNDEFINED && r != null) {
+            cycleToPath(r, postExecutionState, shouldExcludeLastLifecycleState, transaction);
+        }
+    }
+
+    /**
+     * Transition to the final state if requested by the transaction.
+     * @deprecated use {@link #executeTransactionItems} instead
+     */
+    @Deprecated
     private void executeLifecycleState(@NonNull ClientTransaction transaction) {
         final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
         if (lifecycleItem == null) {
@@ -189,6 +225,11 @@
             return;
         }
 
+        executeLifecycleItem(transaction, lifecycleItem);
+    }
+
+    private void executeLifecycleItem(@NonNull ClientTransaction transaction,
+            @NonNull ActivityLifecycleItem lifecycleItem) {
         final IBinder token = lifecycleItem.getActivityToken();
         final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
         if (DEBUG_RESOLVER) {
diff --git a/core/java/android/app/servertransaction/TransactionExecutorHelper.java b/core/java/android/app/servertransaction/TransactionExecutorHelper.java
index 7e89a5b..dfbccb4 100644
--- a/core/java/android/app/servertransaction/TransactionExecutorHelper.java
+++ b/core/java/android/app/servertransaction/TransactionExecutorHelper.java
@@ -236,21 +236,39 @@
      * index 1 will be returned, because ActivityResult request on position 1 will be the last
      * request that moves activity to the RESUMED state where it will eventually end.
      */
-    static int lastCallbackRequestingState(ClientTransaction transaction) {
+    static int lastCallbackRequestingState(@NonNull ClientTransaction transaction) {
         final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
-        if (callbacks == null || callbacks.size() == 0) {
+        if (callbacks == null || callbacks.isEmpty()
+                || transaction.getLifecycleStateRequest() == null) {
             return -1;
         }
+        return lastCallbackRequestingStateIndex(callbacks, 0, callbacks.size() - 1,
+                transaction.getLifecycleStateRequest().getActivityToken());
+    }
 
+    /**
+     * Returns the index of the last callback between the start index and last index that requests
+     * the state for the given activity token in which that activity will be after execution.
+     * If there is a group of callbacks in the end that requests the same specific state or doesn't
+     * request any - we will find the first one from such group.
+     *
+     * E.g. ActivityResult requests RESUMED post-execution state, Configuration does not request any
+     * specific state. If there is a sequence
+     *   Configuration - ActivityResult - Configuration - ActivityResult
+     * index 1 will be returned, because ActivityResult request on position 1 will be the last
+     * request that moves activity to the RESUMED state where it will eventually end.
+     */
+    private static int lastCallbackRequestingStateIndex(@NonNull List<ClientTransactionItem> items,
+            int startIndex, int lastIndex, @NonNull IBinder activityToken) {
         // Go from the back of the list to front, look for the request closes to the beginning that
         // requests the state in which activity will end after all callbacks are executed.
         int lastRequestedState = UNDEFINED;
         int lastRequestingCallback = -1;
-        for (int i = callbacks.size() - 1; i >= 0; i--) {
-            final ClientTransactionItem callback = callbacks.get(i);
-            final int postExecutionState = callback.getPostExecutionState();
-            if (postExecutionState != UNDEFINED) {
-                // Found a callback that requests some post-execution state.
+        for (int i = lastIndex; i >= startIndex; i--) {
+            final ClientTransactionItem item = items.get(i);
+            final int postExecutionState = item.getPostExecutionState();
+            if (postExecutionState != UNDEFINED && activityToken.equals(item.getActivityToken())) {
+                // Found a callback that requests some post-execution state for the given activity.
                 if (lastRequestedState == UNDEFINED || lastRequestedState == postExecutionState) {
                     // It's either a first-from-end callback that requests state or it requests
                     // the same state as the last one. In both cases, we will use it as the new
@@ -266,6 +284,53 @@
         return lastRequestingCallback;
     }
 
+    /**
+     * For the transaction item at {@code currentIndex}, if it is requesting post execution state,
+     * whether or not to exclude the last state. This only returns {@code true} when there is a
+     * following explicit {@link ActivityLifecycleItem} requesting the same state for the same
+     * activity, so that last state will be covered by the following {@link ActivityLifecycleItem}.
+     */
+    static boolean shouldExcludeLastLifecycleState(@NonNull List<ClientTransactionItem> items,
+            int currentIndex) {
+        final ClientTransactionItem item = items.get(currentIndex);
+        final IBinder activityToken = item.getActivityToken();
+        final int postExecutionState = item.getPostExecutionState();
+        if (activityToken == null || postExecutionState == UNDEFINED) {
+            // Not a transaction item requesting post execution state.
+            return false;
+        }
+        final int nextLifecycleItemIndex = findNextLifecycleItemIndex(items, currentIndex + 1,
+                activityToken);
+        if (nextLifecycleItemIndex == -1) {
+            // No following ActivityLifecycleItem for this activity token.
+            return false;
+        }
+        final ActivityLifecycleItem lifecycleItem =
+                (ActivityLifecycleItem) items.get(nextLifecycleItemIndex);
+        if (postExecutionState != lifecycleItem.getTargetState()) {
+            // The explicit ActivityLifecycleItem is not requesting the same state.
+            return false;
+        }
+        // Only exclude for the first non-lifecycle item that requests the same specific state.
+        return currentIndex == lastCallbackRequestingStateIndex(items, currentIndex,
+                nextLifecycleItemIndex - 1, activityToken);
+    }
+
+    /**
+     * Finds the index of the next {@link ActivityLifecycleItem} for the given activity token.
+     */
+    private static int findNextLifecycleItemIndex(@NonNull List<ClientTransactionItem> items,
+            int startIndex, @NonNull IBinder activityToken) {
+        final int size = items.size();
+        for (int i = startIndex; i < size; i++) {
+            final ClientTransactionItem item = items.get(i);
+            if (item.isActivityLifecycleItem() && item.getActivityToken().equals(activityToken)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
     /** Dump transaction to string. */
     static String transactionToString(@NonNull ClientTransaction transaction,
             @NonNull ClientTransactionHandler transactionHandler) {
diff --git a/core/java/android/companion/CompanionDeviceService.java b/core/java/android/companion/CompanionDeviceService.java
index 570ecaa..c99a457 100644
--- a/core/java/android/companion/CompanionDeviceService.java
+++ b/core/java/android/companion/CompanionDeviceService.java
@@ -17,6 +17,7 @@
 
 package android.companion;
 
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.MainThread;
 import android.annotation.NonNull;
@@ -140,24 +141,28 @@
      * Companion app receives {@link #onDeviceEvent(AssociationInfo, int)} callback
      * with this event if the device comes into BLE range.
      */
+    @FlaggedApi(Flags.FLAG_DEVICE_PRESENCE)
     public static final int DEVICE_EVENT_BLE_APPEARED = 0;
 
     /**
      * Companion app receives {@link #onDeviceEvent(AssociationInfo, int)} callback
      * with this event if the device is no longer in BLE range.
      */
+    @FlaggedApi(Flags.FLAG_DEVICE_PRESENCE)
     public static final int DEVICE_EVENT_BLE_DISAPPEARED = 1;
 
     /**
      * Companion app receives {@link #onDeviceEvent(AssociationInfo, int)} callback
      * with this event when the bluetooth device is connected.
      */
+    @FlaggedApi(Flags.FLAG_DEVICE_PRESENCE)
     public static final int DEVICE_EVENT_BT_CONNECTED = 2;
 
     /**
      * Companion app receives {@link #onDeviceEvent(AssociationInfo, int)} callback
      * with this event if the bluetooth device is disconnected.
      */
+    @FlaggedApi(Flags.FLAG_DEVICE_PRESENCE)
     public static final int DEVICE_EVENT_BT_DISCONNECTED = 3;
 
     /**
@@ -165,6 +170,7 @@
      * {@link #onDeviceEvent(AssociationInfo, int)} if it reports that a device has appeared on its
      * own.
      */
+    @FlaggedApi(Flags.FLAG_DEVICE_PRESENCE)
     public static final int DEVICE_EVENT_SELF_MANAGED_APPEARED = 4;
 
     /**
@@ -172,6 +178,7 @@
      * {@link #onDeviceEvent(AssociationInfo, int)} if it reports that a device has disappeared on
      * its own.
      */
+    @FlaggedApi(Flags.FLAG_DEVICE_PRESENCE)
     public static final int DEVICE_EVENT_SELF_MANAGED_DISAPPEARED = 5;
 
     private final Stub mRemote = new Stub();
@@ -348,6 +355,7 @@
      * @param associationInfo A record for the companion device.
      * @param event Associated companion device's event.
      */
+    @FlaggedApi(Flags.FLAG_DEVICE_PRESENCE)
     @MainThread
     public void onDeviceEvent(@NonNull AssociationInfo associationInfo,
             @DeviceEvent int event) {
diff --git a/core/java/android/companion/flags.aconfig b/core/java/android/companion/flags.aconfig
index 4f9c849..6e33dff 100644
--- a/core/java/android/companion/flags.aconfig
+++ b/core/java/android/companion/flags.aconfig
@@ -19,4 +19,11 @@
     namespace: "companion"
     description: "Enable Association tag APIs "
     bug: "289241123"
-}
\ No newline at end of file
+}
+
+flag {
+    name: "device_presence"
+    namespace: "companion"
+    description: "Enable device presence APIs"
+    bug: "283000075"
+}
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
index bf77681..db7055b 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
@@ -357,7 +357,7 @@
             mCameraRepeatingSurface = mRepeatingRequestImageReader.getSurface();
         }
         mRepeatingRequestImageCallback = new CameraOutputImageCallback(
-                mRepeatingRequestImageReader);
+                mRepeatingRequestImageReader, true /*pruneOlderBuffers*/);
         mRepeatingRequestImageReader
                 .setOnImageAvailableListener(mRepeatingRequestImageCallback, mHandler);
     }
@@ -398,7 +398,8 @@
                         CameraExtensionCharacteristics.PROCESSING_INPUT_FORMAT);
             }
 
-            mBurstCaptureImageCallback = new CameraOutputImageCallback(mBurstCaptureImageReader);
+            mBurstCaptureImageCallback = new CameraOutputImageCallback(mBurstCaptureImageReader,
+                    false /*pruneOlderBuffers*/);
             mBurstCaptureImageReader.setOnImageAvailableListener(mBurstCaptureImageCallback,
                     mHandler);
             mCameraBurstSurface = mBurstCaptureImageReader.getSurface();
@@ -1106,7 +1107,9 @@
                 }
 
                 for (Pair<Image, TotalCaptureResult> captureStage : mCaptureStageMap.values()) {
-                    captureStage.first.close();
+                    if (captureStage.first != null) {
+                        captureStage.first.close();
+                    }
                 }
                 mCaptureStageMap.clear();
             }
@@ -1207,6 +1210,7 @@
                 if (mImageProcessor != null) {
                     if (mCapturePendingMap.indexOfKey(timestamp) >= 0) {
                         Image img = mCapturePendingMap.get(timestamp).first;
+                        mCapturePendingMap.remove(timestamp);
                         mCaptureStageMap.put(stageId, new Pair<>(img, result));
                         checkAndFireBurstProcessing();
                     } else {
@@ -1303,6 +1307,7 @@
                 reader.detachImage(img);
                 if (mCapturePendingMap.indexOfKey(timestamp) >= 0) {
                     Integer stageId = mCapturePendingMap.get(timestamp).second;
+                    mCapturePendingMap.remove(timestamp);
                     Pair<Image, TotalCaptureResult> captureStage =
                             mCaptureStageMap.get(stageId);
                     if (captureStage != null) {
@@ -1402,9 +1407,11 @@
         private HashMap<Long, Pair<Image, OnImageAvailableListener>> mImageListenerMap =
                 new HashMap<>();
         private boolean mOutOfBuffers = false;
+        private final boolean mPruneOlderBuffers;
 
-        CameraOutputImageCallback(ImageReader imageReader) {
+        CameraOutputImageCallback(ImageReader imageReader, boolean pruneOlderBuffers) {
             mImageReader = imageReader;
+            mPruneOlderBuffers = pruneOlderBuffers;
         }
 
         @Override
@@ -1447,6 +1454,10 @@
                 ArrayList<Long> removedTs = new ArrayList<>();
                 for (long ts : timestamps) {
                     if (ts < timestamp) {
+                        if (!mPruneOlderBuffers) {
+                            Log.w(TAG, "Unexpected older image with ts: " + ts);
+                            continue;
+                        }
                         Log.e(TAG, "Dropped image with ts: " + ts);
                         Pair<Image, OnImageAvailableListener> entry = mImageListenerMap.get(ts);
                         if (entry.second != null) {
diff --git a/core/java/android/nfc/flags.aconfig b/core/java/android/nfc/flags.aconfig
index 55b0b42..cd50ace 100644
--- a/core/java/android/nfc/flags.aconfig
+++ b/core/java/android/nfc/flags.aconfig
@@ -13,3 +13,10 @@
     description: "Flag for NFC reader option API changes"
     bug: "291187960"
 }
+
+flag {
+    name: "enable_nfc_user_restriction"
+    namespace: "nfc"
+    description: "Flag for NFC user restriction"
+    bug: "291187960"
+}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 9034ff1..72bc211 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -23,6 +23,7 @@
 import android.accounts.AccountManager;
 import android.annotation.ColorInt;
 import android.annotation.DrawableRes;
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -58,6 +59,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.location.LocationManager;
+import android.nfc.Flags;
 import android.provider.Settings;
 import android.util.AndroidException;
 import android.util.ArraySet;
@@ -1871,6 +1873,7 @@
      * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
      * @see #getUserRestrictions()
      */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_USER_RESTRICTION)
     public static final String DISALLOW_NEAR_FIELD_COMMUNICATION_RADIO =
             "no_near_field_communication_radio";
 
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 42b3e38..57011e8 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -364,14 +364,6 @@
             "enable_content_protection_receiver";
 
     /**
-     * Sets the size of the app blocklist for the content protection flow.
-     *
-     * @hide
-     */
-    public static final String DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE =
-            "content_protection_apps_blocklist_size";
-
-    /**
      * Sets the size of the in-memory ring buffer for the content protection flow.
      *
      * @hide
@@ -440,8 +432,6 @@
     /** @hide */
     public static final boolean DEFAULT_ENABLE_CONTENT_PROTECTION_RECEIVER = false;
     /** @hide */
-    public static final int DEFAULT_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE = 5000;
-    /** @hide */
     public static final int DEFAULT_CONTENT_PROTECTION_BUFFER_SIZE = 150;
     /** @hide */
     public static final List<List<String>> DEFAULT_CONTENT_PROTECTION_REQUIRED_GROUPS =
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 79b3b4f..4705dc5 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -23,7 +23,7 @@
 }
 
 flag {
-  name: "dimmer_refactor"
+  name: "introduce_smoother_dimmer"
   namespace: "windowing_frontend"
   description: "Refactor dim to fix flickers"
   bug: "295291019"
diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp
index f97d41b..262f5e8 100644
--- a/core/jni/android_view_InputDevice.cpp
+++ b/core/jni/android_view_InputDevice.cpp
@@ -42,13 +42,6 @@
         return NULL;
     }
 
-    // b/274058082: Pass a copy of the key character map to avoid concurrent
-    // access
-    std::shared_ptr<KeyCharacterMap> map = deviceInfo.getKeyCharacterMap();
-    if (map != nullptr) {
-        map = std::make_shared<KeyCharacterMap>(*map);
-    }
-
     ScopedLocalRef<jstring> descriptorObj(env,
             env->NewStringUTF(deviceInfo.getIdentifier().descriptor.c_str()));
     if (!descriptorObj.get()) {
@@ -67,9 +60,14 @@
                                                                   ? layoutInfo->layoutType.c_str()
                                                                   : NULL));
 
+    std::shared_ptr<KeyCharacterMap> map = deviceInfo.getKeyCharacterMap();
+    std::unique_ptr<KeyCharacterMap> mapCopy;
+    if (map != nullptr) {
+        mapCopy = std::make_unique<KeyCharacterMap>(*map);
+    }
     ScopedLocalRef<jobject> kcmObj(env,
                                    android_view_KeyCharacterMap_create(env, deviceInfo.getId(),
-                                                                       map));
+                                                                       std::move(mapCopy)));
     if (!kcmObj.get()) {
         return NULL;
     }
diff --git a/core/jni/android_view_KeyCharacterMap.cpp b/core/jni/android_view_KeyCharacterMap.cpp
index 7f69e22..a79e37a 100644
--- a/core/jni/android_view_KeyCharacterMap.cpp
+++ b/core/jni/android_view_KeyCharacterMap.cpp
@@ -48,7 +48,7 @@
 
 class NativeKeyCharacterMap {
 public:
-    NativeKeyCharacterMap(int32_t deviceId, std::shared_ptr<KeyCharacterMap> map)
+    NativeKeyCharacterMap(int32_t deviceId, std::unique_ptr<KeyCharacterMap> map)
           : mDeviceId(deviceId), mMap(std::move(map)) {}
 
     ~NativeKeyCharacterMap() {
@@ -58,16 +58,18 @@
         return mDeviceId;
     }
 
-    inline const std::shared_ptr<KeyCharacterMap> getMap() const { return mMap; }
+    inline const std::unique_ptr<KeyCharacterMap>& getMap() const {
+        return mMap;
+    }
 
 private:
     int32_t mDeviceId;
-    std::shared_ptr<KeyCharacterMap> mMap;
+    std::unique_ptr<KeyCharacterMap> mMap;
 };
 
 jobject android_view_KeyCharacterMap_create(JNIEnv* env, int32_t deviceId,
-                                            const std::shared_ptr<KeyCharacterMap> kcm) {
-    NativeKeyCharacterMap* nativeMap = new NativeKeyCharacterMap(deviceId, kcm);
+                                            std::unique_ptr<KeyCharacterMap> kcm) {
+    NativeKeyCharacterMap* nativeMap = new NativeKeyCharacterMap(deviceId, std::move(kcm));
     if (!nativeMap) {
         return nullptr;
     }
@@ -91,7 +93,7 @@
         return 0;
     }
 
-    std::shared_ptr<KeyCharacterMap> kcm = nullptr;
+    std::unique_ptr<KeyCharacterMap> kcm;
     // Check if map is a null character map
     if (parcel->readBool()) {
         kcm = KeyCharacterMap::readFromParcel(parcel);
@@ -99,7 +101,7 @@
             return 0;
         }
     }
-    NativeKeyCharacterMap* map = new NativeKeyCharacterMap(deviceId, kcm);
+    NativeKeyCharacterMap* map = new NativeKeyCharacterMap(deviceId, std::move(kcm));
     return reinterpret_cast<jlong>(map);
 }
 
@@ -230,9 +232,9 @@
 }
 
 static jboolean nativeEquals(JNIEnv* env, jobject clazz, jlong ptr1, jlong ptr2) {
-    const std::shared_ptr<KeyCharacterMap>& map1 =
+    const std::unique_ptr<KeyCharacterMap>& map1 =
             (reinterpret_cast<NativeKeyCharacterMap*>(ptr1))->getMap();
-    const std::shared_ptr<KeyCharacterMap>& map2 =
+    const std::unique_ptr<KeyCharacterMap>& map2 =
             (reinterpret_cast<NativeKeyCharacterMap*>(ptr2))->getMap();
     if (map1 == nullptr || map2 == nullptr) {
         return map1 == map2;
diff --git a/core/jni/android_view_KeyCharacterMap.h b/core/jni/android_view_KeyCharacterMap.h
index be03353..a8aabd1 100644
--- a/core/jni/android_view_KeyCharacterMap.h
+++ b/core/jni/android_view_KeyCharacterMap.h
@@ -25,7 +25,7 @@
 
 /* Creates a KeyCharacterMap object from the given information. */
 extern jobject android_view_KeyCharacterMap_create(JNIEnv* env, int32_t deviceId,
-                                                   const std::shared_ptr<KeyCharacterMap> kcm);
+                                                   std::unique_ptr<KeyCharacterMap> kcm);
 
 } // namespace android
 
diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java
index 7f3e014..9430ba6 100644
--- a/core/tests/coretests/src/android/app/NotificationTest.java
+++ b/core/tests/coretests/src/android/app/NotificationTest.java
@@ -857,7 +857,8 @@
             assertEquals(cDay.getPrimaryAccentColor(), cNight.getPrimaryAccentColor());
             assertEquals(cDay.getSecondaryAccentColor(), cNight.getSecondaryAccentColor());
             assertEquals(cDay.getTertiaryAccentColor(), cNight.getTertiaryAccentColor());
-            assertEquals(cDay.getOnAccentTextColor(), cNight.getOnAccentTextColor());
+            assertEquals(cDay.getOnTertiaryAccentTextColor(),
+                    cNight.getOnTertiaryAccentTextColor());
             assertEquals(cDay.getProtectionColor(), cNight.getProtectionColor());
             assertEquals(cDay.getContrastColor(), cNight.getContrastColor());
             assertEquals(cDay.getRippleAlpha(), cNight.getRippleAlpha());
@@ -1830,7 +1831,7 @@
         assertThat(c.getPrimaryAccentColor()).isNotEqualTo(Notification.COLOR_INVALID);
         assertThat(c.getSecondaryAccentColor()).isNotEqualTo(Notification.COLOR_INVALID);
         assertThat(c.getTertiaryAccentColor()).isNotEqualTo(Notification.COLOR_INVALID);
-        assertThat(c.getOnAccentTextColor()).isNotEqualTo(Notification.COLOR_INVALID);
+        assertThat(c.getOnTertiaryAccentTextColor()).isNotEqualTo(Notification.COLOR_INVALID);
         assertThat(c.getErrorColor()).isNotEqualTo(Notification.COLOR_INVALID);
         assertThat(c.getContrastColor()).isNotEqualTo(Notification.COLOR_INVALID);
         assertThat(c.getRippleAlpha()).isAtLeast(0x00);
@@ -1848,7 +1849,7 @@
         assertContrastIsAtLeast(c.getTertiaryAccentColor(), c.getBackgroundColor(), 1);
 
         // The text that is used within the accent color DOES need to have contrast
-        assertContrastIsAtLeast(c.getOnAccentTextColor(), c.getTertiaryAccentColor(), 4.5);
+        assertContrastIsAtLeast(c.getOnTertiaryAccentTextColor(), c.getTertiaryAccentColor(), 4.5);
     }
 
     private void resolveColorsInNightMode(boolean nightMode, Notification.Colors c, int rawColor,
diff --git a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
index 531404b..d10cf16 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
@@ -62,4 +62,24 @@
         verify(callback2, times(1)).preExecute(clientTransactionHandler);
         verify(stateRequest, times(1)).preExecute(clientTransactionHandler);
     }
+
+    @Test
+    public void testPreExecuteTransactionItems() {
+        final ClientTransactionItem callback1 = mock(ClientTransactionItem.class);
+        final ClientTransactionItem callback2 = mock(ClientTransactionItem.class);
+        final ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class);
+        final ClientTransactionHandler clientTransactionHandler =
+                mock(ClientTransactionHandler.class);
+
+        final ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
+        transaction.addTransactionItem(callback1);
+        transaction.addTransactionItem(callback2);
+        transaction.addTransactionItem(stateRequest);
+
+        transaction.preExecute(clientTransactionHandler);
+
+        verify(callback1, times(1)).preExecute(clientTransactionHandler);
+        verify(callback2, times(1)).preExecute(clientTransactionHandler);
+        verify(stateRequest, times(1)).preExecute(clientTransactionHandler);
+    }
 }
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
index 44a4d58..f2b0f2e 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
@@ -247,6 +247,31 @@
     }
 
     @Test
+    public void testExecuteTransactionItems_transactionResolution() {
+        ClientTransactionItem callback1 = mock(ClientTransactionItem.class);
+        when(callback1.getPostExecutionState()).thenReturn(UNDEFINED);
+        ClientTransactionItem callback2 = mock(ClientTransactionItem.class);
+        when(callback2.getPostExecutionState()).thenReturn(UNDEFINED);
+        ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class);
+        IBinder token = mock(IBinder.class);
+        when(stateRequest.getActivityToken()).thenReturn(token);
+        when(mTransactionHandler.getActivity(token)).thenReturn(mock(Activity.class));
+
+        ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
+        transaction.addTransactionItem(callback1);
+        transaction.addTransactionItem(callback2);
+        transaction.addTransactionItem(stateRequest);
+
+        transaction.preExecute(mTransactionHandler);
+        mExecutor.execute(transaction);
+
+        InOrder inOrder = inOrder(mTransactionHandler, callback1, callback2, stateRequest);
+        inOrder.verify(callback1).execute(eq(mTransactionHandler), any());
+        inOrder.verify(callback2).execute(eq(mTransactionHandler), any());
+        inOrder.verify(stateRequest).execute(eq(mTransactionHandler), eq(mClientRecord), any());
+    }
+
+    @Test
     public void testDoNotLaunchDestroyedActivity() {
         final Map<IBinder, DestroyActivityItem> activitiesToBeDestroyed = new ArrayMap<>();
         when(mTransactionHandler.getActivitiesToBeDestroyed()).thenReturn(activitiesToBeDestroyed);
@@ -279,12 +304,43 @@
     }
 
     @Test
+    public void testExecuteTransactionItems_doNotLaunchDestroyedActivity() {
+        final Map<IBinder, DestroyActivityItem> activitiesToBeDestroyed = new ArrayMap<>();
+        when(mTransactionHandler.getActivitiesToBeDestroyed()).thenReturn(activitiesToBeDestroyed);
+        // Assume launch transaction is still in queue, so there is no client record.
+        when(mTransactionHandler.getActivityClient(any())).thenReturn(null);
+
+        // An incoming destroy transaction enters binder thread (preExecute).
+        final IBinder token = mock(IBinder.class);
+        final ClientTransaction destroyTransaction = ClientTransaction.obtain(null /* client */);
+        destroyTransaction.addTransactionItem(
+                DestroyActivityItem.obtain(token, false /* finished */, 0 /* configChanges */));
+        destroyTransaction.preExecute(mTransactionHandler);
+        // The activity should be added to to-be-destroyed container.
+        assertEquals(1, activitiesToBeDestroyed.size());
+
+        // A previous queued launch transaction runs on main thread (execute).
+        final ClientTransaction launchTransaction = ClientTransaction.obtain(null /* client */);
+        final LaunchActivityItem launchItem =
+                spy(new LaunchActivityItemBuilder().setActivityToken(token).build());
+        launchTransaction.addTransactionItem(launchItem);
+        mExecutor.execute(launchTransaction);
+
+        // The launch transaction should not be executed because its token is in the
+        // to-be-destroyed container.
+        verify(launchItem, never()).execute(any(), any());
+
+        // After the destroy transaction has been executed, the token should be removed.
+        mExecutor.execute(destroyTransaction);
+        assertTrue(activitiesToBeDestroyed.isEmpty());
+    }
+
+    @Test
     public void testActivityResultRequiredStateResolution() {
         when(mTransactionHandler.getActivity(any())).thenReturn(mock(Activity.class));
 
         PostExecItem postExecItem = new PostExecItem(ON_RESUME);
 
-        IBinder token = mock(IBinder.class);
         ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
         transaction.addCallback(postExecItem);
 
@@ -300,6 +356,26 @@
     }
 
     @Test
+    public void testExecuteTransactionItems_activityResultRequiredStateResolution() {
+        when(mTransactionHandler.getActivity(any())).thenReturn(mock(Activity.class));
+
+        PostExecItem postExecItem = new PostExecItem(ON_RESUME);
+
+        ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
+        transaction.addTransactionItem(postExecItem);
+
+        // Verify resolution that should get to onPause
+        mClientRecord.setState(ON_RESUME);
+        mExecutor.executeTransactionItems(transaction);
+        verify(mExecutor).cycleToPath(eq(mClientRecord), eq(ON_PAUSE), eq(transaction));
+
+        // Verify resolution that should get to onStart
+        mClientRecord.setState(ON_STOP);
+        mExecutor.executeTransactionItems(transaction);
+        verify(mExecutor).cycleToPath(eq(mClientRecord), eq(ON_START), eq(transaction));
+    }
+
+    @Test
     public void testClosestStateResolutionForSameState() {
         final int[] allStates = new int[] {
                 ON_CREATE, ON_START, ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY};
@@ -444,6 +520,18 @@
         mExecutor.executeCallbacks(transaction);
     }
 
+    @Test(expected = IllegalArgumentException.class)
+    public void testExecuteTransactionItems_activityItemNullRecordThrowsException() {
+        final ActivityTransactionItem activityItem = mock(ActivityTransactionItem.class);
+        when(activityItem.getPostExecutionState()).thenReturn(UNDEFINED);
+        final IBinder token = mock(IBinder.class);
+        final ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
+        transaction.addTransactionItem(activityItem);
+        when(mTransactionHandler.getActivityClient(token)).thenReturn(null);
+
+        mExecutor.executeTransactionItems(transaction);
+    }
+
     @Test
     public void testActivityItemExecute() {
         final IBinder token = mock(IBinder.class);
@@ -464,6 +552,26 @@
         inOrder.verify(stateRequest).execute(eq(mTransactionHandler), eq(mClientRecord), any());
     }
 
+    @Test
+    public void testExecuteTransactionItems_activityItemExecute() {
+        final IBinder token = mock(IBinder.class);
+        final ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
+        final ActivityTransactionItem activityItem = mock(ActivityTransactionItem.class);
+        when(activityItem.getPostExecutionState()).thenReturn(UNDEFINED);
+        when(activityItem.getActivityToken()).thenReturn(token);
+        transaction.addTransactionItem(activityItem);
+        final ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class);
+        transaction.addTransactionItem(stateRequest);
+        when(stateRequest.getActivityToken()).thenReturn(token);
+        when(mTransactionHandler.getActivity(token)).thenReturn(mock(Activity.class));
+
+        mExecutor.execute(transaction);
+
+        final InOrder inOrder = inOrder(activityItem, stateRequest);
+        inOrder.verify(activityItem).execute(eq(mTransactionHandler), eq(mClientRecord), any());
+        inOrder.verify(stateRequest).execute(eq(mTransactionHandler), eq(mClientRecord), any());
+    }
+
     private static int[] shuffledArray(int[] inputArray) {
         final List<Integer> list = Arrays.stream(inputArray).boxed().collect(Collectors.toList());
         Collections.shuffle(list);
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index 7d047c9..4aa62c5 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -285,6 +285,10 @@
                 78 /* configChanges */);
 
         ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
+        transaction.addTransactionItem(callback1);
+        transaction.addTransactionItem(callback2);
+        transaction.addTransactionItem(lifecycleRequest);
+
         transaction.addCallback(callback1);
         transaction.addCallback(callback2);
         transaction.setLifecycleStateRequest(lifecycleRequest);
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index 18796494..fd4522e 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -172,4 +172,5 @@
     kotlincflags: ["-Xjvm-default=all"],
     manifest: "AndroidManifest.xml",
     plugins: ["dagger2-compiler"],
+    use_resource_processor: true,
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index dddcbd4..f0da35d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -317,7 +317,8 @@
         mBubbleIconFactory = new BubbleIconFactory(context,
                 context.getResources().getDimensionPixelSize(R.dimen.bubble_size),
                 context.getResources().getDimensionPixelSize(R.dimen.bubble_badge_size),
-                context.getResources().getColor(R.color.important_conversation),
+                context.getResources().getColor(
+                        com.android.launcher3.icons.R.color.important_conversation),
                 context.getResources().getDimensionPixelSize(
                         com.android.internal.R.dimen.importance_ring_stroke_width));
         mDisplayController = displayController;
@@ -949,7 +950,8 @@
         mBubbleIconFactory = new BubbleIconFactory(mContext,
                 mContext.getResources().getDimensionPixelSize(R.dimen.bubble_size),
                 mContext.getResources().getDimensionPixelSize(R.dimen.bubble_badge_size),
-                mContext.getResources().getColor(R.color.important_conversation),
+                mContext.getResources().getColor(
+                        com.android.launcher3.icons.R.color.important_conversation),
                 mContext.getResources().getDimensionPixelSize(
                         com.android.internal.R.dimen.importance_ring_stroke_width));
 
@@ -988,7 +990,8 @@
                 mBubbleIconFactory = new BubbleIconFactory(mContext,
                         mContext.getResources().getDimensionPixelSize(R.dimen.bubble_size),
                         mContext.getResources().getDimensionPixelSize(R.dimen.bubble_badge_size),
-                        mContext.getResources().getColor(R.color.important_conversation),
+                        mContext.getResources().getColor(
+                                com.android.launcher3.icons.R.color.important_conversation),
                         mContext.getResources().getDimensionPixelSize(
                                 com.android.internal.R.dimen.importance_ring_stroke_width));
                 mStackView.onDisplaySizeChanged();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
index dc099d9..22e836a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
@@ -113,7 +113,7 @@
                 context,
                 res.getDimensionPixelSize(R.dimen.bubble_size),
                 res.getDimensionPixelSize(R.dimen.bubble_badge_size),
-                res.getColor(R.color.important_conversation),
+                res.getColor(com.android.launcher3.icons.R.color.important_conversation),
                 res.getDimensionPixelSize(com.android.internal.R.dimen.importance_ring_stroke_width)
             )
 
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 14602ef..7fac0c9 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -562,7 +562,11 @@
 void CanvasContext::draw(bool solelyTextureViewUpdates) {
     if (auto grContext = getGrContext()) {
         if (grContext->abandoned()) {
-            LOG_ALWAYS_FATAL("GrContext is abandoned/device lost at start of CanvasContext::draw");
+            if (grContext->isDeviceLost()) {
+                LOG_ALWAYS_FATAL("Lost GPU device unexpectedly");
+                return;
+            }
+            LOG_ALWAYS_FATAL("GrContext is abandoned at start of CanvasContext::draw");
             return;
         }
     }
diff --git a/packages/SettingsProvider/Android.bp b/packages/SettingsProvider/Android.bp
index f4ca260..a4a9290 100644
--- a/packages/SettingsProvider/Android.bp
+++ b/packages/SettingsProvider/Android.bp
@@ -17,9 +17,10 @@
     ],
 }
 
-android_app {
-    name: "SettingsProvider",
+android_library {
+    name: "SettingsProviderLib",
     defaults: ["platform_app_defaults"],
+    manifest: "AndroidManifestLib.xml",
     resource_dirs: ["res"],
     srcs: [
         "src/**/*.java",
@@ -32,38 +33,37 @@
     ],
     static_libs: [
         "device_config_service_flags_java",
-        "junit",
         "SettingsLibDeviceStateRotationLock",
         "SettingsLibDisplayUtils",
     ],
     platform_apis: true,
+}
+
+android_app {
+    name: "SettingsProvider",
+    defaults: ["platform_app_defaults"],
+    resource_dirs: [],
+    static_libs: ["SettingsProviderLib"],
+    platform_apis: true,
     certificate: "platform",
     privileged: true,
 }
 
 android_test {
     name: "SettingsProviderTest",
-    // Note we statically link several classes to do some unit tests.  It's not accessible otherwise
-    // because this test is not an instrumentation test. (because the target runs in the system process.)
     srcs: [
         "test/**/*.java",
-        "src/android/provider/settings/backup/*",
-        "src/android/provider/settings/validators/*",
-        "src/com/android/providers/settings/GenerationRegistry.java",
-        "src/com/android/providers/settings/SettingsBackupAgent.java",
-        "src/com/android/providers/settings/SettingsState.java",
-        "src/com/android/providers/settings/SettingsHelper.java",
-        "src/com/android/providers/settings/WifiSoftApConfigChangedNotifier.java",
     ],
     static_libs: [
+        // Note we statically link SettingsProviderLib to do some unit tests.  It's not accessible otherwise
+        // because this test is not an instrumentation test. (because the target runs in the system process.)
+        "SettingsProviderLib",
+
         "androidx.test.rules",
-        "device_config_service_flags_java",
         "flag-junit",
+        "junit",
         "mockito-target-minus-junit4",
         "platform-test-annotations",
-        "SettingsLibDeviceStateRotationLock",
-        "SettingsLibDisplayUtils",
-        "platform-test-annotations",
         "truth",
     ],
     libs: [
@@ -71,12 +71,7 @@
         "android.test.mock",
         "unsupportedappusage",
     ],
-    resource_dirs: ["res"],
-    aaptflags: [
-        "--auto-add-overlay",
-        "--extra-packages",
-        "com.android.providers.settings",
-    ],
+    resource_dirs: [],
     platform_apis: true,
     certificate: "platform",
     test_suites: ["device-tests"],
diff --git a/packages/SettingsProvider/AndroidManifestLib.xml b/packages/SettingsProvider/AndroidManifestLib.xml
new file mode 100644
index 0000000..a20b539
--- /dev/null
+++ b/packages/SettingsProvider/AndroidManifestLib.xml
@@ -0,0 +1,2 @@
+<manifest package="com.android.providers.settings">
+</manifest>
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 9d3200d..e6a82e8 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -214,6 +214,7 @@
 
     lint: {
         extra_check_modules: ["SystemUILintChecker"],
+        warning_checks: ["MissingApacheLicenseDetector"],
     },
 }
 
@@ -254,7 +255,6 @@
     srcs: [
         /* Keyguard converted tests */
         // data
-        "tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt",
         "tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt",
         "tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt",
         "tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt",
@@ -402,10 +402,19 @@
         "tests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt",
         "tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt",
         "tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt",
+
     ],
     path: "tests/src",
 }
 
+filegroup {
+    name: "SystemUI-tests-multivalent",
+    srcs: [
+        "multivalentTests/src/**/*.kt",
+    ],
+    path: "multivalentTests/src",
+}
+
 java_library {
     name: "SystemUI-tests-concurrency",
     srcs: [
@@ -494,6 +503,7 @@
         "src/**/*.java",
         "src/**/I*.aidl",
         ":ReleaseJavaFiles",
+        ":SystemUI-tests-multivalent",
         ":SystemUI-tests-utils",
     ],
     static_libs: [
@@ -572,6 +582,7 @@
         ":SystemUI-tests-utils",
         ":SystemUI-test-fakes",
         ":SystemUI-tests-robolectric-pilots",
+        ":SystemUI-tests-multivalent",
     ],
     static_libs: [
         "androidx.test.uiautomator_uiautomator",
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
index 4ea57a8..ab4db45 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -290,9 +290,10 @@
         controller: Controller?,
         animate: Boolean = true,
         packageName: String? = null,
+        showOverLockscreen: Boolean = false,
         intentStarter: PendingIntentStarter
     ) {
-        startIntentWithAnimation(controller, animate, packageName) {
+        startIntentWithAnimation(controller, animate, packageName, showOverLockscreen) {
             intentStarter.startPendingIntent(it)
         }
     }
diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/MissingApacheLicenseDetector.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/MissingApacheLicenseDetector.kt
new file mode 100644
index 0000000..46125be
--- /dev/null
+++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/MissingApacheLicenseDetector.kt
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2023 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.internal.systemui.lint
+
+import com.android.ide.common.blame.SourcePosition
+import com.android.tools.lint.client.api.UElementHandler
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Location
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import java.time.Year
+import org.jetbrains.uast.UComment
+import org.jetbrains.uast.UFile
+
+/**
+ * Checks if every AOSP Java/Kotlin source code file is starting with Apache license information.
+ */
+class MissingApacheLicenseDetector : Detector(), SourceCodeScanner {
+
+    override fun getApplicableUastTypes() = listOf(UFile::class.java)
+
+    override fun createUastHandler(context: JavaContext): UElementHandler? {
+        return object : UElementHandler() {
+            override fun visitFile(node: UFile) {
+                val firstComment = node.allCommentsInFile.firstOrNull()
+                // Normally we don't need to explicitly handle suppressing case and just return
+                // error as usual with indicating node and lint will ignore it for us. But here
+                // suppressing will be applied on top of comment that doesn't exist so we don't have
+                // node to return - it's a bit of corner case
+                if (firstComment != null && firstComment.isSuppressingComment()) {
+                    return
+                }
+                if (firstComment == null || !firstComment.isLicenseComment()) {
+                    val firstLineOfFile =
+                        Location.create(
+                            context.file,
+                            SourcePosition(/* lineNumber= */ 1, /* column= */ 1, /* offset= */ 0)
+                        )
+                    context.report(
+                        issue = ISSUE,
+                        location = firstLineOfFile,
+                        message =
+                            "License header is missing\n" +
+                                "Please add the following copyright and license header to the" +
+                                " beginning of the file:\n\n" +
+                                copyrightHeader
+                    )
+                }
+            }
+        }
+    }
+
+    private fun UComment.isSuppressingComment(): Boolean {
+        val suppressingComment =
+            "//noinspection ${MissingApacheLicenseDetector::class.java.simpleName}"
+        return text.contains(suppressingComment)
+    }
+
+    private fun UComment.isLicenseComment(): Boolean {
+        // We probably don't want to compare full copyright header in case there are some small
+        // discrepancies in already existing files, e.g. year. We could do regexp but it should be
+        // good enough if this detector deals with missing
+        // license header instead of incorrect license header
+        return text.contains("Apache License")
+    }
+
+    private val copyrightHeader: String
+        get() =
+            """
+            /*
+             * Copyright (C) ${Year.now().value} 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.
+             */
+            """
+                .trimIndent()
+                .trim()
+
+    companion object {
+        @JvmField
+        val ISSUE: Issue =
+            Issue.create(
+                id = "MissingApacheLicenseDetector",
+                briefDescription = "File is missing Apache license information",
+                explanation =
+                    """
+                        Every source code file should have copyright and license information \
+                        attached at the beginning.""",
+                category = Category.COMPLIANCE,
+                priority = 8,
+                // ignored by default and then explicitly overridden in SysUI's soong configuration
+                severity = Severity.IGNORE,
+                implementation =
+                    Implementation(MissingApacheLicenseDetector::class.java, Scope.JAVA_FILE_SCOPE),
+            )
+    }
+}
diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
index 520c888..e09aa42 100644
--- a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
+++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
@@ -42,6 +42,7 @@
                 StaticSettingsProviderDetector.ISSUE,
                 DemotingTestWithoutBugDetector.ISSUE,
                 TestFunctionNameViolationDetector.ISSUE,
+                MissingApacheLicenseDetector.ISSUE,
             )
 
     override val api: Int
diff --git a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/MissingApacheLicenseDetectorTest.kt b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/MissingApacheLicenseDetectorTest.kt
new file mode 100644
index 0000000..78e133f
--- /dev/null
+++ b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/MissingApacheLicenseDetectorTest.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2023 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.internal.systemui.lint
+
+import com.android.tools.lint.checks.infrastructure.TestMode
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+import java.time.Year
+import org.junit.Test
+
+class MissingApacheLicenseDetectorTest : SystemUILintDetectorTest() {
+    override fun getDetector(): Detector {
+        return MissingApacheLicenseDetector()
+    }
+
+    override fun getIssues(): List<Issue> {
+        return listOf(
+            MissingApacheLicenseDetector.ISSUE,
+        )
+    }
+
+    @Test
+    fun testHasCopyright() {
+        lint()
+            .files(
+                kotlin(
+                    """
+                    /*
+                     * Copyright (C) ${Year.now().value} 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 test.pkg.name
+
+                    class MyTest
+                    """
+                        .trimIndent()
+                )
+            )
+            .issues(MissingApacheLicenseDetector.ISSUE)
+            .run()
+            .expectClean()
+    }
+
+    @Test
+    fun testDoesntHaveCopyright() {
+        lint()
+            .files(
+                kotlin(
+                    """
+                    package test.pkg.name
+
+                    class MyTest
+                    """
+                        .trimIndent()
+                )
+            )
+            // skipping mode SUPPRESSIBLE because lint tries to add @Suppress to class which
+            // probably doesn't make much sense for license header (which is far above it) and for
+            // kotlin files that can have several classes. If someone really wants to omit header
+            // they can do it with //noinspection
+            .skipTestModes(TestMode.SUPPRESSIBLE)
+            .issues(MissingApacheLicenseDetector.ISSUE)
+            .run()
+            .expectContains("License header is missing")
+    }
+}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt
index d70a248..2dc53ab 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt
@@ -157,6 +157,8 @@
      */
     private val positionalThreshold = with(layoutImpl.density) { 56.dp.toPx() }
 
+    internal var gestureWithPriority: Any? = null
+
     internal fun onDragStarted() {
         if (isDrivingTransition) {
             // This [transition] was already driving the animation: simply take over it.
@@ -525,15 +527,21 @@
     private val gestureHandler: SceneGestureHandler,
 ) : DraggableHandler {
     override suspend fun onDragStarted(coroutineScope: CoroutineScope, startedPosition: Offset) {
+        gestureHandler.gestureWithPriority = this
         gestureHandler.onDragStarted()
     }
 
     override fun onDelta(pixels: Float) {
-        gestureHandler.onDrag(delta = pixels)
+        if (gestureHandler.gestureWithPriority == this) {
+            gestureHandler.onDrag(delta = pixels)
+        }
     }
 
     override suspend fun onDragStopped(coroutineScope: CoroutineScope, velocity: Float) {
-        gestureHandler.onDragStopped(velocity = velocity, canChangeScene = true)
+        if (gestureHandler.gestureWithPriority == this) {
+            gestureHandler.gestureWithPriority = null
+            gestureHandler.onDragStopped(velocity = velocity, canChangeScene = true)
+        }
     }
 }
 
@@ -615,10 +623,15 @@
             },
             canContinueScroll = { priorityScene == gestureHandler.swipeTransitionToScene.key },
             onStart = {
+                gestureHandler.gestureWithPriority = this
                 priorityScene = nextScene
                 gestureHandler.onDragStarted()
             },
             onScroll = { offsetAvailable ->
+                if (gestureHandler.gestureWithPriority != this) {
+                    return@PriorityNestedScrollConnection Offset.Zero
+                }
+
                 val amount = offsetAvailable.toAmount()
 
                 // TODO(b/297842071) We should handle the overscroll or slow drag if the gesture is
@@ -628,6 +641,10 @@
                 amount.toOffset()
             },
             onStop = { velocityAvailable ->
+                if (gestureHandler.gestureWithPriority != this) {
+                    return@PriorityNestedScrollConnection Velocity.Zero
+                }
+
                 priorityScene = null
 
                 gestureHandler.onDragStopped(
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneGestureHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneGestureHandlerTest.kt
index 9b9e70d..6791a85 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneGestureHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneGestureHandlerTest.kt
@@ -312,4 +312,52 @@
         advanceUntilIdle()
         assertScene(currentScene = SceneA, isIdle = true)
     }
+
+    @Test
+    fun beforeDraggableStart_drag_shouldBeIgnored() = runGestureTest {
+        draggable.onDelta(deltaInPixels10)
+        assertScene(currentScene = SceneA, isIdle = true)
+    }
+    @Test
+    fun beforeDraggableStart_stop_shouldBeIgnored() = runGestureTest {
+        draggable.onDragStopped(coroutineScope, velocityThreshold)
+        assertScene(currentScene = SceneA, isIdle = true)
+    }
+
+    @Test
+    fun beforeNestedScrollStart_stop_shouldBeIgnored() = runGestureTest {
+        nestedScroll.onPreFling(Velocity(0f, velocityThreshold))
+        assertScene(currentScene = SceneA, isIdle = true)
+    }
+
+    @Test
+    fun startNestedScrollWhileDragging() = runGestureTest {
+        draggable.onDragStarted(coroutineScope, Offset.Zero)
+        assertScene(currentScene = SceneA, isIdle = false)
+        val transition = transitionState as Transition
+
+        draggable.onDelta(deltaInPixels10)
+        assertThat(transition.progress).isEqualTo(0.1f)
+
+        // now we can intercept the scroll events
+        nestedScrollEvents(available = offsetY10)
+        assertThat(transition.progress).isEqualTo(0.2f)
+
+        // this should be ignored, we are scrolling now!
+        draggable.onDragStopped(coroutineScope, velocityThreshold)
+        assertScene(currentScene = SceneA, isIdle = false)
+
+        nestedScrollEvents(available = offsetY10)
+        assertThat(transition.progress).isEqualTo(0.3f)
+
+        nestedScrollEvents(available = offsetY10)
+        assertThat(transition.progress).isEqualTo(0.4f)
+
+        nestedScroll.onPreFling(available = Velocity(0f, velocityThreshold))
+        assertScene(currentScene = SceneC, isIdle = false)
+
+        // wait for the stop animation
+        advanceUntilIdle()
+        assertScene(currentScene = SceneC, isIdle = true)
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt
diff --git a/packages/SystemUI/multivalentTestsForDevice b/packages/SystemUI/multivalentTestsForDevice
new file mode 120000
index 0000000..20ee34a
--- /dev/null
+++ b/packages/SystemUI/multivalentTestsForDevice
@@ -0,0 +1 @@
+multivalentTests
\ No newline at end of file
diff --git a/packages/SystemUI/multivalentTestsForDeviceless b/packages/SystemUI/multivalentTestsForDeviceless
new file mode 120000
index 0000000..20ee34a
--- /dev/null
+++ b/packages/SystemUI/multivalentTestsForDeviceless
@@ -0,0 +1 @@
+multivalentTests
\ No newline at end of file
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
index 9cc87fd..f0e3c99 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
@@ -57,6 +57,16 @@
             @Nullable ActivityLaunchAnimator.Controller animationController);
 
     /**
+     * Similar to {@link #startPendingIntentDismissingKeyguard}, except that it supports launching
+     * activities on top of the keyguard. If the activity supports {@code showOverLockscreen}, it
+     * will show over keyguard without first dimissing it. If it doesn't support it, calling this
+     * method is exactly the same as calling {@link #startPendingIntentDismissingKeyguard}.
+     */
+    void startPendingIntentMaybeDismissingKeyguard(PendingIntent intent,
+            @Nullable Runnable intentSentUiThreadCallback,
+            @Nullable ActivityLaunchAnimator.Controller animationController);
+
+    /**
      * The intent flag can be specified in startActivity().
      */
     void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade, int flags);
diff --git a/packages/SystemUI/res-keyguard/values-af/strings.xml b/packages/SystemUI/res-keyguard/values-af/strings.xml
index 2eb1bb5..a6a8122 100644
--- a/packages/SystemUI/res-keyguard/values-af/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-af/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laai tans stadig"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laaiproses word geoptimeer om battery te beskerm"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Kwessie met laaibykomstigheid"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Druk Kieslys om te ontsluit."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Netwerk is gesluit"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Geen SIM nie"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Voeg ’n SIM by."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"Die SIM is weg of nie leesbaar nie. Voeg ’n SIM by."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Onbruikbare SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Jou SIM is permanent gedeaktiveer.\n Kontak jou draadlose diensverskaffer vir ’n ander SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM is gesluit."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM is PUK-gesluit."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Ontsluit tans SIM …"</string>
diff --git a/packages/SystemUI/res-keyguard/values-am/strings.xml b/packages/SystemUI/res-keyguard/values-am/strings.xml
index 5fd946b..fb84414 100644
--- a/packages/SystemUI/res-keyguard/values-am/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-am/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • በዝግታ ኃይልን በመሙላት ላይ"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ባትሪን ለመጠበቅ ኃይል መሙላት ተብቷል"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ተለዋዋጭን ኃይል በመሙላት ላይ ችግር"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ለመክፈት ምናሌ ተጫን።"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"አውታረ መረብ ተቆልፏል"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"ምንም SIM የለም"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"ሲም ያክሉ።"</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"ሲሙ ጠፍቷል ወይም አይነበብም። ሲም ያክሉ።"</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"ጥቅም ላይ የማይውል ሲም።"</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"ሲምዎ በቋሚነት ቦዝኗል።\n ለሌላ ሲም የእርስዎን አገልግሎት ሰጪ ያግኙ።"</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"ሲም ተቆልፏል።"</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"ሲም በPUK የተቆለፈ ነው።"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"ሲምን በመክፈት ላይ…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml
index b6479f4..fb33092 100644
--- a/packages/SystemUI/res-keyguard/values-ar/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • جارٍ الشحن ببطء"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • تم تحسين الشحن لحماية البطارية"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"‫<xliff:g id="PERCENTAGE">%s</xliff:g> • مشكلة متعلّقة بجهاز الشحن الملحق"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"اضغط على \"القائمة\" لإلغاء التأمين."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"الشبكة مؤمّنة"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"‏لا تتوفر شريحة SIM."</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"‏يجب إضافة شريحة SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"‏شريحة SIM مفقودة أو غير قابلة للقراءة. يجب إضافة شريحة SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"‏شريحة SIM غير قابلة للاستخدام."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"‏تم إيقاف شريحة SIM نهائيًا.\n عليك التواصل مع مقدم خدمة اللاسلكي للحصول على شريحة SIM أخرى."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"‏شريحة SIM مُقفَلة."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"‏شريحة SIM مُقفَلة برمز PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"‏جارٍ إلغاء قفل شريحة SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-as/strings.xml b/packages/SystemUI/res-keyguard/values-as/strings.xml
index a41a704..a123bb7 100644
--- a/packages/SystemUI/res-keyguard/values-as/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-as/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • লাহে লাহে চাৰ্জ কৰি থকা হৈছে"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • বেটাৰী সুৰক্ষিত কৰিবলৈ চাৰ্জিং অপ্টিমাইজ কৰা হৈছে"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • চাৰ্জিঙৰ আনুষংগিক সামগ্ৰীত সমস্যা হৈছে"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"আনলক কৰিবলৈ মেনু টিপক।"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"নেটৱর্ক লক কৰা অৱস্থাত আছে"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"কোনো ছিম নাই"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"এখন ছিম যোগ দিয়ক।"</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"ছিম নাই অথবা সেইখন পঢ়িব নোৱাৰি। এখন ছিম যোগ দিয়ক।"</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"ব্যৱহাৰ কৰিব নোৱৰা ছিম।"</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"আপোনাৰ ছিমখন স্থায়ীভাৱে নিষ্ক্ৰিয় কৰা হৈছে।\n অন্য এখন ছিমৰ বাবে আপোনাৰ ৱায়াৰলেছ সেৱা প্ৰদানকাৰীৰ সৈতে যোগাযোগ কৰক।"</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"ছিমখন লক হৈ আছে।"</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"ছিমখন PUKৰ দ্বাৰা লক হৈ আছে।"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"ছিম আনলক কৰি থকা হৈছে…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-az/strings.xml b/packages/SystemUI/res-keyguard/values-az/strings.xml
index ed969c7..b133b30a 100644
--- a/packages/SystemUI/res-keyguard/values-az/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-az/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Yavaş enerji yığır"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Batareyanı qorumaq üçün şarj optimallaşdırılıb"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Şarj aksesuarı ilə bağlı problem"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Kilidi açmaq üçün Menyu düyməsinə basın."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Şəbəkə kilidlidir"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM yoxdur"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"SIM əlavə edin."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM kart yoxdur və ya oxuna bilinmir. SIM əlavə edin."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"İstifadəyə yararsız SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM kartınız həmişəlik deaktiv edilib.\n Başqa SIM kart üçün simsiz xidmət provayderinizə müraciət edin."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM kilidlənib."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM kart PUK ilə kilidlənib."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM kiliddən çıxarılır…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
index b0a6471..9a91962 100644
--- a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Sporo se puni"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Punjenje je optimizovano da bi se zaštitila baterija"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problem sa dodatnim priborom za punjenje"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pritisnite Meni da biste otključali."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Mreža je zaključana"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Nema SIM-a"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Dodajte SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM nedostaje ili ne može da se pročita. Dodajte SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Neupotrebljiv SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM je trajno deaktiviran.\n Obratite se dobavljaču usluge bežične telefonije da biste dobili drugi SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM je zaključan."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM je zaključan PUK-om."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Otključava se SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-be/strings.xml b/packages/SystemUI/res-keyguard/values-be/strings.xml
index 11cc77d..5e46b715 100644
--- a/packages/SystemUI/res-keyguard/values-be/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-be/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ідзе павольная зарадка"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • У мэтах зберажэння акумулятара зарадка аптымізавана"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Праблема з зараднай прыладай"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Націсніце кнопку \"Меню\", каб разблакіраваць."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Сетка заблакіравана"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Няма SIM-карты"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Дадайце SIM-карту."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM-карта адсутнічае ці не чытаецца. Дадайце SIM-карту."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Непрыдатная для выкарыстання SIM-карта."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Ваша SIM-карта адключана назаўсёды.\n Звяжыцеся з аператарам бесправадной сувязі, каб атрымаць іншую SIM-карту."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM-карта заблакіравана."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM-карта заблакіравана PUK-кодам."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Разблакіраванне SIM-карты…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bg/strings.xml b/packages/SystemUI/res-keyguard/values-bg/strings.xml
index c554a27..ab931ed 100644
--- a/packages/SystemUI/res-keyguard/values-bg/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bg/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарежда се бавно"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зареждането е оптимизирано с цел запазване на батерията"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Проблем със зарядното устройство"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Натиснете „Меню“, за да отключите."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Мрежата е заключена"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Няма SIM карта"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Добавете SIM карта."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM картата липсва или е нечетлива. Добавете SIM карта."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Неизползваема SIM карта."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM картата ви е деактивирана за постоянно.\nЗа да получите друга, се свържете с доставчика си на безжична услуга."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM картата е заключена."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM картата е заключена с PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM картата се отключва…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml
index 67b4e4b..e25de93 100644
--- a/packages/SystemUI/res-keyguard/values-bn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ধীরে চার্জ হচ্ছে"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ব্যাটারি ভাল রাখতে চার্জিং অপ্টিমাইজ করা হয়েছে"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • চার্জিং অ্যাক্সেসরিতে সমস্যা রয়েছে"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"আনলক করতে মেনুতে টিপুন।"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"নেটওয়ার্ক লক করা আছে"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"কোনও সিম নেই"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"সিম যোগ করুন।"</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"সিম নেই অথবা সেটি রিড করা যাচ্ছে না। সিম যোগ করুন।"</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"ব্যবহারযোগ্য নয় এমন সিম।"</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"আপনার সিম স্থায়ীভাবে বন্ধ করে দেওয়া হয়েছে।\n অন্য একটি সিমের জন্য আপনার ওয়্যারলেস পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন।"</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"সিম লক করা হয়েছে।"</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"সিম PUK লক করা হয়েছে।"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"সিম আনলক করা হচ্ছে…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bs/strings.xml b/packages/SystemUI/res-keyguard/values-bs/strings.xml
index 4c519c8..cd7aaeb 100644
--- a/packages/SystemUI/res-keyguard/values-bs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bs/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Sporo punjenje"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Punjenje je optimizirano radi zaštite baterije"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problem s opremom za punjenje"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pritisnite meni da otključate."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Mreža je zaključana"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Nema SIM-a"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Dodajte SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM nedostaje ili se ne može čitati. Dodajte SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Neupotrebljiv SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM je trajno deaktiviran.\n Kontaktirajte pružaoca bežičnih usluga za drugi SIM"</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM je zaključan."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM je zaključan PUK-om."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Otključavanje SIM-a…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml
index 3bd6508..bf8a592 100644
--- a/packages/SystemUI/res-keyguard/values-ca/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • S\'està carregant lentament"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Càrrega optimitzada per protegir la bateria"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problema relacionat amb l\'accessori de càrrega"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Prem Menú per desbloquejar."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"La xarxa està bloquejada"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"No hi ha cap SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Afegeix una SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"Falta la SIM o no es pot llegir. Afegeix una SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"La SIM no es pot utilitzar."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"La SIM s\'ha desactivat permanentment.\n Contacta amb el proveïdor de serveis sense fil per obtenir-ne una altra."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"La SIM està bloquejada."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"La SIM està bloquejada pel PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"S\'està desbloquejant la targeta SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-cs/strings.xml b/packages/SystemUI/res-keyguard/values-cs/strings.xml
index 573638b..bedafd8 100644
--- a/packages/SystemUI/res-keyguard/values-cs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-cs/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Pomalé nabíjení"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Optimalizované nabíjení za účelem ochrany baterie"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problém s nabíjecím příslušenstvím"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Klávesy odemknete stisknutím tlačítka nabídky."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Síť je blokována"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Žádná SIM karta"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Přidejte SIM kartu."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM karta chybí nebo je nečitelná. Přidejte SIM kartu."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM kartu nelze použít."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM karta byla natrvalo deaktivována.\n Požádejte svého poskytovatele bezdrátových služeb o další SIM kartu."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM karta je zablokována."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM karta je blokována pomocí kódu PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Odblokování SIM karty…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-da/strings.xml b/packages/SystemUI/res-keyguard/values-da/strings.xml
index c7c863b..93f505e 100644
--- a/packages/SystemUI/res-keyguard/values-da/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-da/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Oplader langsomt"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Opladning er optimeret for at beskytte batteriet"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problem med opladertilbehør"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Tryk på menuen for at låse op."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Netværket er låst"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Intet SIM-kort"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Tilføj et SIM-kort."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM-kortet mangler eller kan ikke læses. Tilføj et SIM-kort."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Deaktiveret SIM-kort."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Dit SIM-kort er permanent deaktiveret.\n Kontakt din tjenesteudbyder for at få et nyt SIM-kort."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM-kortet er låst."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM-kortet er låst med PUK-koden."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM-kortet låses op…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-de/strings.xml b/packages/SystemUI/res-keyguard/values-de/strings.xml
index 5c5f264..01e166e 100644
--- a/packages/SystemUI/res-keyguard/values-de/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-de/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Wird langsam geladen"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Optimiertes Laden zur Akkuschonung"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problem mit dem Ladezubehör"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Zum Entsperren die Menütaste drücken."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Netzwerk gesperrt"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Keine SIM-Karte"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Lege eine SIM-Karte ein."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM-Karte fehlt oder ist nicht lesbar. Lege eine SIM-Karte ein."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM-Karte ist nicht nutzbar."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Deine SIM-Karte wurde dauerhaft deaktiviert.\n Wende dich an deinen Mobilfunkanbieter, um eine andere SIM-Karte zu erhalten."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM-Karte ist gesperrt."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM-Karte ist mit einem PUK gesperrt."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM-Karte wird entsperrt…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-el/strings.xml b/packages/SystemUI/res-keyguard/values-el/strings.xml
index 3a01da5..9769242 100644
--- a/packages/SystemUI/res-keyguard/values-el/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-el/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Αργή φόρτιση"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Η φόρτιση βελτιστοποιήθηκε για την προστασία της μπαταρίας"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Πρόβλημα αξεσουάρ φόρτισης"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Πατήστε \"Μενού\" για ξεκλείδωμα."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Κλειδωμένο δίκτυο"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Δεν υπάρχει SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Προσθέστε μια SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"Η SIM λείπει ή δεν είναι δυνατή η ανάγνωσή της. Προσθέστε μια SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Η SIM δεν μπορεί να χρησιμοποιηθεί."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Η SIM απενεργοποιήθηκε οριστικά.\n Επικοινωνήστε με τον πάροχο υπηρεσιών ασύρματου δικτύου για μια νέα SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"Η SIM είναι κλειδωμένη."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"Η SIM έχει κλειδωθεί με κωδικό PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Ξεκλείδωμα SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
index a4b13487..087ab3a 100644
--- a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging slowly"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging optimised to protect battery"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Issue with charging accessory"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Press Menu to unlock."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Network locked"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"No SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Add a SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"The SIM is missing or not readable. Add a SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Unusable SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Your SIM has been permanently deactivated.\n Contact your wireless service provider for another SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM is locked."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM is PUK-locked."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Unlocking SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
index 480bcbb..7297cf9 100644
--- a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging slowly"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging optimized to protect battery"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Issue with charging accessory"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Press Menu to unlock."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Network locked"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"No SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Add a SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"The SIM is missing or not readable. Add a SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Unusable SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Your SIM has been permanently deactivated.\n Contact your wireless service provider for another SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM is locked."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM is PUK-locked."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Unlocking SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
index a4b13487..087ab3a 100644
--- a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging slowly"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging optimised to protect battery"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Issue with charging accessory"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Press Menu to unlock."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Network locked"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"No SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Add a SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"The SIM is missing or not readable. Add a SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Unusable SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Your SIM has been permanently deactivated.\n Contact your wireless service provider for another SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM is locked."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM is PUK-locked."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Unlocking SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
index a4b13487..087ab3a 100644
--- a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging slowly"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging optimised to protect battery"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Issue with charging accessory"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Press Menu to unlock."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Network locked"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"No SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Add a SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"The SIM is missing or not readable. Add a SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Unusable SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Your SIM has been permanently deactivated.\n Contact your wireless service provider for another SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM is locked."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM is PUK-locked."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Unlocking SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
index b8e89f4..ead8bce 100644
--- a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‎‎‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‎‎‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="PERCENTAGE">%s</xliff:g>‎‏‎‎‏‏‏‎ • Charging slowly‎‏‎‎‏‎"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‎‏‏‏‎‏‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‏‎‎‏‎‎‏‎‏‎‎‎‏‎‎‎‏‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="PERCENTAGE">%s</xliff:g>‎‏‎‎‏‏‏‎ • Charging optimized to protect battery‎‏‎‎‏‎"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‎‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎‎‎‎‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‏‎‏‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="PERCENTAGE">%s</xliff:g>‎‏‎‎‏‏‏‎ • Issue with charging accessory‎‏‎‎‏‎"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‎‎‏‏‏‎‏‎‎Press Menu to unlock.‎‏‎‎‏‎"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‏‎‎‏‏‎‎‏‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎Network locked‎‏‎‎‏‎"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‎‏‏‏‏‎‎‎‏‎‎‎‎‎‎‎‎‏‏‏‏‎‎‏‎‎‏‎‏‎‎‎‎No SIM‎‏‎‎‏‎"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎‎‎‎‎‎‏‏‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‏‏‎‎Add a SIM.‎‏‎‎‏‎"</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‎‏‏‎‏‎‎‎‎‏‎‎‎‎‏‎‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‎The SIM is missing or not readable. Add a SIM.‎‏‎‎‏‎"</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‎‎‎‏‏‎‎‏‎‏‎‏‏‎‏‎‎‎‎‎‎‏‎‎‏‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‎‏‏‎‎‎‎‏‎‏‎‎‎Unusable SIM.‎‏‎‎‏‎"</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‎‎‏‏‏‎‏‏‏‎‎‎‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‎‎‎Your SIM has been permanently deactivated.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎ Contact your wireless service provider for another SIM.‎‏‎‎‏‎"</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‏‎‏‎‏‎‏‏‏‎‏‎‏‏‏‏‏‎‎‏‏‎‎SIM is locked.‎‏‎‎‏‎"</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‏‎‎‎‎‎‏‎‏‏‎‎‏‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‏‏‏‎‎SIM is PUK-locked.‎‏‎‎‏‎"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‏‏‎‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎Unlocking SIM…‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
index debbeb1..5b82c44 100644
--- a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando lentamente"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carga optimizada para proteger la batería"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problema con el accesorio de carga"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Presiona Menú para desbloquear."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Bloqueada para la red"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"No hay ninguna tarjeta SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Introduce una tarjeta SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"Falta la tarjeta SIM o no se puede leer. Introduce una tarjeta SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Tarjeta SIM inutilizable."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Tu tarjeta SIM se desactivó permanentemente.\n Ponte en contacto con tu proveedor de servicios inalámbricos para obtener otra tarjeta SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"La tarjeta SIM está bloqueada."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"La tarjeta SIM está bloqueada con el código PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Desbloqueando tarjeta SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-es/strings.xml b/packages/SystemUI/res-keyguard/values-es/strings.xml
index 0ea98a8..cf7f3d2 100644
--- a/packages/SystemUI/res-keyguard/values-es/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando lentamente"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carga optimizada para proteger la batería"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problema con el accesorio de carga"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pulsa el menú para desbloquear la pantalla."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Bloqueada para la red"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"No hay ninguna SIM."</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Añade una SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"Falta la SIM o no se puede leer. Añade una SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"No se puede usar la SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Tu SIM se ha desactivado de forma permanente.\n Para obtener otra SIM, ponte en contacto con tu proveedor de servicios inalámbricos."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"La SIM está bloqueada."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"La SIM está bloqueada con el código PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Desbloqueando SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-et/strings.xml b/packages/SystemUI/res-keyguard/values-et/strings.xml
index 722a022..6335ca8 100644
--- a/packages/SystemUI/res-keyguard/values-et/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-et/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Aeglane laadimine"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laadimine on aku kaitsmiseks optimeeritud"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • probleem laadimistarvikuga"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Vajutage avamiseks menüüklahvi."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Võrk on lukus"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM-i pole"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Lisage SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM puudub või pole loetav. Lisage SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM-i ei saa kasutada."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Teie SIM on jäädavalt inaktiveeritud.\n Teise SIM-i saamiseks võtke ühendust oma traadita side teenusepakkujaga."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM on lukustatud."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM on PUK-koodiga lukustatud."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM-i avamine …"</string>
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index d329369..b47c58a 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mantso kargatzen"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Bateria ez kaltetzeko, kargatzeko modua optimizatu da"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Arazo bat dago kargatzeko osagarriarekin"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Desblokeatzeko, sakatu Menua."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Sarea blokeatuta dago"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Ez dago SIMik"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Gehitu SIM bat."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIMa falta da, edo ezin da irakurri. Gehitu SIM bat."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Ezin da erabili SIMa."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Betiko desaktibatu da SIMa.\n Jarri operadorearekin harremanetan beste SIM bat eskuratzeko."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIMa blokeatuta dago."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIMa PUKaren bidez desblokeatu behar da."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIMa desblokeatzen…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml
index ae3f04a..f274f5f 100644
--- a/packages/SystemUI/res-keyguard/values-fa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • آهسته‌آهسته شارژ می‌شود"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • برای محافظت از باتری، شارژ بهینه می‌شود"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • در شارژ وسیله جانبی مشکلی وجود دارد"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"برای باز کردن قفل روی «منو» فشار دهید."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"شبکه قفل شد"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"سیم‌کارتی وجود ندارد"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"سیم‌کارت اضافه کنید."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"سیم‌کارت موجود نیست یا قابل‌خواندن نیست. سیم‌کارت اضافه کنید."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"سیم‌کارت قابل‌استفاده نیست."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"سیم‌کارت شما برای همیشه غیرفعال شده است.\n برای دریافت سیم‌کارتی دیگر، با رساننده خدمات بی‌سیم خود تماس بگیرید."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"سیم‌کارت قفل است."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"‏سیم‌کارت با کد PUK قفل شده است."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"درحال باز کردن قفل سیم‌کارت…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fi/strings.xml b/packages/SystemUI/res-keyguard/values-fi/strings.xml
index 050df99..dd9ce2e4 100644
--- a/packages/SystemUI/res-keyguard/values-fi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fi/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ladataan hitaasti"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lataus optimoitu akun suojaamiseksi"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ongelma laturin kanssa"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Poista lukitus painamalla Valikkoa."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Verkko lukittu"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Ei SIM-korttia"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Lisää SIM-kortti."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM-korttia ei löydy tai ei voi lukea. Lisää SIM-kortti."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM-korttia ei voi käyttää."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Sim-kortti on poistettu käytöstä pysyvästi.\n Ota yhteyttä langattoman palvelun tarjoajaan ja pyydä uusi SIM-kortti."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM-kortti on lukittu."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM-kortti on lukittu PUK-koodilla."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM-kortin lukitusta avataan…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
index fa1a191..742f56e 100644
--- a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"En recharge lente : <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge optimisée pour protéger la pile"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problème concernant l\'accessoire de recharge"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Appuyez sur la touche Menu pour déverrouiller l\'appareil."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Réseau verrouillé"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Aucune carte SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Ajouter une carte SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"La carte SIM est manquante ou illisible. Ajouter une carte SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"La carte SIM est inutilisable."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Votre carte SIM a été désactivée de manière permanente.\n Communiquez avec votre fournisseur de services sans fil pour obtenir une autre carte SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"La carte SIM est verrouillée."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"La carte SIM est verrouillée par clé PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Déverrouillage de la carte SIM en cours…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr/strings.xml b/packages/SystemUI/res-keyguard/values-fr/strings.xml
index d687a1d..92d24c4 100644
--- a/packages/SystemUI/res-keyguard/values-fr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge lente"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge optimisée pour protéger la batterie"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problème de recharge de l\'accessoire"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Appuyez sur \"Menu\" pour déverrouiller le clavier."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Réseau verrouillé"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Aucune SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Ajoutez une SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"La SIM est absente ou illisible. Ajoutez une SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM inutilisable."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Votre SIM a été désactivée définitivement.\n Contactez votre opérateur de téléphonie mobile pour en obtenir une autre."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM verrouillée."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM verrouillée par clé PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Déblocage de la SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-gl/strings.xml b/packages/SystemUI/res-keyguard/values-gl/strings.xml
index 68f22cb..4837de2 100644
--- a/packages/SystemUI/res-keyguard/values-gl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gl/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando lentamente"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carga optimizada para protexer a batería"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problema co accesorio de carga"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Preme Menú para desbloquear."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Bloqueada pola rede"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Non hai ningunha SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Engade unha SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"A SIM falta ou non se pode ler. Engade unha."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"A SIM non se pode usar."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"A SIM desactivouse permanentemente.\n Ponte en contacto co teu fornecedor de servizos sen fíos para conseguir outra."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"A SIM está bloqueada."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"A SIM está bloqueada mediante PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Desbloqueando SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-gu/strings.xml b/packages/SystemUI/res-keyguard/values-gu/strings.xml
index 99c9883..7f8c6d8 100644
--- a/packages/SystemUI/res-keyguard/values-gu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gu/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ધીમેથી ચાર્જિંગ"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • બૅટરીની સુરક્ષા કરવા માટે, ચાર્જિંગ ઑપ્ટિમાઇઝ કરવામાં આવ્યું છે"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ચાર્જિંગ ઍક્સેસરીમાં સમસ્યા"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"અનલૉક કરવા માટે મેનૂ દબાવો."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"નેટવર્ક લૉક થયું"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"કોઈ સિમ કાર્ડ નથી"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"સિમ કાર્ડ ઉમેરો."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"સિમ કાર્ડ ખૂટે છે અથવા વાંચી શકાય એવું નથી. સિમ કાર્ડ ઉમેરો."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"ઉપયોગમાં ન લઈ શકાતું સિમ કાર્ડ."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"તમારું સિમ કાર્ડ કાયમ માટે નિષ્ક્રિય કરવામાં આવ્યું છે.\n બીજા સિમ કાર્ડ માટે તમારા વાયરલેસ સેવા પ્રદાતાનો સંપર્ક કરો."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"સિમ કાર્ડ લૉક કરેલું છે."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"સિમ કાર્ડ PUK-લૉક કરેલું છે."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"સિમ કાર્ડ અનલૉક કરી રહ્યાં છીએ…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hi/strings.xml b/packages/SystemUI/res-keyguard/values-hi/strings.xml
index 9d32f04..18d63ab 100644
--- a/packages/SystemUI/res-keyguard/values-hi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hi/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • धीरे चार्ज हो रहा है"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • बैटरी को नुकसान से बचाने के लिए, चार्जिंग को ऑप्टिमाइज़ किया गया"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्जर ऐक्सेसरी से जुड़ी समस्या"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"लॉक खोलने के लिए मेन्यू दबाएं."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"नेटवर्क लॉक किया हुआ है"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"कोई सिम नहीं है"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"कोई सिम जोड़ें."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"सिम मौजूद नहीं है या उसे ऐक्सेस नहीं किया जा सकता. कोई सिम जोड़ें."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"सिम को हमेशा के लिए बंद कर दिया गया है."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"आपका सिम हमेशा के लिए बंद कर दिया गया है.\n दूसरा सिम पाने के लिए, वायरलेस सेवा देने वाली कंपनी से संपर्क करें."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"सिम लॉक है."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"सिम में PUK लॉक लगा है."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"सिम अनलॉक हो रहा है…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hr/strings.xml b/packages/SystemUI/res-keyguard/values-hr/strings.xml
index b4224bf..0206faf 100644
--- a/packages/SystemUI/res-keyguard/values-hr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hr/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • sporo punjenje"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Punjenje se optimizira radi zaštite baterije"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problem s priborom za punjenje"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pritisnite Izbornik da biste otključali."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Mreža je zaključana"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Nema SIM-a"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Dodajte SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM nedostaje ili nije čitljiv. Dodajte SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM je neupotrebljiv."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Vaš je SIM trajno deaktiviran.\n Obratite se svom davatelju bežičnih usluga da biste dobili drugi SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM je zaključan."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM je zaključan PUK-om."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Otključavanje SIM-a…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hu/strings.xml b/packages/SystemUI/res-keyguard/values-hu/strings.xml
index bc712c7..8575e10 100644
--- a/packages/SystemUI/res-keyguard/values-hu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hu/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lassú töltés"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Optimalizált töltés az akkumulátor védelme érdekében"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Probléma van a töltőtartozékkal"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"A feloldáshoz nyomja meg a Menü gombot."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Hálózat zárolva"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Nincs SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Adjon hozzá egy SIM-et."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"A SIM hiányzik vagy nem olvasható. Adjon hozzá egy SIM-et."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Nem használható SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM véglegesen deaktiválva.\n Forduljon a vezeték nélküli szolgáltatójához másik SIM beszerzése érdekében."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"Zárolt SIM."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"A SIM le van zárva PUK-kóddal."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM zárolásának feloldása…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hy/strings.xml b/packages/SystemUI/res-keyguard/values-hy/strings.xml
index 4d7bbbe..a7c3aba 100644
--- a/packages/SystemUI/res-keyguard/values-hy/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hy/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Դանդաղ լիցքավորում"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Մարտկոցը պաշտպանելու համար լիցքավորումն օպտիմալացվել է"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Լիցքավորիչի հետ կապված խնդիր"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Ապակողպելու համար սեղմեք Ընտրացանկը:"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Ցանցը կողպված է"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM քարտ չկա"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Ավելացրեք SIM քարտ։"</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM քարտը բացակայում է կամ ընթեռնելի չէ։ Ավելացրեք SIM քարտ։"</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Անվավեր SIM քարտ։"</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Ձեր SIM քարտն ընդմիշտ ապակտիվացվել է։\n Նոր SIM քարտ ձեռք բերելու համար կապվեք ձեր բջջային օպերատորի հետ։"</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM քարտը կողպված է։"</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM քարտը կողպված է PUK կոդով։"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM քարտն ապակողպվում է…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-in/strings.xml b/packages/SystemUI/res-keyguard/values-in/strings.xml
index aa766e9..f9a840f 100644
--- a/packages/SystemUI/res-keyguard/values-in/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-in/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengisi daya dengan lambat"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Pengisian daya dioptimalkan untuk melindungi baterai"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Masalah dengan aksesori pengisian daya"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Tekan Menu untuk membuka kunci."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Jaringan terkunci"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Tidak ada SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Tambahkan SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM tidak ada atau tidak dapat dibaca. Tambahkan SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM tidak dapat digunakan."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM Anda telah dinonaktifkan secara permanen.\n Hubungi penyedia layanan nirkabel Anda untuk mendapatkan SIM lain."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM dikunci."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM dikunci PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Membuka kunci SIM …"</string>
diff --git a/packages/SystemUI/res-keyguard/values-is/strings.xml b/packages/SystemUI/res-keyguard/values-is/strings.xml
index 99f1779..b7147c2 100644
--- a/packages/SystemUI/res-keyguard/values-is/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-is/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hæg hleðsla"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hleðsla fínstillt til að vernda rafhlöðuna"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Vandamál með hleðslubúnað"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Ýttu á valmyndarhnappinn til að taka úr lás."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Net læst"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Ekkert SIM-kort"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Bæta við SIM-korti."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM-kort vantar eða er ekki læsilegt. Bæta við SIM-korti."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Ónothæft SIM-kort."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM-kortið þitt var gert varanlega óvirkt.\n Hafðu samband við símafyrirtækið þitt til að fá nýtt SIM-kort."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM-kort er læst."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM-kort er læst með PUK-númeri."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Opnar SIM-kort…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-it/strings.xml b/packages/SystemUI/res-keyguard/values-it/strings.xml
index cc0a164..9e1b187 100644
--- a/packages/SystemUI/res-keyguard/values-it/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-it/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ricarica lenta"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ricarica ottimizzata per proteggere la batteria"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problema relativo all\'accessorio di ricarica"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Premi Menu per sbloccare."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Rete bloccata"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Nessuna SIM presente"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Aggiungi una SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM mancante o non leggibile. Aggiungi una SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM inutilizzabile."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"La SIM è stata disattivata definitivamente.\n Contatta il tuo fornitore di servizi wireless per richiedere un\'altra SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"La SIM è bloccata."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"La SIM è bloccata tramite PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Sblocco della SIM in corso…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-iw/strings.xml b/packages/SystemUI/res-keyguard/values-iw/strings.xml
index 00c717c..16316ce 100644
--- a/packages/SystemUI/res-keyguard/values-iw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-iw/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • בטעינה איטית"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • הטעינה עברה אופטימיזציה כדי להגן על הסוללה"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • יש בעיה עם אביזר הטעינה"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"יש ללחוץ על \'תפריט\' כדי לבטל את הנעילה."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"הרשת נעולה"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"‏אין כרטיס SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"‏הוספת כרטיס SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"‏כרטיס ה-SIM חסר או שלא ניתן לקרוא אותו. הוספת כרטיס SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"‏לא ניתן להשתמש בכרטיס ה-SIM הזה."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"‏כרטיס ה-SIM שלך הושבת באופן סופי.\n עליך לפנות לספק השירות האלחוטי שלך לקבלת כרטיס SIM אחר."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"‏כרטיס ה-SIM נעול."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"‏כרטיס ה-SIM נעול באמצעות PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"‏מתבצע ביטול נעילה של כרטיס ה-SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ja/strings.xml b/packages/SystemUI/res-keyguard/values-ja/strings.xml
index 1d59a63..6e8f423 100644
--- a/packages/SystemUI/res-keyguard/values-ja/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ja/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 低速充電中"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • バッテリーを保護するために、充電が最適化されています"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 充電用アクセサリに関する問題"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"メニューからロックを解除できます。"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"ネットワークがロックされました"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM がありません"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"SIM を追加してください。"</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM が見つからないか読み取れません。SIM を追加してください。"</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM が使用できません。"</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM が完全に無効になっています。\n ワイヤレス サービス プロバイダにお問い合わせのうえ、新しい SIM を入手してください。"</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM がロックされています。"</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM が PUK でロックされました。"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM ロックを解除しています…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ka/strings.xml b/packages/SystemUI/res-keyguard/values-ka/strings.xml
index 5bd6b2e..a31243d 100644
--- a/packages/SystemUI/res-keyguard/values-ka/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ka/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ნელა იტენება"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • დატენვა ოპტიმიზირებულია ბატარეის დასაცავად"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • დამტენი დამხმარე მოწყობილობის პრობლემა"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"განსაბლოკად დააჭირეთ მენიუს."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"ქსელი ჩაკეტილია"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM არ არის"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"SIM-ის დამატება."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM აკლია ან არ იკითხება. SIM-ის დამატება."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"გამოუყენებელი SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"თქვენი SIM სამუდამოდ გამორთულია.\n დაუკავშირდით თქვენს უკაბელო სერვისის პროვაიდერს სხვა SIM ბარათისთვის."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM-ბარათი ჩაკეტილია."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM დაბლოკილია PUK-ით."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM-ის განბლოკვა…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml
index 83d270d..6a77783 100644
--- a/packages/SystemUI/res-keyguard/values-kk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Баяу зарядталуда"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Батареяны қорғау үшін зарядтау оңтайландырылды"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарядтау құрылғысына қатысты мәселе туындады."</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Ашу үшін \"Мәзір\" пернесін басыңыз."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Желі құлыптаулы"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM картасы жоқ."</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"SIM картасын қосыңыз."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM картасы жоқ немесе оқылмай тұр. SIM картасын қосыңыз."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM картасын пайдалану мүмкін емес."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM картаңыз біржола өшірілді.\n Сымсыз байланыс провайдеріне хабарласып, басқа SIM картасын алыңыз."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM картасы құлыпталған."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM картасы PUK кодымен құлыпталды."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM картасының құлпы ашылып жатыр…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-km/strings.xml b/packages/SystemUI/res-keyguard/values-km/strings.xml
index 5306cb1..cda9520 100644
--- a/packages/SystemUI/res-keyguard/values-km/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-km/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • កំពុង​សាកថ្មយឺត"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • បានបង្កើនប្រសិទ្ធភាពនៃការសាក ដើម្បីការពារថ្ម"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • បញ្ហាពាក់ព័ន្ធនឹងគ្រឿងសាកថ្ម"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ចុចម៉ឺនុយ ​ដើម្បី​ដោះ​សោ។"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"បណ្ដាញ​ជាប់​សោ"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"គ្មានស៊ីមទេ"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"បញ្ចូល​ស៊ីម។"</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"បាត់ស៊ីម ឬមិនអាចអានស៊ីមបាន។ បញ្ចូល​ស៊ីម។"</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"ស៊ីមមិនអាចប្រើបាន។"</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"ស៊ីមរបស់អ្នកត្រូវបានបិទដំណើរការជាអចិន្ត្រៃយ៍។\n ទាក់ទងទៅក្រុមហ៊ុនផ្ដល់សេវាឥតខ្សែរបស់អ្នក ដើម្បីទទួលបានស៊ីមមួយទៀត។"</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"ស៊ីម​ត្រូវបាន​ចាក់សោ។"</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"ស៊ីមត្រូវបានចាក់សោដោយ PUK។"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"កំពុងដោះសោស៊ីម…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-kn/strings.xml b/packages/SystemUI/res-keyguard/values-kn/strings.xml
index d609a23..e24005a 100644
--- a/packages/SystemUI/res-keyguard/values-kn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kn/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ನಿಧಾನವಾಗಿ ಚಾರ್ಜ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ಬ್ಯಾಟರಿಯನ್ನು ರಕ್ಷಿಸಲು ಚಾರ್ಜಿಂಗ್ ಅನ್ನು ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ಚಾರ್ಜಿಂಗ್ ಪರಿಕರ ಕುರಿತು ಸಮಸ್ಯೆ ಇದೆ"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಮೆನು ಒತ್ತಿರಿ."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"ನೆಟ್‌ವರ್ಕ್ ಲಾಕ್ ಆಗಿದೆ"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM ಇಲ್ಲ"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"SIM ಅನ್ನು ಸೇರಿಸಿ."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM ಕಾಣೆಯಾಗಿದೆ ಅಥವಾ ರೀಡ್ ಆಗುತ್ತಿಲ್ಲ. SIM ಅನ್ನು ಸೇರಿಸಿ."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM ನಿಷ್ಪ್ರಯೋಜಕವಾಗಿದೆ."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"ನಿಮ್ಮ SIM ಅನ್ನು ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ.\n ಬೇರೊಂದು SIM ಗಾಗಿ ನಿಮ್ಮ ವೈರ್‌ಲೆಸ್ ಸೇವಾ ಪೂರೈಕೆದಾರರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM ಲಾಕ್ ಆಗಿದೆ."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM PUK ಲಾಕ್ ಆಗಿದೆ."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM ಅನ್ನು ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ko/strings.xml b/packages/SystemUI/res-keyguard/values-ko/strings.xml
index 0e09fad..7378cc78 100644
--- a/packages/SystemUI/res-keyguard/values-ko/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ko/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 저속 충전 중"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 배터리 보호를 위해 충전 최적화됨"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 충전 액세서리 문제"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"잠금 해제하려면 메뉴를 누르세요."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"네트워크 잠김"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM 없음"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"SIM을 추가하세요."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM이 없거나 SIM을 읽을 수 없습니다. SIM을 추가하세요."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM을 사용할 수 없습니다."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM이 영구적으로 비활성화되었습니다.\n 다른 SIM을 사용하려면 무선 서비스 제공업체에 문의하시기 바랍니다."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM이 잠김 상태입니다."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM이 PUK 잠김 상태입니다."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM 잠금 해제 중…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml
index 1e03c03..88f0b97 100644
--- a/packages/SystemUI/res-keyguard/values-ky/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Жай кубатталууда"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Батареяны коргоо үчүн кубаттоо процесси оптималдаштырылды"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Кубаттоочу шайманда көйгөй бар"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Кулпуну ачуу үчүн Менюну басыңыз."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Тармак кулпуланган"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM карта жок"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"SIM карта кошуңуз."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM карта жок же окулбайт. SIM карта кошуңуз."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Жараксыз SIM карта."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM картаңыз биротоло өчүрүлдү.\n Башка SIM карта алуу үчүн зымсыз кызмат көрсөтүүчүгө кайрылыңыз."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM карта кулпуланган."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM карта PUK менен кулпуланган."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM картанын кулпусу ачылууда…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lo/strings.xml b/packages/SystemUI/res-keyguard/values-lo/strings.xml
index 0059d7f..00a382a 100644
--- a/packages/SystemUI/res-keyguard/values-lo/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lo/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ກຳລັງສາກແບບຊ້າ"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ການສາກຖືກປັບໃຫ້ເໝາະສົມເພື່ອປົກປ້ອງແບັດເຕີຣີ"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ບັນຫາກັບອຸປະກອນເສີມໃນການສາກ"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ກົດ \"ເມນູ\" ເພື່ອປົດລັອກ."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"ເຄືອຂ່າຍຖືກລັອກ"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"ບໍ່ມີຊິມ"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"ເພີ່ມຊິມ."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"ບໍ່ມີຊິມ ຫຼື ອ່ານຊິມບໍ່ໄດ້. ເພີ່ມຊິມ."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"ຊິມໃຊ້ບໍ່ໄດ້."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"ຊິມຂອງທ່ານຖືກປິດໃຊ້ຢ່າງຖາວອນແລ້ວ.\n ຕິດຕໍ່ຜູ້ໃຫ້ບໍລິການໂທລະສັບໄຮ້ສາຍຂອງທ່ານເພື່ອຂໍຊິມໃໝ່."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"ຊິມຖືກລັອກຢູ່."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"ຊິມຖືກລັອກດ້ວຍ PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"ກຳລັງປົດລັອກຊິມ…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lt/strings.xml b/packages/SystemUI/res-keyguard/values-lt/strings.xml
index 01e2f88..31c4107 100644
--- a/packages/SystemUI/res-keyguard/values-lt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lt/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lėtai įkraunama"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Įkrovimas optimizuotas siekiant apsaugoti akumuliatorių"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Su įkrovimo priedu susijusi problema"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Paspauskite meniu, jei norite atrakinti."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Tinklas užrakintas"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Nėra SIM kortelės"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Įdėkite SIM kortelę."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"Trūksta SIM kortelės arba ji neskaitoma. Įdėkite SIM kortelę."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Nenaudojama SIM kortelė."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Jūsų SIM kortelė visam laikui išjungta.\n Susisiekite su belaidžio ryšio paslaugos teikėju, kad gautumėte naują SIM kortelę."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM kortelė užrakinta."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM kortelė užrakinta PUK kodu."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Atrakinama SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lv/strings.xml b/packages/SystemUI/res-keyguard/values-lv/strings.xml
index 2133694..ecf2233 100644
--- a/packages/SystemUI/res-keyguard/values-lv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lv/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Notiek lēnā uzlāde"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Uzlāde optimizēta, lai saudzētu akumulatoru"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problēma ar uzlādes ierīci"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Lai atbloķētu, nospiediet izvēlnes ikonu."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Tīkls ir bloķēts."</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Nav SIM kartes"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Pievienojiet SIM karti."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"Nav SIM kartes, vai arī to nevar nolasīt. Pievienojiet SIM karti."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM karte nav izmantojama."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Jūsu SIM karte ir neatgriezeniski deaktivizēta.\n Sazinieties ar savu bezvadu pakalpojumu sniedzēju, lai iegūtu citu SIM karti."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM karte ir bloķēta."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM karte ir bloķēta ar PUK kodu."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Notiek SIM kartes atbloķēšana…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mk/strings.xml b/packages/SystemUI/res-keyguard/values-mk/strings.xml
index 2771c7f..3f089b9 100644
--- a/packages/SystemUI/res-keyguard/values-mk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mk/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Бавно полнење"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Полнењето е оптимизирано за да се заштити батеријата"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Проблем со додатокот за полнење"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Притиснете „Мени“ за отклучување."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Мрежата е заклучена"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Нема SIM-картичка"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Додајте SIM-картичка."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"Нема SIM-картичка или не може да се прочита. Додајте SIM-картичка."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM-картичката е неупотреблива."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Вашата SIM-картичка е трајно деактивирана.\n Контактирајте со давателот на услуги за безжична мрежа за друга SIM-картичка."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM-картичката е заклучена."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM-картичката е заклучена со PUK-код."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Се отклучува SIM-картичката…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ml/strings.xml b/packages/SystemUI/res-keyguard/values-ml/strings.xml
index 02ee66f..be1ea89 100644
--- a/packages/SystemUI/res-keyguard/values-ml/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ml/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • പതുക്കെ ചാർജ് ചെയ്യുന്നു"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ബാറ്ററി പരിരക്ഷിക്കാൻ ചാർജിംഗ് ഒപ്റ്റിമൈസ് ചെയ്തു"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ചാർജിംഗ് ആക്സസറിയുമായി ബന്ധപ്പെട്ട പ്രശ്നം"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"അൺലോക്കുചെയ്യാൻ മെനു അമർത്തുക."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"നെറ്റ്‌വർക്ക് ലോക്കുചെയ്‌തു"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"സിം ഇല്ല"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"സിം ചേർക്കുക."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"സിം കാണുന്നില്ല അല്ലെങ്കിൽ റീഡ് ചെയ്യാനായില്ല. സിം ചേർക്കുക."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"ഉപയോഗശൂന്യമായ സിം."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"നിങ്ങളുടെ സിം ശാശ്വതമായി നിഷ്ക്രിയമാക്കി.\n മറ്റൊരു സിമ്മിന് നിങ്ങളുടെ വയർലെസ് സേവന ദാതാവിനെ ബന്ധപ്പെടുക."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"സിം ലോക്ക് ചെയ്തു."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"സിം PUK ലോക്ക് ചെയ്തു."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"സിം അൺലോക്ക് ചെയ്യുന്നു…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mn/strings.xml b/packages/SystemUI/res-keyguard/values-mn/strings.xml
index 2b9f81e..54fdecd 100644
--- a/packages/SystemUI/res-keyguard/values-mn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mn/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Удаан цэнэглэж байна"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Батарейг хамгаалахын тулд цэнэглэх явцыг оновчилсон"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Цэнэглэх хэрэгсэлд асуудал гарлаа"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Түгжээг тайлах бол цэсийг дарна уу."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Сүлжээ түгжигдсэн"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM байхгүй"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"SIM нэмнэ үү."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM дутуу эсвэл үүнийг унших боломжгүй байна. SIM нэмнэ үү."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Ашиглах боломжгүй SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Таны SIM-г бүрмөсөн идэвхгүй болгосон байна.\n Өөр SIM авах бол утасгүй үйлчилгээ үзүүлэгчтэйгээ холбогдоно уу."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM-г түгжсэн байна."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM-г PUK-р түгжсэн байна."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM-н түгжээг тайлж байна…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mr/strings.xml b/packages/SystemUI/res-keyguard/values-mr/strings.xml
index 7aa7bdd..eff4c7a 100644
--- a/packages/SystemUI/res-keyguard/values-mr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mr/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • सावकाश चार्ज होत आहे"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • बॅटरीचे संरक्षण करण्यासाठी चार्जिंग ऑप्टिमाइझ केले आहे"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्जिंगच्या ॲक्सेसरीसंबंधित समस्या"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"अनलॉक करण्यासाठी मेनू प्रेस करा."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"नेटवर्क लॉक केले"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"सिम नाही"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"सिम जोडा."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"सिम गहाळ झाले आहे किंवा ते रीड करू शकत नाही. सिम जोडा."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"वापरण्यायोग्य नसलेले सिम."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"तुमचे सिम कायमचे डीॲक्टिव्हेट केले गेले आहे.\n दुसऱ्या सिमसाठी तुमच्या वायरलेस सेवा पुरवठादाराशी संपर्क साधा."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"सिम लॉक केलेले आहे."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"सिम PUK लॉक केलेले आहे."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"सिम अनलॉक करत आहे…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ms/strings.xml b/packages/SystemUI/res-keyguard/values-ms/strings.xml
index bdfa4a7..d9eb4ca 100644
--- a/packages/SystemUI/res-keyguard/values-ms/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ms/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengecas dengan perlahan"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Pengecasan dioptimumkan untuk melindungi bateri"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Isu berkaitan aksesori pengecasan"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Tekan Menu untuk membuka kunci."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Rangkaian dikunci"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Tiada SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Tambah SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM tiada atau tidak boleh dibaca. Tambah SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM tidak boleh digunakan."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM anda telah dinyahaktifkan secara kekal.\n Hubungi penyedia perkhidmatan wayarles anda untuk mendapatkan SIM lain."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM dikunci."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM dikunci PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Membuka kunci SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-my/strings.xml b/packages/SystemUI/res-keyguard/values-my/strings.xml
index 576250b..afbce26 100644
--- a/packages/SystemUI/res-keyguard/values-my/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-my/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • နှေးကွေးစွာ အားသွင်းနေသည်"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ဘက်ထရီကာကွယ်ရန် အားသွင်းခြင်းကို အကောင်းဆုံးပြင်ဆင်ထားသည်"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • အားသွင်းပစ္စည်းတွင် ပြဿနာရှိသည်"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"မီနူးကို နှိပ်၍ လော့ခ်ဖွင့်ပါ။"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"ကွန်ရက်ကို လော့ခ်ချထားသည်"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"ဆင်းမ်ကတ် မရှိပါ"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"ဆင်းမ်ကတ်ထည့်ပါ။"</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"ဆင်းမ်မရှိပါ (သို့) သုံး၍မရပါ။ ဆင်းမ်ကတ်ထည့်ပါ။"</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"ဆင်းမ်ကတ်ကို သုံး၍မရပါ။"</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"သင်၏ဆင်းမ်ကတ်ကို အပြီးပိတ်လိုက်သည်။\n ဆင်းမ်ကတ်နောက်တစ်ခု ရယူရန် သင်၏ ကြိုးမဲ့ဝန်ဆောင်မှုပေးသူထံ ဆက်သွယ်ပါ။"</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"ဆင်းမ်ကတ်ကို လော့ခ်ချထားသည်။"</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"ဆင်းမ်ကတ်၏ ပင်နံပါတ်ပြန်ဖွင့်သည့် ကုဒ်ကို လော့ခ်ချထားသည်။"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"ဆင်းမ်ကတ် ဖွင့်နေသည်…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-nb/strings.xml b/packages/SystemUI/res-keyguard/values-nb/strings.xml
index 455d086..3098e87 100644
--- a/packages/SystemUI/res-keyguard/values-nb/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nb/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lader sakte"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ladingen er optimalisert for å beskytte batteriet"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problem med ladetilbehøret"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Trykk på menyknappen for å låse opp."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Nettverket er låst"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Ingen SIM-kort"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Legg til et SIM-kort."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM-kortet mangler eller kan ikke leses. Legg til et SIM-kort."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM-kortet kan ikke brukes."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM-kortet er deaktivert permanent.\n Kontakt leverandøren av trådløstjenesten for å få et nytt SIM-kort."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM-kortet er låst."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM-kortet er låst med PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Låser opp SIM-kortet …"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml
index f0094a3..45b8819 100644
--- a/packages/SystemUI/res-keyguard/values-ne/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • मन्द गतिमा चार्ज गरिँदै"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ब्याट्री जोगाउन चार्ज गर्ने प्रक्रिया अप्टिमाइज गरिएको छ"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्ज गर्ने एक्सेसरीमा कुनै समस्या आयो"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"अनलक गर्न मेनु थिच्नुहोस्।"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"नेटवर्क लक भएको छ"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM कार्ड हालिएको छैन"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"SIM कार्ड हाल्नुहोस्।"</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM कार्ड हालिएको छैन वा रिड गर्न मिल्दैन। SIM कार्ड हाल्नुहोस्।"</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"यो SIM कार्ड प्रयोग गर्न मिल्दैन।"</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"तपाईंको SIM कार्ड सदाका लागि डिएक्टिभेट गरिएको छ।\n आफ्नो वायरलेस सेवा प्रदायकलाई सम्पर्क गरी अर्को SIM कार्ड प्राप्त गर्नुहोस्।"</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM कार्ड लक गरिएको छ।"</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM कार्ड PUK प्रयोग गरी लक गरिएको छ।"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM कार्ड अनलक गरिँदै छ…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml
index 1ba4a81..af24d40 100644
--- a/packages/SystemUI/res-keyguard/values-nl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Langzaam opladen"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Opladen geoptimaliseerd om de batterij te beschermen"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Probleem met oplaadaccessoire"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Druk op Menu om te ontgrendelen."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Netwerk vergrendeld"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Geen simkaart"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Voeg een simkaart toe."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"De simkaart ontbreekt of kan niet worden gelezen. Voeg een simkaart toe."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Onbruikbare simkaart."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Je simkaart is permanent gedeactiveerd.\n Neem contact op met je mobiele serviceprovider voor een nieuwe simkaart."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"Simkaart is vergrendeld."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"Simkaart is vergrendeld met pukcode."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Simkaart ontgrendelen…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-or/strings.xml b/packages/SystemUI/res-keyguard/values-or/strings.xml
index b31c9c0..8cae987 100644
--- a/packages/SystemUI/res-keyguard/values-or/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-or/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ଧୀରେ ଚାର୍ଜ ହେଉଛି"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ବେଟେରୀକୁ ସୁରକ୍ଷିତ ରଖିବା ପାଇଁ ଚାର୍ଜିଂକୁ ଅପ୍ଟିମାଇଜ କରାଯାଇଛି"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ଚାର୍ଜିଂ ଆକସେସୋରୀ ସହ ସମସ୍ୟା"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ଅନଲକ୍‌ କରିବା ପାଇଁ ମେନୁକୁ ଦବାନ୍ତୁ।"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"ନେଟୱର୍କକୁ ଲକ୍‌ କରାଯାଇଛି"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"କୌଣସି SIM ନାହିଁ"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"ଏକ SIM ଯୋଗ କରନ୍ତୁ।"</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM ଉପଲବ୍ଧ ନାହିଁ କିମ୍ବା ପଢ଼ିପାରିବା ଯୋଗ୍ୟ ନୁହେଁ। ଏକ SIM ଯୋଗ କରନ୍ତୁ।"</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"ବ୍ୟବହାର ଅଯୋଗ୍ୟ ଥିବା SIM।"</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"ଆପଣଙ୍କ SIMକୁ ସ୍ଥାୟୀ ଭାବରେ ନିଷ୍କ୍ରିୟ କରାଯାଇଛି।\n ଅନ୍ୟ ଏକ SIM ପାଇଁ ଆପଣଙ୍କ ୱେୟାରଲେସ ସେବା ପ୍ରଦାନକାରୀଙ୍କ ସହ କଣ୍ଟାକ୍ଟ କରନ୍ତୁ।"</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIMକୁ ଲକ କରାଯାଇଛି।"</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIMକୁ PUK-ଲକ କରାଯାଇଛି।"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIMକୁ ଅନଲକ କରାଯାଉଛି…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pa/strings.xml b/packages/SystemUI/res-keyguard/values-pa/strings.xml
index 209b63f..18959c8 100644
--- a/packages/SystemUI/res-keyguard/values-pa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pa/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ਹੌਲੀ-ਹੌਲੀ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ਬੈਟਰੀ ਦੀ ਸੁਰੱਖਿਆ ਲਈ ਚਾਰਜਿੰਗ ਨੂੰ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ਚਾਰਜ ਕਰਨ ਵਾਲੀ ਐਕਸੈਸਰੀ ਸੰਬੰਧੀ ਸਮੱਸਿਆ"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ਅਣਲਾਕ ਕਰਨ ਲਈ \"ਮੀਨੂ\" ਦਬਾਓ।"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"ਨੈੱਟਵਰਕ  ਲਾਕ  ਕੀਤਾ ਗਿਆ"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"ਕੋਈ ਸਿਮ ਨਹੀਂ ਹੈ"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"ਸਿਮ ਸ਼ਾਮਲ ਕਰੋ।"</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"ਸਿਮ ਮੌਜੂਦ ਨਹੀਂ ਹੈ ਜਾਂ ਪੜ੍ਹਨਯੋਗ ਨਹੀਂ ਹੈ। ਸਿਮ ਸ਼ਾਮਲ ਕਰੋ।"</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"ਬੇਕਾਰ ਸਿਮ।"</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"ਤੁਹਾਡੇ ਸਿਮ ਨੂੰ ਪੱਕੇ ਤੌਰ \'ਤੇ ਅਕਿਰਿਆਸ਼ੀਲ ਕੀਤਾ ਗਿਆ ਹੈ।\n ਦੂਜੇ ਸਿਮ ਲਈ ਆਪਣੇ ਵਾਇਰਲੈੱਸ ਸੇਵਾ ਪ੍ਰਦਾਨਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"ਸਿਮ ਲਾਕ ਹੈ।"</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"ਸਿਮ PUK-ਲਾਕ ਹੈ।"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"ਸਿਮ ਨੂੰ ਅਣਲਾਕ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pl/strings.xml b/packages/SystemUI/res-keyguard/values-pl/strings.xml
index 7ec988e..bd00ba9 100644
--- a/packages/SystemUI/res-keyguard/values-pl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pl/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Wolne ładowanie"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ładowanie zoptymalizowane w celu ochrony baterii"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problem z akcesoriami do ładowania"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Naciśnij Menu, aby odblokować."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Sieć zablokowana"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Brak karty SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Dodaj kartę SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"Brak karty SIM lub nie można jej odczytać. Dodaj kartę SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Nie można użyć karty SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Karta SIM została trwale wyłączona.\n Skontaktuj się z dostawcą usług bezprzewodowych, aby uzyskać inną kartę SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"Karta SIM jest zablokowana."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"Karta SIM została zablokowana kodem PUK"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Odblokowuję kartę SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
index 78a8091..54e270f 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando lentamente"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregamento otimizado para proteger a bateria"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problema com o acessório de carregamento"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pressione Menu para desbloquear."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Rede bloqueada"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Sem chip"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Adicione um chip."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"O chip não foi inserido ou não pode ser lido. Adicione um chip."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Chip inutilizável."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Seu chip foi desativado permanentemente.\n Entre em contato com seu provedor de serviços sem fio para receber outro chip."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"O chip está bloqueado."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"O chip está bloqueado pela PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Desbloqueando chip…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
index 5549b36..2e37bde 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • A carregar lentamente…"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregamento otimizado para proteger a bateria"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problema com o acessório de carregamento"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Prima Menu para desbloquear."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Rede bloqueada"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Sem SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Adicione um SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"O SIM está em falta ou não é legível. Adicione um SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM inutilizável."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"O SIM foi desativado permanentemente.\n Contacte o seu fornecedor de serviços de rede sem fios para obter outro SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"O SIM está bloqueado."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"O SIM está bloqueado com o PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"A desbloquear SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt/strings.xml b/packages/SystemUI/res-keyguard/values-pt/strings.xml
index 78a8091..54e270f 100644
--- a/packages/SystemUI/res-keyguard/values-pt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando lentamente"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregamento otimizado para proteger a bateria"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problema com o acessório de carregamento"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pressione Menu para desbloquear."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Rede bloqueada"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Sem chip"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Adicione um chip."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"O chip não foi inserido ou não pode ser lido. Adicione um chip."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Chip inutilizável."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Seu chip foi desativado permanentemente.\n Entre em contato com seu provedor de serviços sem fio para receber outro chip."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"O chip está bloqueado."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"O chip está bloqueado pela PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Desbloqueando chip…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ro/strings.xml b/packages/SystemUI/res-keyguard/values-ro/strings.xml
index df28b8d..ead09209 100644
--- a/packages/SystemUI/res-keyguard/values-ro/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ro/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Se încarcă lent"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Încărcarea este optimizată pentru a proteja bateria"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problemă legată de accesoriul de încărcare"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Apasă pe Meniu pentru a debloca."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Rețea blocată"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Niciun card SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Adaugă un card SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"Cardul SIM lipsește sau nu poate fi citit. Adaugă un card SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Cardul SIM nu se poate folosi."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Cardul tău SIM a fost dezactivat definitiv.\n Contactează furnizorul de servicii wireless pentru a obține un alt card SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"Cardul SIM este blocat."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"Cardul SIM este blocat prin cod PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Se deblochează cardul SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ru/strings.xml b/packages/SystemUI/res-keyguard/values-ru/strings.xml
index 62249a1..595fba5 100644
--- a/packages/SystemUI/res-keyguard/values-ru/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ru/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"Идет медленная зарядка (<xliff:g id="PERCENTAGE">%s</xliff:g>)"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарядка оптимизирована для защиты батареи"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Проблема с зарядным устройством"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Для разблокировки нажмите \"Меню\"."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Сеть заблокирована"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM-карта отсутствует"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Добавьте SIM-карту."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM-карта отсутствует или не распознана. Добавьте SIM-карту."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM-карту невозможно использовать."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM-карта была окончательно деактивирована.\n Чтобы получить новую, обратитесь к своему оператору мобильной связи."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM-карта заблокирована."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM-карта заблокирована с помощью PUK-кода."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Разблокировка SIM-карты…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-si/strings.xml b/packages/SystemUI/res-keyguard/values-si/strings.xml
index 17ced75..b6a7422 100644
--- a/packages/SystemUI/res-keyguard/values-si/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-si/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • සෙමින් ආරෝපණය වෙමින්"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • බැටරිය ආරක්ෂා කිරීම සඳහා ආරෝපණය ප්‍රශස්ත කර ඇත"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ආරෝපණ උපාංගයේ ගැටලුව"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"අගුලු හැරීමට මෙනුව ඔබන්න."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"ජාලය අගුළු දමා ඇත"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM නැත"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"SIM එකක් එක් කරන්න."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM අස්ථානගතයි හෝ කියවිය නොහැක. SIM එකක් එක් කරන්න."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"භාවිත කළ නොහැකි SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"ඔබේ SIM ස්ථිරවම අක්‍රිය කර ඇත.\n වෙනත් SIM පතක් සඳහා ඔබේ රැහැන් රහිත සේවා සපයන්නා අමතන්න."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM අගුළු දමා ඇත."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM PUK-අගුළු දමා ඇත."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM අගුළු අරිමින්…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sk/strings.xml b/packages/SystemUI/res-keyguard/values-sk/strings.xml
index ef08a6c..5e34a94 100644
--- a/packages/SystemUI/res-keyguard/values-sk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sk/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nabíja sa pomaly"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nabíjanie je optimalizované, aby sa chránila batéria"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problém s nabíjacím príslušenstvom"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Odomknete stlačením tlačidla ponuky."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Sieť je zablokovaná"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Žiadna SIM karta"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Pridajte SIM kartu."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM karta chýba alebo sa nedá čítať. Pridajte SIM kartu."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Nepoužiteľná SIM karta."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Vaša SIM karta bola natrvalo deaktivovaná.\n Požiadajte svojho poskytovateľa bezdrôtových služieb o ďalšiu SIM kartu."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM karta je uzamknutá."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM karta je uzamknutá kódom PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM karta sa odomyká…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sl/strings.xml b/packages/SystemUI/res-keyguard/values-sl/strings.xml
index a42989c..3508f3b 100644
--- a/packages/SystemUI/res-keyguard/values-sl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sl/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • počasno polnjenje"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Polnjenje je optimizirano zaradi zaščite baterije"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • težava s pripomočkom za polnjenje"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Če želite odkleniti, pritisnite meni."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Omrežje je zaklenjeno"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Ni kartice SIM."</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Dodajte kartico SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"Ni kartice SIM ali je ni mogoče prebrati. Dodajte kartico SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Kartica SIM je neuporabna."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Vaša kartica SIM je bila trajno deaktivirana.\n Za drugo kartico SIM se obrnite na ponudnika brezžičnih storitev."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"Kartica SIM je zaklenjena."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"Kartica SIM je zaklenjena s kodo PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Odklepanje kartice SIM …"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sq/strings.xml b/packages/SystemUI/res-keyguard/values-sq/strings.xml
index ce53b7e..8d71b0f 100644
--- a/packages/SystemUI/res-keyguard/values-sq/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sq/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Po karikohet ngadalë"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Karikimi u optimizua për të mbrojtur baterinë"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problem me aksesorin e karikimit"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Shtyp \"Meny\" për të shkyçur."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Rrjeti është i kyçur"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Nuk ka kartë SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Shto një kartë SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"Karta SIM mungon ose është e palexueshme. Shto një kartë SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Kartë SIM e papërdorshme."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Karta jote SIM është çaktivizuar përgjithmonë.\n Kontakto me ofruesin e shërbimit wireless për një tjetër kartë SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"Karta SIM është e kyçur."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"Karta SIM është e kyçur me PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Karta SIM po shkyçet…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sr/strings.xml b/packages/SystemUI/res-keyguard/values-sr/strings.xml
index 437018d..4093952 100644
--- a/packages/SystemUI/res-keyguard/values-sr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sr/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Споро се пуни"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Пуњење је оптимизовано да би се заштитила батерија"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Проблем са додатним прибором за пуњење"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Притисните Мени да бисте откључали."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Мрежа је закључана"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Нема SIM-а"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Додајте SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM недостаје или не може да се прочита. Додајте SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Неупотребљив SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM је трајно деактивиран.\n Обратите се добављачу услуге бежичне телефоније да бисте добили други SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM је закључан."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM је закључан PUK-ом."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Откључава се SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sv/strings.xml b/packages/SystemUI/res-keyguard/values-sv/strings.xml
index b4b1996..5b01f39 100644
--- a/packages/SystemUI/res-keyguard/values-sv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sv/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laddas långsamt"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laddningen har optimerats för att skydda batteriet"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ett problem uppstod med att ladda tillbehöret"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Lås upp genom att trycka på Meny."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Nätverk låst"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Inget SIM-kort"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Lägg till ett SIM-kort."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM-kort saknas eller går inte att läsa. Lägg till ett SIM-kort."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM-kortet går inte att använda."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Ditt SIM-kort har inaktiverats permanent.\n Kontakta din operatör och be om ett nytt SIM-kort."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM-kortet är låst."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM-kortet har låsts med PUK-kod."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM-kortet låses upp …"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sw/strings.xml b/packages/SystemUI/res-keyguard/values-sw/strings.xml
index 8ca9046..72f1fc3 100644
--- a/packages/SystemUI/res-keyguard/values-sw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sw/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Inachaji pole pole"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hali ya kuchaji imeboreshwa ili kulinda betri"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Kifuasi cha kuchaji kina hitilafu"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Bonyeza Menyu ili kufungua."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Mtandao umefungwa"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Hakuna SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Weka SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM haipo au haiwezi kusomwa. Weka SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM haiwezi kutumika."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM kadi yako imefungwa kabisa.\n wasiliana na mtoa huduma wako wa pasi waya ili upate SIM nyingine."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM imefungwa."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM imefungwa kwa PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Inafungua SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml
index 7671194..20eb8ef 100644
--- a/packages/SystemUI/res-keyguard/values-ta/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • மெதுவாகச் சார்ஜாகிறது"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • பேட்டரியைப் பாதுகாக்க சார்ஜிங் மேம்படுத்தப்பட்டுள்ளது"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • சார்ஜரில் சிக்கல் உள்ளது"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"அன்லாக் செய்ய மெனுவை அழுத்தவும்."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"நெட்வொர்க் பூட்டப்பட்டது"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"சிம் இல்லை"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"சிம்மைச் சேருங்கள்."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"சிம் இல்லை அல்லது படிக்கக்கூடியதாக இல்லை. சிம்மைச் சேருங்கள்."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"பயன்படுத்த முடியாத சிம்."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"உங்கள் சிம் நிரந்தரமாக முடக்கப்பட்டுள்ளது.\n மற்றொரு சிம்மிற்கான உங்கள் வயர்லெஸ் சேவை வழங்குநரைத் தொடர்புகொள்ளுங்கள்."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"சிம் லாக் செய்யப்பட்டுள்ளது."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"சிம் PUK-லாக் செய்யப்பட்டுள்ளது."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"சிம்மை அன்லாக் செய்கிறது…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-te/strings.xml b/packages/SystemUI/res-keyguard/values-te/strings.xml
index 623b589..d496944 100644
--- a/packages/SystemUI/res-keyguard/values-te/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-te/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • నెమ్మదిగా ఛార్జ్ అవుతోంది"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • బ్యాటరీని రక్షించడానికి ఛార్జింగ్ ఆప్టిమైజ్ చేయబడింది"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ఛార్జింగ్ యాక్సెసరీతో సమస్య ఉంది"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"అన్‌లాక్ చేయడానికి మెనూను నొక్కండి."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"నెట్‌వర్క్ లాక్ చేయబడింది"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM లేదు"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"SIMను జోడించండి."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM మిస్ అయ్యింది లేదా ఆమోదయోగ్యం కాదు. SIMను జోడించండి."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"వినియోగించలేని SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"మీ SIM శాశ్వతంగా డీయాక్టివేట్ చేయబడింది.\n మరో SIMను పొందడం కోసం మీ వైర్‌లెస్ సర్వీస్ ప్రొవైడర్‌ను సంప్రదించండి."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM లాక్ చేయబడింది."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM PUK లాక్ చేయబడింది."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIMను అన్‌లాక్ చేస్తోంది…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-th/strings.xml b/packages/SystemUI/res-keyguard/values-th/strings.xml
index c244107..605d077 100644
--- a/packages/SystemUI/res-keyguard/values-th/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-th/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • กำลังชาร์จอย่างช้าๆ"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ปรับการชาร์จให้เหมาะสมเพื่อถนอมแบตเตอรี่"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ปัญหาเกี่ยวกับอุปกรณ์เสริมสำหรับการชาร์จ"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"กด \"เมนู\" เพื่อปลดล็อก"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"เครือข่ายถูกล็อก"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"ไม่มี SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"โปรดใส่ SIM"</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"ไม่มี SIM หรืออ่านไม่ได้ โปรดใส่ SIM"</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM ใช้งานไม่ได้"</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"ปิดใช้งาน SIM อย่างถาวรแล้ว\n ติดต่อผู้ให้บริการไร้สายของคุณเพื่อรับ SIM ใหม่"</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM ถูกล็อก"</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM ถูกล็อกด้วย PUK"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"กำลังปลดล็อก SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-tl/strings.xml b/packages/SystemUI/res-keyguard/values-tl/strings.xml
index cd8f810..040ec9e 100644
--- a/packages/SystemUI/res-keyguard/values-tl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tl/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mabagal na nagcha-charge"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Naka-optimize ang pag-charge para protektahan ang baterya"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Isyu sa pag-charge ng accessory"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pindutin ang Menu upang i-unlock."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Naka-lock ang network"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Walang SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Magdagdag ng SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"Wala o hindi nababasa ang SIM. Magdagdag ng SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Hindi magagamit na SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Permanenteng na-deactivate ang iyong SIM.\n Makipag-ugnayan sa iyong service provider ng wireless para sa isa pang SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"Naka-lock ang SIM."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"Naka-PUK lock ang SIM."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Ina-unlock ang SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-tr/strings.xml b/packages/SystemUI/res-keyguard/values-tr/strings.xml
index ddeba67..750ba11 100644
--- a/packages/SystemUI/res-keyguard/values-tr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tr/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Yavaş şarj oluyor"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Şarj işlemi pili korumak üzere optimize edildi"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Şarj aksesuarı ile ilgili sorun"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Kilidi açmak için Menü\'ye basın."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Ağ kilitli"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM yok"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"SIM ekleyin."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM yok veya okunamıyor. SIM ekleyin."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Kullanılamayan SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM\'iniz kalıcı olarak devre dışı bırakıldı.\n Başka bir SIM için kablosuz servis sağlayıcınızla iletişime geçin."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM kilitli."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM\'in PUK kilidi devrede."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM\'in kilidi açılıyor…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-uk/strings.xml b/packages/SystemUI/res-keyguard/values-uk/strings.xml
index f06d17d..169ea1f 100644
--- a/packages/SystemUI/res-keyguard/values-uk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uk/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Повільне заряджання"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Заряджання оптимізовано, щоб захистити акумулятор"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Проблема із зарядним пристроєм"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Натисніть меню, щоб розблокувати."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Мережу заблоковано"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Немає SIM-карти"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Додайте SIM-карту."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM-карта відсутня або недоступна для читання. Додайте SIM-карту."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Непридатна SIM-карта."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM-карту деактивовано назавжди.\n Щоб отримати іншу, зверніться до свого постачальника послуг бездротового зв’язку."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM-карту заблоковано."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM-карту заблоковано PUK-кодом."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Розблокування SIM-карти…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml
index 8adbaca..d7f7b65 100644
--- a/packages/SystemUI/res-keyguard/values-ur/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • آہستہ چارج ہو رہا ہے"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • بیٹری کی حفاظت کے لیے چارجنگ کو بہتر بنایا گیا"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • چارجنگ ایکسیسری کے ساتھ مسئلہ"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"غیر مقفل کرنے کیلئے مینیو دبائیں۔"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"نیٹ ورک مقفل ہو گیا"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"‏کوئی SIM نہیں ہے"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"‏ایک SIM شامل کریں۔"</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"‏SIM غائب ہے یا پڑھنے لائق نہیں ہے۔ ایک SIM شامل کریں۔"</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"‏ناقابل استعمال SIM۔"</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"‏آپ کے SIM کو مستقل طور پر غیر فعال کر دیا گیا ہے۔\n کسی دوسرے SIM کیلئے اپنے وائرلیس سروس فراہم کنندہ سے رابطہ کریں۔"</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"‏SIM مقفل ہے۔"</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"‏آپ کا SIM ‏PUK مقفل ہے۔"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"‏SIM کو غیر مقفل کیا جا رہا ہے…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-uz/strings.xml b/packages/SystemUI/res-keyguard/values-uz/strings.xml
index 96dfa05..40dbaf3 100644
--- a/packages/SystemUI/res-keyguard/values-uz/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uz/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Sekin quvvat olmoqda"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Batareyani himoyalash uchun quvvatlash optimallashtirildi"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Quvvatlash aksessuari bilan muammo"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Qulfdan chiqarish uchun Menyu tugmasini bosing."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Tarmoq qulflangan"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM kartasiz"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"SIM karta qoʻshish."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM karta topilmadi yoki oʻqilmadi. SIM karta qoʻshish."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Ishlamaydigan SIM."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM karta butunlay faolsizlantirildi.\n Boshqa SIM karta olish uchun simsiz aloqa operatoriga murojaat qiling."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM karta qulflandi."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM karta PUK kod bilan qulflangan."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM karta qulfdan chiqarilmoqda…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-vi/strings.xml b/packages/SystemUI/res-keyguard/values-vi/strings.xml
index 41b5a33..d5a33d3 100644
--- a/packages/SystemUI/res-keyguard/values-vi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-vi/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Đang sạc chậm"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Quá trình sạc được tối ưu hoá để bảo vệ pin"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Có vấn đề với phụ kiện sạc"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Nhấn vào Menu để mở khóa."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Mạng đã bị khóa"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Không có SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Hãy thêm SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"Không tìm thấy hoặc không đọc được SIM. Hãy thêm SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM không sử dụng được."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM của bạn đã bị vô hiệu hoá vĩnh viễn.\n Hãy liên hệ với nhà cung cấp dịch vụ viễn thông không dây của bạn để yêu cầu cấp SIM khác."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM này đang bị khoá."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM này đang bị khoá PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Đang mở khoá SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
index 4c65832..6de9ff9 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 正在慢速充电"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 为保护电池,充电方式已优化"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 充电配件有问题"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"按“菜单”即可解锁。"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"网络已锁定"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"没有 SIM 卡"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"请插入 SIM 卡。"</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIM 卡缺失或无法读取。请插入 SIM 卡。"</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM 卡无法使用。"</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"您的 SIM 卡已被永久停用。\n请与您的无线服务提供商联系,以便重新获取一张 SIM 卡。"</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM 卡已被锁定。"</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM 卡已用 PUK 码锁定。"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"正在解锁 SIM 卡…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
index dad6f31..11966ca 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 慢速充電中"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 為保護電池,系統已優化充電"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 充電配件發生問題"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"按下 [選單] 即可解鎖。"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"網絡已鎖定"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"沒有 SIM 卡"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"請新增 SIM 卡。"</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"找不到 SIM 卡或 SIM 卡無法讀取,請新增 SIM 卡。"</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM 卡無法使用。"</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM 卡已永久停用。\n請向無線服務供應商索取其他 SIM 卡。"</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM 卡已鎖定。"</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM 卡已使用 PUK 鎖定。"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"正在解鎖 SIM 卡…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
index 88b7e43..e4f868a 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 慢速充電中"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 為保護電池,充電效能已最佳化"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 充電配件有問題"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"按選單鍵解鎖。"</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"網路已鎖定"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"沒有 SIM 卡"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"請新增 SIM 卡。"</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"找不到 SIM 卡或 SIM 卡無法讀取,請新增 SIM 卡。"</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"SIM 卡無法使用。"</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"SIM 卡已永久停用。\n 請向無線服務供應商索取其他 SIM 卡。"</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM 卡已鎖定。"</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM 卡已使用 PUK 碼鎖定。"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"正在解鎖 SIM 卡…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zu/strings.xml b/packages/SystemUI/res-keyguard/values-zu/strings.xml
index c5e99ab..4fadc2e 100644
--- a/packages/SystemUI/res-keyguard/values-zu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zu/strings.xml
@@ -35,13 +35,9 @@
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ishaja kancane"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ukushaja kuthuthukisiwe ukuze kuvikelwe ibhethri"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • • Inkinga ngesisekeli sokushaja"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Chofoza Menyu ukuvula."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Inethiwekhi ivaliwe"</string>
     <string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Ayikho i-SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"engeza i-SIM"</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"I-SIM ayitholakali noma ayifundeki. engeza i-SIM"</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"I-SIM engasebenziseki."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"I-SIM yakho iyekiswe ukusebenza unomphela.\n Xhumana nomhlinzeki wakho wesevisi ngokungenazintambo ukuze uthole enye i-SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"I-SIM ikhiyiwe."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"I-SIM ikhiyiwe nge-PUK."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Ivula i-SIM…"</string>
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 28b5870..565ed10 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -67,23 +67,13 @@
     <!-- When the lock screen is showing and the phone plugged in with incompatible charger. -->
     <string name="keyguard_plugged_in_incompatible_charger"><xliff:g id="percentage">%s</xliff:g> • Issue with charging accessory</string>
 
-    <!-- On the keyguard screen, when pattern lock is disabled, only tell them to press menu to unlock.  This is shown in small font at the bottom. -->
-    <string name="keyguard_instructions_when_pattern_disabled">Press Menu to unlock.</string>
-
     <!-- SIM messages --><skip />
     <!-- When the user inserts a sim card from an unsupported network, it becomes network locked -->
     <string name="keyguard_network_locked_message">Network locked</string>
     <!-- Shown when there is no SIM. -->
     <string name="keyguard_missing_sim_message_short">No SIM</string>
-    <!-- Shown to ask the user to add a SIM. -->
-    <string name="keyguard_missing_sim_instructions">Add a SIM.</string>
-    <!-- Shown to ask the user to add a SIM when sim is missing or not readable. -->
-    <string name="keyguard_missing_sim_instructions_long">The SIM is missing or not readable. Add a SIM.</string>
     <!-- Shown when SIM is permanently disabled. -->
     <string name="keyguard_permanent_disabled_sim_message_short">Unusable SIM.</string>
-    <!-- Shown to inform the user to SIM is permanently deactivated. -->
-    <string name="keyguard_permanent_disabled_sim_instructions">Your SIM has been permanently deactivated.\n
-    Contact your wireless service provider for another SIM.</string>
     <!-- Shown to tell the user that their SIM is locked and they must unlock it. -->
     <string name="keyguard_sim_locked_message">SIM is locked.</string>
     <!-- When the user enters a wrong sim pin too many times, it becomes PUK locked (Pin Unlock Kode) -->
diff --git a/packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/Tracing.kt b/packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/Tracing.kt
new file mode 100644
index 0000000..9b7cd70
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/Tracing.kt
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2023 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.systemui.dagger.qualifiers
+
+import javax.inject.Qualifier
+
+@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class Tracing
diff --git a/packages/SystemUI/shared/src/com/android/systemui/util/TraceUtils.kt b/packages/SystemUI/shared/src/com/android/systemui/util/TraceUtils.kt
index 7b2e1af..e459034 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/util/TraceUtils.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/util/TraceUtils.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2023 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.
@@ -18,13 +18,25 @@
 
 import android.os.Trace
 import android.os.TraceNameSupplier
+import android.util.Log
+import com.android.systemui.util.tracing.TraceContextElement
+import com.android.systemui.util.tracing.TraceData
+import com.android.systemui.util.tracing.TraceData.Companion.FIRST_VALID_SPAN
+import com.android.systemui.util.tracing.TraceData.Companion.INVALID_SPAN
+import com.android.systemui.util.tracing.threadLocalTrace
 import java.util.concurrent.atomic.AtomicInteger
 import kotlin.coroutines.CoroutineContext
 import kotlin.coroutines.EmptyCoroutineContext
+import kotlin.coroutines.coroutineContext
+import kotlin.random.Random
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.CoroutineStart
 import kotlinx.coroutines.Deferred
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Job
 import kotlinx.coroutines.async
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withContext
 
 /**
  * Run a block within a [Trace] section. Calls [Trace.beginSection] before and [Trace.endSection]
@@ -44,6 +56,10 @@
 
 class TraceUtils {
     companion object {
+        const val TAG = "TraceUtils"
+        private const val DEBUG_COROUTINE_TRACING = false
+        const val DEFAULT_TRACK_NAME = "AsyncTraces"
+
         inline fun traceRunnable(tag: String, crossinline block: () -> Unit): Runnable {
             return Runnable { traceSection(tag) { block() } }
         }
@@ -73,7 +89,7 @@
          * under a single track.
          */
         inline fun <T> traceAsync(method: String, block: () -> T): T =
-            traceAsync("AsyncTraces", method, block)
+            traceAsync(DEFAULT_TRACK_NAME, method, block)
 
         /**
          * Creates an async slice in a track with [trackName] while [block] runs.
@@ -93,16 +109,313 @@
         }
 
         /**
-         * Convenience method to avoid one indentation level when we want to add a trace when
-         * launching a coroutine
+         * Convenience function for calling [CoroutineScope.launch] with [traceCoroutine] enable
+         * tracing.
+         *
+         * @see traceCoroutine
          */
-        fun <T> CoroutineScope.tracedAsync(
-            method: String,
+        inline fun CoroutineScope.launch(
+            crossinline spanName: () -> String,
             context: CoroutineContext = EmptyCoroutineContext,
-            start: CoroutineStart = CoroutineStart.DEFAULT,
-            block: suspend () -> T
-        ): Deferred<T> {
-            return async(context, start) { traceAsync(method) { block() } }
+            // TODO(b/306457056): DO NOT pass CoroutineStart; doing so will regress .odex size
+            crossinline block: suspend CoroutineScope.() -> Unit
+        ): Job = launch(context) { traceCoroutine(spanName) { block() } }
+
+        /**
+         * Convenience function for calling [CoroutineScope.launch] with [traceCoroutine] enable
+         * tracing.
+         *
+         * @see traceCoroutine
+         */
+        inline fun CoroutineScope.launch(
+            spanName: String,
+            context: CoroutineContext = EmptyCoroutineContext,
+            // TODO(b/306457056): DO NOT pass CoroutineStart; doing so will regress .odex size
+            crossinline block: suspend CoroutineScope.() -> Unit
+        ): Job = launch(context) { traceCoroutine(spanName) { block() } }
+
+        /**
+         * Convenience function for calling [CoroutineScope.async] with [traceCoroutine] enable
+         * tracing
+         *
+         * @see traceCoroutine
+         */
+        inline fun <T> CoroutineScope.async(
+            crossinline spanName: () -> String,
+            context: CoroutineContext = EmptyCoroutineContext,
+            // TODO(b/306457056): DO NOT pass CoroutineStart; doing so will regress .odex size
+            crossinline block: suspend CoroutineScope.() -> T
+        ): Deferred<T> = async(context) { traceCoroutine(spanName) { block() } }
+
+        /**
+         * Convenience function for calling [CoroutineScope.async] with [traceCoroutine] enable
+         * tracing.
+         *
+         * @see traceCoroutine
+         */
+        inline fun <T> CoroutineScope.async(
+            spanName: String,
+            context: CoroutineContext = EmptyCoroutineContext,
+            // TODO(b/306457056): DO NOT pass CoroutineStart; doing so will regress .odex size
+            crossinline block: suspend CoroutineScope.() -> T
+        ): Deferred<T> = async(context) { traceCoroutine(spanName) { block() } }
+
+        /**
+         * Convenience function for calling [runBlocking] with [traceCoroutine] to enable tracing.
+         *
+         * @see traceCoroutine
+         */
+        inline fun <T> runBlocking(
+            crossinline spanName: () -> String,
+            context: CoroutineContext,
+            crossinline block: suspend () -> T
+        ): T = runBlocking(context) { traceCoroutine(spanName) { block() } }
+
+        /**
+         * Convenience function for calling [runBlocking] with [traceCoroutine] to enable tracing.
+         *
+         * @see traceCoroutine
+         */
+        inline fun <T> runBlocking(
+            spanName: String,
+            context: CoroutineContext,
+            crossinline block: suspend CoroutineScope.() -> T
+        ): T = runBlocking(context) { traceCoroutine(spanName) { block() } }
+
+        /**
+         * Convenience function for calling [withContext] with [traceCoroutine] to enable tracing.
+         *
+         * @see traceCoroutine
+         */
+        suspend inline fun <T> withContext(
+            spanName: String,
+            context: CoroutineContext,
+            crossinline block: suspend CoroutineScope.() -> T
+        ): T = withContext(context) { traceCoroutine(spanName) { block() } }
+
+        /**
+         * Convenience function for calling [withContext] with [traceCoroutine] to enable tracing.
+         *
+         * @see traceCoroutine
+         */
+        suspend inline fun <T> withContext(
+            crossinline spanName: () -> String,
+            context: CoroutineContext,
+            crossinline block: suspend CoroutineScope.() -> T
+        ): T = withContext(context) { traceCoroutine(spanName) { block() } }
+
+        /**
+         * A hacky way to propagate the value of the COROUTINE_TRACING flag for static usage in this
+         * file. It should only every be set to true during startup. Once true, it cannot be set to
+         * false again.
+         */
+        var coroutineTracingIsEnabled = false
+            set(v) {
+                if (v) field = true
+            }
+
+        /**
+         * Traces a section of work of a `suspend` [block]. The trace sections will appear on the
+         * thread that is currently executing the [block] of work. If the [block] is suspended, all
+         * trace sections added using this API will end until the [block] is resumed, which could
+         * happen either on this thread or on another thread. If a child coroutine is started, it
+         * will inherit the trace sections of its parent. The child will continue to print these
+         * trace sections whether or not the parent coroutine is still running them.
+         *
+         * The current [CoroutineContext] must have a [TraceContextElement] for this API to work.
+         * Otherwise, the trace sections will be dropped.
+         *
+         * For example, in the following trace, Thread #1 ran some work, suspended, then continued
+         * working on Thread #2. Meanwhile, Thread #2 created a new child coroutine which inherited
+         * its trace sections. Then, the original coroutine resumed on Thread #1 before ending.
+         * Meanwhile Thread #3 is still printing trace sections from its parent because they were
+         * copied when it was created. There is no way for the parent to communicate to the child
+         * that it marked these slices as completed. While this might seem counterintuitive, it
+         * allows us to pinpoint the origin of the child coroutine's work.
+         *
+         * ```
+         * Thread #1 | [==== Slice A ====]                        [==== Slice A ====]
+         *           |       [==== B ====]                        [=== B ===]
+         * --------------------------------------------------------------------------------------
+         * Thread #2 |                    [====== Slice A ======]
+         *           |                    [========= B =========]
+         *           |                        [===== C ======]
+         * --------------------------------------------------------------------------------------
+         * Thread #3 |                            [== Slice A ==]                [== Slice A ==]
+         *           |                            [===== B =====]                [===== B =====]
+         *           |                            [===== C =====]                [===== C =====]
+         *           |                                                               [=== D ===]
+         * ```
+         *
+         * @param name The name of the code section to appear in the trace
+         * @see endSlice
+         * @see traceCoroutine
+         */
+        @OptIn(ExperimentalCoroutinesApi::class)
+        suspend inline fun <T> traceCoroutine(
+            spanName: Lazy<String>,
+            crossinline block: suspend () -> T
+        ): T {
+            // For coroutine tracing to work, trace spans must be added and removed even when
+            // tracing is not active (i.e. when TRACE_TAG_APP is disabled). Otherwise, when the
+            // coroutine resumes when tracing is active, we won't know its name.
+            val tracer = getTraceData(spanName)
+            val coroutineSpanCookie = tracer?.beginSpan(spanName.value) ?: INVALID_SPAN
+
+            // For now, also trace to "AsyncTraces". This will allow us to verify the correctness
+            // of the COROUTINE_TRACING feature flag.
+            val asyncTraceCookie =
+                if (Trace.isTagEnabled(Trace.TRACE_TAG_APP))
+                    Random.nextInt(FIRST_VALID_SPAN, Int.MAX_VALUE)
+                else INVALID_SPAN
+            if (asyncTraceCookie != INVALID_SPAN) {
+                Trace.asyncTraceForTrackBegin(
+                    Trace.TRACE_TAG_APP,
+                    DEFAULT_TRACK_NAME,
+                    spanName.value,
+                    asyncTraceCookie
+                )
+            }
+            try {
+                return block()
+            } finally {
+                if (asyncTraceCookie != INVALID_SPAN) {
+                    Trace.asyncTraceForTrackEnd(
+                        Trace.TRACE_TAG_APP,
+                        DEFAULT_TRACK_NAME,
+                        asyncTraceCookie
+                    )
+                }
+                tracer?.endSpan(coroutineSpanCookie)
+            }
+        }
+
+        @OptIn(ExperimentalCoroutinesApi::class)
+        suspend fun getTraceData(spanName: Lazy<String>): TraceData? {
+            if (!coroutineTracingIsEnabled) {
+                logVerbose("Experimental flag COROUTINE_TRACING is off", spanName)
+            } else if (coroutineContext[TraceContextElement] == null) {
+                logVerbose("Current CoroutineContext is missing TraceContextElement", spanName)
+            } else {
+                return threadLocalTrace.get().also {
+                    if (it == null) logVerbose("ThreadLocal TraceData is null", spanName)
+                }
+            }
+            return null
+        }
+
+        private fun logVerbose(logMessage: String, spanName: Lazy<String>) {
+            if (DEBUG_COROUTINE_TRACING && Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, "$logMessage. Dropping trace section: \"${spanName.value}\"")
+            }
+        }
+
+        /** @see traceCoroutine */
+        suspend inline fun <T> traceCoroutine(
+            spanName: String,
+            crossinline block: suspend () -> T
+        ): T = traceCoroutine(lazyOf(spanName)) { block() }
+
+        /** @see traceCoroutine */
+        suspend inline fun <T> traceCoroutine(
+            crossinline spanName: () -> String,
+            crossinline block: suspend () -> T
+        ): T = traceCoroutine(lazy(LazyThreadSafetyMode.PUBLICATION) { spanName() }) { block() }
+
+        /**
+         * Writes a trace message to indicate that a given section of code has begun running __on
+         * the current thread__. This must be followed by a corresponding call to [endSlice] in a
+         * reasonably short amount of time __on the same thread__ (i.e. _before_ the thread becomes
+         * idle again and starts running other, unrelated work).
+         *
+         * Calls to [beginSlice] and [endSlice] may be nested, and they will render in Perfetto as
+         * follows:
+         * ```
+         * Thread #1 | [==========================]
+         *           |       [==============]
+         *           |           [====]
+         * ```
+         *
+         * This function is provided for convenience to wrap a call to [Trace.traceBegin], which is
+         * more verbose to call than [Trace.beginSection], but has the added benefit of not throwing
+         * an [IllegalArgumentException] if the provided string is longer than 127 characters. We
+         * use the term "slice" instead of "section" to be consistent with Perfetto.
+         *
+         * # Avoiding malformed traces
+         *
+         * Improper usage of this API will lead to malformed traces with long slices that sometimes
+         * never end. This will look like the following:
+         * ```
+         * Thread #1 | [===================================================================== ...
+         *           |       [==============]         [====================================== ...
+         *           |           [=======]              [======]       [===================== ...
+         *           |                                                       [=======]
+         * ```
+         *
+         * To avoid this, [beginSlice] and [endSlice] should never be called from `suspend` blocks
+         * (instead, use [traceCoroutine] for tracing suspending functions). While it would be
+         * technically okay to call from a suspending function if that function were to only wrap
+         * non-suspending blocks with [beginSlice] and [endSlice], doing so is risky because suspend
+         * calls could be mistakenly added to that block as the code is refactored.
+         *
+         * Additionally, it is _not_ okay to call [beginSlice] when registering a callback and match
+         * it with a call to [endSlice] inside that callback, even if the callback runs on the same
+         * thread. Doing so would cause malformed traces because the [beginSlice] wasn't closed
+         * before the thread became idle and started running unrelated work.
+         *
+         * @param sliceName The name of the code section to appear in the trace
+         * @see endSlice
+         * @see traceCoroutine
+         */
+        fun beginSlice(sliceName: String) {
+            Trace.traceBegin(Trace.TRACE_TAG_APP, sliceName)
+        }
+
+        /**
+         * Writes a trace message to indicate that a given section of code has ended. This call must
+         * be preceded by a corresponding call to [beginSlice]. See [beginSlice] for important
+         * information regarding usage.
+         *
+         * @see beginSlice
+         * @see traceCoroutine
+         */
+        fun endSlice() {
+            Trace.traceEnd(Trace.TRACE_TAG_APP)
+        }
+
+        /**
+         * Writes a trace message indicating that an instant event occurred on the current thread.
+         * Unlike slices, instant events have no duration and do not need to be matched with another
+         * call. Perfetto will display instant events using an arrow pointing to the timestamp they
+         * occurred:
+         * ```
+         * Thread #1 | [==============]               [======]
+         *           |     [====]                        ^
+         *           |        ^
+         * ```
+         *
+         * @param eventName The name of the event to appear in the trace.
+         */
+        fun instant(eventName: String) {
+            Trace.instant(Trace.TRACE_TAG_APP, eventName)
+        }
+
+        /**
+         * Writes a trace message indicating that an instant event occurred on the given track.
+         * Unlike slices, instant events have no duration and do not need to be matched with another
+         * call. Perfetto will display instant events using an arrow pointing to the timestamp they
+         * occurred:
+         * ```
+         * Async  | [==============]               [======]
+         *  Track |     [====]                        ^
+         *   Name |        ^
+         * ```
+         *
+         * @param trackName The track where the event should appear in the trace.
+         * @param eventName The name of the event to appear in the trace.
+         */
+        fun instantForTrack(trackName: String, eventName: String) {
+            Trace.instantForTrack(Trace.TRACE_TAG_APP, trackName, eventName)
         }
     }
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/util/tracing/TraceContextElement.kt b/packages/SystemUI/shared/src/com/android/systemui/util/tracing/TraceContextElement.kt
new file mode 100644
index 0000000..4d8c545
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/util/tracing/TraceContextElement.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023 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.systemui.util.tracing
+
+import com.android.systemui.util.TraceUtils.Companion.instant
+import com.android.systemui.util.TraceUtils.Companion.traceCoroutine
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.CopyableThreadContextElement
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+/**
+ * Used for safely persisting [TraceData] state when coroutines are suspended and resumed.
+ *
+ * This is internal machinery for [traceCoroutine]. It cannot be made `internal` or `private`
+ * because [traceCoroutine] is a Public-API inline function.
+ *
+ * @see traceCoroutine
+ */
+@OptIn(DelicateCoroutinesApi::class)
+@ExperimentalCoroutinesApi
+class TraceContextElement(private val traceData: TraceData = TraceData()) :
+    CopyableThreadContextElement<TraceData?> {
+
+    companion object Key : CoroutineContext.Key<TraceContextElement>
+
+    override val key: CoroutineContext.Key<TraceContextElement> = Key
+
+    @OptIn(ExperimentalStdlibApi::class)
+    override fun updateThreadContext(context: CoroutineContext): TraceData? {
+        val oldState = threadLocalTrace.get()
+        oldState?.endAllOnThread()
+        threadLocalTrace.set(traceData)
+        instant("resuming ${context[CoroutineDispatcher]}")
+        traceData.beginAllOnThread()
+        return oldState
+    }
+
+    @OptIn(ExperimentalStdlibApi::class)
+    override fun restoreThreadContext(context: CoroutineContext, oldState: TraceData?) {
+        instant("suspending ${context[CoroutineDispatcher]}")
+        traceData.endAllOnThread()
+        threadLocalTrace.set(oldState)
+        oldState?.beginAllOnThread()
+    }
+
+    override fun copyForChild(): CopyableThreadContextElement<TraceData?> {
+        return TraceContextElement(traceData.copy())
+    }
+
+    override fun mergeForChild(overwritingElement: CoroutineContext.Element): CoroutineContext {
+        return TraceContextElement(traceData.copy())
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/util/tracing/TraceData.kt b/packages/SystemUI/shared/src/com/android/systemui/util/tracing/TraceData.kt
new file mode 100644
index 0000000..0ae58fc
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/util/tracing/TraceData.kt
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2023 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.systemui.util.tracing
+
+import android.os.Build
+import android.util.Log
+import com.android.systemui.util.TraceUtils.Companion.beginSlice
+import com.android.systemui.util.TraceUtils.Companion.endSlice
+import com.android.systemui.util.TraceUtils.Companion.traceCoroutine
+import kotlin.random.Random
+
+/**
+ * Used for giving each thread a unique [TraceData] for thread-local storage. `null` by default.
+ * [threadLocalTrace] can only be used when it is paired with a [TraceContextElement].
+ *
+ * This ThreadLocal will be `null` if either 1) we aren't in a coroutine, or 2) the coroutine we are
+ * in does not have a [TraceContextElement].
+ *
+ * This is internal machinery for [traceCoroutine]. It cannot be made `internal` or `private`
+ * because [traceCoroutine] is a Public-API inline function.
+ *
+ * @see traceCoroutine
+ */
+val threadLocalTrace = ThreadLocal<TraceData?>()
+
+/**
+ * Used for storing trace sections so that they can be added and removed from the currently running
+ * thread when the coroutine is suspended and resumed.
+ *
+ * This is internal machinery for [traceCoroutine]. It cannot be made `internal` or `private`
+ * because [traceCoroutine] is a Public-API inline function.
+ *
+ * @see traceCoroutine
+ */
+class TraceData {
+    private var slices = mutableListOf<TraceSection>()
+
+    /** Adds current trace slices back to the current thread. Called when coroutine is resumed. */
+    fun beginAllOnThread() {
+        slices.forEach { beginSlice(it.name) }
+    }
+
+    /**
+     * Removes all current trace slices from the current thread. Called when coroutine is suspended.
+     */
+    fun endAllOnThread() {
+        for (i in 0..slices.size) {
+            endSlice()
+        }
+    }
+
+    /**
+     * Creates a new trace section with a unique ID and adds it to the current trace data. The slice
+     * will also be added to the current thread immediately. This slice will not propagate to parent
+     * coroutines, or to child coroutines that have already started. The unique ID is used to verify
+     * that the [endSpan] is corresponds to a [beginSpan].
+     */
+    fun beginSpan(name: String): Int {
+        val newSlice = TraceSection(name, Random.nextInt(FIRST_VALID_SPAN, Int.MAX_VALUE))
+        slices.add(newSlice)
+        beginSlice(name)
+        return newSlice.id
+    }
+
+    /**
+     * Used by [TraceContextElement] when launching a child coroutine so that the child coroutine's
+     * state is isolated from the parent.
+     */
+    fun copy(): TraceData {
+        return TraceData().also { it.slices.addAll(slices) }
+    }
+
+    /**
+     * Ends the trace section and validates it corresponds with an earlier call to [beginSpan]. The
+     * trace slice will immediately be removed from the current thread. This information will not
+     * propagate to parent coroutines, or to child coroutines that have already started.
+     */
+    fun endSpan(id: Int) {
+        val v = slices.removeLast()
+        if (v.id != id) {
+            if (STRICT_MODE) {
+                throw IllegalArgumentException(errorMsg)
+            } else if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, errorMsg)
+            }
+        }
+        endSlice()
+    }
+
+    companion object {
+        private const val TAG = "TraceData"
+        const val INVALID_SPAN = -1
+        const val FIRST_VALID_SPAN = 1
+
+        /**
+         * If true, throw an exception instead of printing a warning when trace sections beginnings
+         * and ends are mismatched.
+         */
+        private val STRICT_MODE = Build.IS_ENG
+
+        private const val errorMsg =
+            "Mismatched trace section. This likely means you are accessing the trace local " +
+                "storage (threadLocalTrace) without a corresponding CopyableThreadContextElement." +
+                " This could happen if you are using a global dispatcher like Dispatchers.IO." +
+                " To fix this, use one of the coroutine contexts provided by the dagger scope " +
+                "(e.g. \"@Main CoroutineContext\")."
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/util/tracing/TraceSection.kt b/packages/SystemUI/shared/src/com/android/systemui/util/tracing/TraceSection.kt
new file mode 100644
index 0000000..b70c497
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/util/tracing/TraceSection.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 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.systemui.util.tracing
+
+import com.android.systemui.util.TraceUtils.Companion.traceCoroutine
+
+/**
+ * Represents a section of code executing in a coroutine. This can be split up into multiple slices
+ * on different threads as the coroutine is suspended and resumed.
+ *
+ * This is internal machinery for [traceCoroutine]. It cannot be made `internal` or `private`
+ * because [traceCoroutine] is a Public-API inline function.
+ *
+ * @param name the name of the slice to appear on the current thread's track.
+ * @param id used for matching the beginning and end of trace sections and validating correctness
+ * @see traceCoroutine
+ */
+data class TraceSection(
+    val name: String,
+    val id: Int,
+)
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
index 873c3d9..1cfa816 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
@@ -39,10 +39,10 @@
 
 import com.android.keyguard.logging.CarrierTextManagerLogger;
 import com.android.settingslib.WirelessUtils;
-import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository;
 import com.android.systemui.telephony.TelephonyListenerManager;
 
@@ -612,36 +612,6 @@
         return list;
     }
 
-    private CharSequence getCarrierHelpTextForSimState(int simState,
-            String plmn, String spn) {
-        int carrierHelpTextId = 0;
-        CarrierTextManager.StatusMode status = getStatusForIccState(simState);
-        switch (status) {
-            case NetworkLocked:
-                carrierHelpTextId = R.string.keyguard_instructions_when_pattern_disabled;
-                break;
-
-            case SimMissing:
-                carrierHelpTextId = R.string.keyguard_missing_sim_instructions_long;
-                break;
-
-            case SimPermDisabled:
-                carrierHelpTextId = R.string.keyguard_permanent_disabled_sim_instructions;
-                break;
-
-            case SimMissingLocked:
-                carrierHelpTextId = R.string.keyguard_missing_sim_instructions;
-                break;
-
-            case Normal:
-            case SimLocked:
-            case SimPukLocked:
-                break;
-        }
-
-        return mContext.getText(carrierHelpTextId);
-    }
-
     /** Injectable Buildeer for {@#link CarrierTextManager}. */
     public static class Builder {
         private final Context mContext;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
index 13f9d3e..05fb5fa 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
@@ -246,7 +246,7 @@
 
     private boolean checkPuk() {
         // make sure the puk is at least 8 digits long.
-        if (mPasswordEntry.getText().length() == 8) {
+        if (mPasswordEntry.getText().length() >= 8) {
             mPukText = mPasswordEntry.getText();
             return true;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
index 453a7a6..8ea867b 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
@@ -28,6 +28,8 @@
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.deviceentry.data.repository.DeviceEntryRepository
 import com.android.systemui.user.data.repository.UserRepository
+import com.android.systemui.util.TraceUtils.Companion.async
+import com.android.systemui.util.TraceUtils.Companion.withContext
 import com.android.systemui.util.time.SystemClock
 import javax.inject.Inject
 import kotlin.math.max
@@ -263,7 +265,7 @@
      *   not being throttled.
      */
     private suspend fun refreshThrottling(): Long {
-        return withContext(backgroundDispatcher) {
+        return withContext("$TAG#refreshThrottling", backgroundDispatcher) {
             val failedAttemptCount = async { repository.getFailedAuthenticationAttemptCount() }
             val deadline = async { repository.getThrottlingEndTimestamp() }
             val remainingMs = max(0, deadline.await() - clock.elapsedRealtime())
@@ -311,6 +313,10 @@
                 DomainLayerAuthenticationMethodModel.Pattern
         }
     }
+
+    companion object {
+        const val TAG = "AuthenticationInteractor"
+    }
 }
 
 /** Result of a user authentication attempt. */
diff --git a/packages/SystemUI/src/com/android/systemui/complication/ComplicationLayoutEngine.java b/packages/SystemUI/src/com/android/systemui/complication/ComplicationLayoutEngine.java
index 20b2494..f7b6b0f 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/ComplicationLayoutEngine.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/ComplicationLayoutEngine.java
@@ -652,8 +652,7 @@
             CrossFadeHelper.fadeOut(
                     mLayout,
                     mFadeOutDuration,
-                    /* delay= */ 0,
-                    /* endRunnable= */ null);
+                    /* delay= */ 0);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/flags/ConditionalRestarter.kt b/packages/SystemUI/src/com/android/systemui/flags/ConditionalRestarter.kt
index 93b00ee..dd58604 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/ConditionalRestarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/ConditionalRestarter.kt
@@ -17,13 +17,13 @@
 package com.android.systemui.flags
 
 import android.util.Log
-import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.flags.ConditionalRestarter.Condition
+import com.android.systemui.util.kotlin.UnflaggedApplication
+import com.android.systemui.util.kotlin.UnflaggedBackground
 import java.util.concurrent.TimeUnit
 import javax.inject.Inject
 import javax.inject.Named
-import kotlinx.coroutines.CoroutineDispatcher
+import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.Flow
@@ -39,8 +39,8 @@
     private val systemExitRestarter: SystemExitRestarter,
     private val conditions: Set<@JvmSuppressWildcards Condition>,
     @Named(RESTART_DELAY) private val restartDelaySec: Long,
-    @Application private val applicationScope: CoroutineScope,
-    @Background private val backgroundDispatcher: CoroutineDispatcher,
+    @UnflaggedApplication private val applicationScope: CoroutineScope,
+    @UnflaggedBackground private val backgroundDispatcher: CoroutineContext,
 ) : Restarter {
 
     private var pendingReason = ""
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 10fac4d..8c81fbb 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -118,7 +118,7 @@
     // TODO(b/292213543): Tracking Bug
     @JvmField
     val NOTIFICATION_GROUP_EXPANSION_CHANGE =
-            unreleasedFlag("notification_group_expansion_change", teamfood = true)
+            releasedFlag("notification_group_expansion_change")
 
     // TODO(b/301955929)
     @JvmField
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt b/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt
index bc07139..6f491d8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt
@@ -36,9 +36,9 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
 import com.android.systemui.keyguard.ui.preview.KeyguardRemotePreviewManager
 import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
+import com.android.systemui.util.TraceUtils.Companion.runBlocking
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.runBlocking
 
 class CustomizationProvider :
     ContentProvider(), SystemUIAppComponentFactoryBase.ContextInitializer {
@@ -132,7 +132,7 @@
             throw UnsupportedOperationException()
         }
 
-        return runBlocking(mainDispatcher) { insertSelection(values) }
+        return runBlocking("$TAG#insert", mainDispatcher) { insertSelection(values) }
     }
 
     override fun query(
@@ -142,7 +142,7 @@
         selectionArgs: Array<out String>?,
         sortOrder: String?,
     ): Cursor? {
-        return runBlocking(mainDispatcher) {
+        return runBlocking("$TAG#query", mainDispatcher) {
             when (uriMatcher.match(uri)) {
                 MATCH_CODE_ALL_AFFORDANCES -> queryAffordances()
                 MATCH_CODE_ALL_SLOTS -> querySlots()
@@ -172,7 +172,7 @@
             throw UnsupportedOperationException()
         }
 
-        return runBlocking(mainDispatcher) { deleteSelection(uri, selectionArgs) }
+        return runBlocking("$TAG#delete", mainDispatcher) { deleteSelection(uri, selectionArgs) }
     }
 
     override fun call(method: String, arg: String?, extras: Bundle?): Bundle? {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
index d44a9d8..95ac0d8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
@@ -31,6 +31,7 @@
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.power.domain.interactor.PowerInteractor
 import com.android.systemui.shade.data.repository.ShadeRepository
+import com.android.systemui.util.TraceUtils.Companion.launch
 import com.android.systemui.util.kotlin.Utils.Companion.toQuad
 import com.android.systemui.util.kotlin.Utils.Companion.toTriple
 import com.android.systemui.util.kotlin.sample
@@ -43,7 +44,6 @@
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onStart
-import kotlinx.coroutines.launch
 
 @SysUISingleton
 class FromLockscreenTransitionInteractor
@@ -136,7 +136,7 @@
 
     private fun listenForLockscreenToDreaming() {
         val invalidFromStates = setOf(KeyguardState.AOD, KeyguardState.DOZING)
-        scope.launch {
+        scope.launch("$TAG#listenForLockscreenToDreaming") {
             keyguardInteractor.isAbleToDream
                 .sample(
                     combine(
@@ -169,7 +169,7 @@
     }
 
     private fun listenForLockscreenToPrimaryBouncer() {
-        scope.launch {
+        scope.launch("$TAG#listenForLockscreenToPrimaryBouncer") {
             keyguardInteractor.primaryBouncerShowing
                 .sample(transitionInteractor.startedKeyguardTransitionStep, ::Pair)
                 .collect { pair ->
@@ -184,7 +184,7 @@
     }
 
     private fun listenForLockscreenToAlternateBouncer() {
-        scope.launch {
+        scope.launch("$TAG#listenForLockscreenToAlternateBouncer") {
             keyguardInteractor.alternateBouncerShowing
                 .sample(transitionInteractor.startedKeyguardTransitionStep, ::Pair)
                 .collect { pair ->
@@ -202,7 +202,7 @@
     /* Starts transitions when manually dragging up the bouncer from the lockscreen. */
     private fun listenForLockscreenToPrimaryBouncerDragging() {
         var transitionId: UUID? = null
-        scope.launch {
+        scope.launch("$TAG#listenForLockscreenToPrimaryBouncerDragging") {
             shadeRepository.shadeModel
                 .sample(
                     combine(
@@ -287,7 +287,7 @@
             return
         }
 
-        scope.launch {
+        scope.launch("$TAG#listenForLockscreenToGone") {
             keyguardInteractor.isKeyguardGoingAway
                 .sample(transitionInteractor.startedKeyguardTransitionStep, ::Pair)
                 .collect { pair ->
@@ -304,7 +304,7 @@
             return
         }
 
-        scope.launch {
+        scope.launch("$TAG#listenForLockscreenToGoneDragging") {
             keyguardInteractor.isKeyguardGoingAway
                 .sample(transitionInteractor.startedKeyguardTransitionStep, ::Pair)
                 .collect { pair ->
@@ -317,7 +317,7 @@
     }
 
     private fun listenForLockscreenToOccluded() {
-        scope.launch {
+        scope.launch("$TAG#listenForLockscreenToOccluded") {
             keyguardInteractor.isKeyguardOccluded
                 .sample(transitionInteractor.startedKeyguardState, ::Pair)
                 .collect { (isOccluded, keyguardState) ->
@@ -329,7 +329,7 @@
     }
 
     private fun listenForLockscreenToAodOrDozing() {
-        scope.launch {
+        scope.launch("$TAG#listenForLockscreenToAodOrDozing") {
             powerInteractor.isAsleep
                 .sample(
                     combine(
@@ -375,6 +375,7 @@
     }
 
     companion object {
+        const val TAG = "FromLockscreenTransitionInteractor"
         private val DEFAULT_DURATION = 400.milliseconds
         val TO_DREAMING_DURATION = 933.milliseconds
         val TO_OCCLUDED_DURATION = 450.milliseconds
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
index de791aa..fe9370f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
@@ -23,7 +23,6 @@
 import android.content.Intent
 import android.util.Log
 import com.android.internal.widget.LockPatternUtils
-import com.android.systemui.res.R
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.animation.Expandable
 import com.android.systemui.dagger.SysUISingleton
@@ -44,11 +43,12 @@
 import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
 import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancesMetricsLogger
 import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.res.R
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.statusbar.policy.KeyguardStateController
-import com.android.systemui.util.TraceUtils.Companion.traceAsync
+import com.android.systemui.util.TraceUtils.Companion.withContext
 import dagger.Lazy
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
@@ -59,7 +59,6 @@
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onStart
-import kotlinx.coroutines.withContext
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SysUISingleton
@@ -417,10 +416,8 @@
     }
 
     private suspend fun isFeatureDisabledByDevicePolicy(): Boolean =
-        traceAsync(TAG, "isFeatureDisabledByDevicePolicy") {
-            withContext(backgroundDispatcher) {
-                devicePolicyManager.areKeyguardShortcutsDisabled(userId = userTracker.userId)
-            }
+        withContext("$TAG#isFeatureDisabledByDevicePolicy", backgroundDispatcher) {
+            devicePolicyManager.areKeyguardShortcutsDisabled(userId = userTracker.userId)
         }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt b/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt
index 565bf24..baa07c1 100644
--- a/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt
@@ -95,7 +95,7 @@
         tableLogBuffer.logChange(columnPrefix, columnName, initialValue, isInitial = true)
         initialValue
     }
-    return this.pairwiseBy(initialValueFun) { prevVal, newVal: Boolean ->
+    return this.pairwiseBy(initialValueFun) { prevVal: Boolean, newVal: Boolean ->
         if (prevVal != newVal) {
             tableLogBuffer.logChange(columnPrefix, columnName, newVal)
         }
@@ -114,7 +114,7 @@
         tableLogBuffer.logChange(columnPrefix, columnName, initialValue, isInitial = true)
         initialValue
     }
-    return this.pairwiseBy(initialValueFun) { prevVal, newVal: Int ->
+    return this.pairwiseBy(initialValueFun) { prevVal: Int, newVal: Int ->
         if (prevVal != newVal) {
             tableLogBuffer.logChange(columnPrefix, columnName, newVal)
         }
@@ -133,7 +133,7 @@
         tableLogBuffer.logChange(columnPrefix, columnName, initialValue, isInitial = true)
         initialValue
     }
-    return this.pairwiseBy(initialValueFun) { prevVal, newVal: Int? ->
+    return this.pairwiseBy(initialValueFun) { prevVal: Int?, newVal: Int? ->
         if (prevVal != newVal) {
             tableLogBuffer.logChange(columnPrefix, columnName, newVal)
         }
@@ -152,7 +152,7 @@
         tableLogBuffer.logChange(columnPrefix, columnName, initialValue, isInitial = true)
         initialValue
     }
-    return this.pairwiseBy(initialValueFun) { prevVal, newVal: String? ->
+    return this.pairwiseBy(initialValueFun) { prevVal: String?, newVal: String? ->
         if (prevVal != newVal) {
             tableLogBuffer.logChange(columnPrefix, columnName, newVal)
         }
@@ -176,7 +176,7 @@
         )
         initialValue
     }
-    return this.pairwiseBy(initialValueFun) { prevVal, newVal: List<T> ->
+    return this.pairwiseBy(initialValueFun) { prevVal: List<T>, newVal: List<T> ->
         if (prevVal != newVal) {
             // TODO(b/267761156): Can we log list changes without using toString?
             tableLogBuffer.logChange(columnPrefix, columnName, newVal.toString())
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index 051eeb0..bd13d06 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -48,6 +48,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.WorkerThread;
 
+import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.animation.ActivityLaunchAnimator;
@@ -538,12 +539,17 @@
             Log.i(TAG, "Launching activity before click");
         } else {
             Log.i(TAG, "The activity is starting");
-            ActivityLaunchAnimator.Controller controller = mViewClicked == null
-                    ? null
-                    : ActivityLaunchAnimator.Controller.fromView(mViewClicked, 0);
-            mUiHandler.post(() ->
-                    mActivityStarter.startPendingIntentDismissingKeyguard(
-                            pendingIntent, null, controller)
+
+            ActivityLaunchAnimator.Controller controller =
+                    mViewClicked == null ? null :
+                    ActivityLaunchAnimator.Controller.fromView(
+                            mViewClicked,
+                            InteractionJankMonitor.CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE
+                    );
+            mActivityStarter.startPendingIntentMaybeDismissingKeyguard(
+                    pendingIntent,
+                    /* intentSentUiThreadCallback= */ null,
+                    controller
             );
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
index f0650d3..9ba02b1 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
@@ -17,6 +17,8 @@
 package com.android.systemui.scene.shared.flag
 
 import androidx.annotation.VisibleForTesting
+import com.android.systemui.FeatureFlags
+import com.android.systemui.Flags as AConfigFlags
 import com.android.systemui.compose.ComposeFacade
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.flags.FeatureFlagsClassic
@@ -47,15 +49,15 @@
 class SceneContainerFlagsImpl
 @AssistedInject
 constructor(
-    private val featureFlags: FeatureFlagsClassic,
+    private val featureFlagsClassic: FeatureFlagsClassic,
+    featureFlags: FeatureFlags,
     @Assisted private val isComposeAvailable: Boolean,
 ) : SceneContainerFlags {
 
     companion object {
         @VisibleForTesting
-        val flags: List<Flag<Boolean>> =
+        val classicFlagTokens: List<Flag<Boolean>> =
             listOf(
-                Flags.SCENE_CONTAINER,
                 Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA,
                 Flags.MIGRATE_LOCK_ICON,
                 Flags.MIGRATE_NSSL,
@@ -67,7 +69,13 @@
 
     /** The list of requirements, all must be met for the feature to be enabled. */
     private val requirements =
-        flags.map { FlagMustBeEnabled(it) } +
+        listOf(
+            AconfigFlagMustBeEnabled(
+                flagName = AConfigFlags.FLAG_SCENE_CONTAINER,
+                flagValue = featureFlags.sceneContainer(),
+            ),
+        ) +
+            classicFlagTokens.map { flagToken -> FlagMustBeEnabled(flagToken) } +
             listOf(ComposeMustBeAvailable(), CompileTimeFlagMustBeEnabled())
 
     override fun isEnabled(): Boolean {
@@ -115,14 +123,25 @@
 
         override fun isMet(): Boolean {
             return when (flag) {
-                is ResourceBooleanFlag -> featureFlags.isEnabled(flag)
-                is ReleasedFlag -> featureFlags.isEnabled(flag)
-                is UnreleasedFlag -> featureFlags.isEnabled(flag)
+                is ResourceBooleanFlag -> featureFlagsClassic.isEnabled(flag)
+                is ReleasedFlag -> featureFlagsClassic.isEnabled(flag)
+                is UnreleasedFlag -> featureFlagsClassic.isEnabled(flag)
                 else -> error("Unsupported flag type ${flag.javaClass}")
             }
         }
     }
 
+    private inner class AconfigFlagMustBeEnabled(
+        flagName: String,
+        private val flagValue: Boolean,
+    ) : Requirement {
+        override val name: String = "Aconfig flag $flagName must be enabled"
+
+        override fun isMet(): Boolean {
+            return flagValue
+        }
+    }
+
     @AssistedFactory
     interface Factory {
         fun create(isComposeAvailable: Boolean): SceneContainerFlagsImpl
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt
index aa6bfc3..10d5f59 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt
@@ -34,11 +34,11 @@
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.settings.DisplayTracker
+import com.android.systemui.util.TraceUtils.Companion.launch
 import javax.inject.Inject
 import kotlinx.coroutines.CompletableDeferred
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 
 @SysUISingleton
@@ -63,7 +63,9 @@
         user: UserHandle,
         overrideTransition: Boolean,
     ) {
-        applicationScope.launch { launchIntent(intent, options, user, overrideTransition) }
+        applicationScope.launch("$TAG#launchIntentAsync") {
+            launchIntent(intent, options, user, overrideTransition)
+        }
     }
 
     suspend fun launchIntent(
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt
index c34fd42..f1c74c1 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt
@@ -20,10 +20,10 @@
 import android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.util.TraceUtils.Companion.launch
+import kotlinx.coroutines.CoroutineScope
 import java.util.function.Consumer
 import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
 
 /** Processes a screenshot request sent from [ScreenshotHelper]. */
 interface ScreenshotRequestProcessor {
@@ -88,7 +88,7 @@
      *                 thread
      */
     fun processAsync(screenshot: ScreenshotData, callback: Consumer<ScreenshotData>) {
-        mainScope.launch {
+        mainScope.launch({ "$TAG#processAsync" }) {
             val result = process(screenshot)
             callback.accept(result)
         }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotProxyService.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotProxyService.kt
index 14e875d2..d2e4794 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotProxyService.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotProxyService.kt
@@ -25,7 +25,7 @@
 import com.android.systemui.shade.ShadeExpansionStateManager
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.launch
+import com.android.systemui.util.TraceUtils.Companion.launch
 import kotlinx.coroutines.withContext
 
 /** Provides state from the main SystemUI process on behalf of the Screenshot process. */
@@ -47,7 +47,9 @@
             }
 
             override fun dismissKeyguard(callback: IOnDoneCallback) {
-                lifecycleScope.launch { executeAfterDismissing(callback) }
+                lifecycleScope.launch("IScreenshotProxy#dismissKeyguard") {
+                    executeAfterDismissing(callback)
+                }
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSoundController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSoundController.kt
index cd0cab5..1eae191 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSoundController.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSoundController.kt
@@ -20,7 +20,7 @@
 import android.util.Log
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.util.TraceUtils.Companion.tracedAsync
+import com.android.systemui.util.TraceUtils.Companion.async
 import com.google.errorprone.annotations.CanIgnoreReturnValue
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.seconds
@@ -48,7 +48,7 @@
 ) : ScreenshotSoundController {
 
     val player: Deferred<MediaPlayer?> =
-        coroutineScope.tracedAsync("loadCameraSound", bgDispatcher) {
+        coroutineScope.async("loadCameraSound", bgDispatcher) {
             try {
                 soundProvider.getScreenshotSound()
             } catch (e: IllegalStateException) {
@@ -58,12 +58,10 @@
         }
 
     override fun playCameraSound(): Deferred<Unit> {
-        return coroutineScope.tracedAsync("playCameraSound", bgDispatcher) {
-            player.await()?.start()
-        }
+        return coroutineScope.async("playCameraSound", bgDispatcher) { player.await()?.start() }
     }
     override fun releaseScreenshotSound(): Deferred<Unit> {
-        return coroutineScope.tracedAsync("releaseScreenshotSound", bgDispatcher) {
+        return coroutineScope.async("releaseScreenshotSound", bgDispatcher) {
             try {
                 withTimeout(1.seconds) { player.await()?.release() }
             } catch (e: TimeoutCancellationException) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt
index 25ee8d8..5684605 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt
@@ -13,11 +13,11 @@
 import com.android.systemui.res.R
 import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_CAPTURE_FAILED
 import com.android.systemui.screenshot.TakeScreenshotService.RequestCallback
+import com.android.systemui.util.TraceUtils.Companion.launch
 import java.util.function.Consumer
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.launch
 
 /**
  * Receives the signal to take a screenshot from [TakeScreenshotService], and calls back with the
@@ -176,7 +176,7 @@
         onSaved: Consumer<Uri>,
         requestCallback: RequestCallback
     ) {
-        mainScope.launch {
+        mainScope.launch("TakeScreenshotService#executeScreenshotsAsync") {
             executeScreenshots(screenshotRequest, { uri -> onSaved.accept(uri) }, requestCallback)
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index cc59f87..8dc97c0 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -2629,6 +2629,7 @@
         if (isPanelExpanded() != isExpanded) {
             setExpandedOrAwaitingInputTransfer(isExpanded);
             updateSystemUiStateFlags();
+            mShadeExpansionStateManager.onShadeExpansionFullyChanged(isExpanded);
             if (!isExpanded) {
                 mQsController.closeQsCustomizer();
             }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index 3d3447b..a2627ed 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -65,7 +65,7 @@
 import com.android.systemui.statusbar.NotificationShadeDepthController;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
-import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository;
+import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor;
 import com.android.systemui.statusbar.notification.stack.AmbientState;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
@@ -182,7 +182,7 @@
             PrimaryBouncerToGoneTransitionViewModel primaryBouncerToGoneTransitionViewModel,
             CommunalViewModel communalViewModel,
             CommunalRepository communalRepository,
-            NotificationExpansionRepository notificationExpansionRepository,
+            NotificationLaunchAnimationInteractor notificationLaunchAnimationInteractor,
             FeatureFlagsClassic featureFlagsClassic,
             SystemClock clock,
             BouncerMessageInteractor bouncerMessageInteractor,
@@ -239,7 +239,7 @@
                 mLockscreenToDreamingTransition);
         collectFlow(
                 mView,
-                notificationExpansionRepository.isExpandAnimationRunning(),
+                notificationLaunchAnimationInteractor.isLaunchAnimationRunning(),
                 this::setExpandAnimationRunning);
 
         mClock = clock;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt
index 533927d..0554c58 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt
@@ -36,6 +36,7 @@
 class ShadeExpansionStateManager @Inject constructor() : ShadeStateEvents {
 
     private val expansionListeners = CopyOnWriteArrayList<ShadeExpansionListener>()
+    private val fullExpansionListeners = CopyOnWriteArrayList<ShadeFullExpansionListener>()
     private val qsExpansionListeners = CopyOnWriteArrayList<ShadeQsExpansionListener>()
     private val qsExpansionFractionListeners =
         CopyOnWriteArrayList<ShadeQsExpansionFractionListener>()
@@ -66,6 +67,15 @@
         expansionListeners.remove(listener)
     }
 
+    fun addFullExpansionListener(listener: ShadeFullExpansionListener) {
+        fullExpansionListeners.add(listener)
+        listener.onShadeExpansionFullyChanged(qsExpanded)
+    }
+
+    fun removeFullExpansionListener(listener: ShadeFullExpansionListener) {
+        fullExpansionListeners.remove(listener)
+    }
+
     fun addQsExpansionListener(listener: ShadeQsExpansionListener) {
         qsExpansionListeners.add(listener)
         listener.onQsExpansionChanged(qsExpanded)
@@ -89,6 +99,11 @@
         stateListeners.add(listener)
     }
 
+    /** Removes a state listener. */
+    fun removeStateListener(listener: ShadeStateListener) {
+        stateListeners.remove(listener)
+    }
+
     override fun addShadeStateEventsListener(listener: ShadeStateEventsListener) {
         shadeStateEventsListeners.addIfAbsent(listener)
     }
@@ -181,6 +196,13 @@
         }
     }
 
+    fun onShadeExpansionFullyChanged(isExpanded: Boolean) {
+        this.expanded = isExpanded
+
+        debugLog("expanded=$isExpanded")
+        fullExpansionListeners.forEach { it.onShadeExpansionFullyChanged(isExpanded) }
+    }
+
     /** Updates the panel state if necessary. */
     fun updateState(@PanelState state: Int) {
         debugLog(
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeFullExpansionListener.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeFullExpansionListener.kt
new file mode 100644
index 0000000..6d13e19
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeFullExpansionListener.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2022 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.systemui.shade
+
+/** A listener interface to be notified of expansion events for the notification shade. */
+fun interface ShadeFullExpansionListener {
+    /** Invoked whenever the shade expansion changes, when it is fully collapsed or expanded */
+    fun onShadeExpansionFullyChanged(isExpanded: Boolean)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
index f043c71..2f68476 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
@@ -148,13 +148,12 @@
      *
      * TODO(b/300258424) remove all but the first sentence of this comment
      */
-    val isAnyExpanded: StateFlow<Boolean> =
+    val isAnyExpanded: Flow<Boolean> =
         if (sceneContainerFlags.isEnabled()) {
-                anyExpansion.map { it > 0f }.distinctUntilChanged()
-            } else {
-                repository.legacyExpandedOrAwaitingInputTransfer
-            }
-            .stateIn(scope, SharingStarted.Eagerly, false)
+            anyExpansion.map { it > 0f }.distinctUntilChanged()
+        } else {
+            repository.legacyExpandedOrAwaitingInputTransfer
+        }
 
     /**
      * Whether the user is expanding or collapsing the shade with user input. This will be true even
@@ -185,7 +184,7 @@
      * but a transition they initiated is still animating.
      */
     val isUserInteracting: Flow<Boolean> =
-        combine(isUserInteractingWithShade, isUserInteractingWithQs) { shade, qs -> shade || qs }
+        combine(isUserInteractingWithShade, isUserInteractingWithShade) { shade, qs -> shade || qs }
             .distinctUntilChanged()
 
     /** Are touches allowed on the notification panel? */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
index 77b0958..7d81e55 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
@@ -16,7 +16,9 @@
 
 package com.android.systemui.statusbar;
 
+import android.animation.Animator;
 import android.view.View;
+import android.view.ViewPropertyAnimator;
 
 import androidx.annotation.Nullable;
 
@@ -31,30 +33,35 @@
     public static final long ANIMATION_DURATION_LENGTH = 210;
 
     public static void fadeOut(final View view) {
-        fadeOut(view, null);
+        fadeOut(view, (Runnable) null);
     }
 
     public static void fadeOut(final View view, final Runnable endRunnable) {
         fadeOut(view, ANIMATION_DURATION_LENGTH, 0, endRunnable);
     }
 
+    public static void fadeOut(final View view, final Animator.AnimatorListener listener) {
+        fadeOut(view, ANIMATION_DURATION_LENGTH, 0, listener);
+    }
+
+    public static void fadeOut(final View view, long duration, int delay) {
+        fadeOut(view, duration, delay, (Runnable) null);
+    }
+
     public static void fadeOut(final View view, long duration, int delay,
-            final Runnable endRunnable) {
+            @Nullable final Runnable endRunnable) {
         view.animate().cancel();
         view.animate()
                 .alpha(0f)
                 .setDuration(duration)
                 .setInterpolator(Interpolators.ALPHA_OUT)
                 .setStartDelay(delay)
-                .withEndAction(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (endRunnable != null) {
-                            endRunnable.run();
-                        }
-                        if (view.getVisibility() != View.GONE) {
-                            view.setVisibility(View.INVISIBLE);
-                        }
+                .withEndAction(() -> {
+                    if (endRunnable != null) {
+                        endRunnable.run();
+                    }
+                    if (view.getVisibility() != View.GONE) {
+                        view.setVisibility(View.INVISIBLE);
                     }
                 });
         if (view.hasOverlappingRendering()) {
@@ -62,6 +69,27 @@
         }
     }
 
+    public static void fadeOut(final View view, long duration, int delay,
+            @Nullable final Animator.AnimatorListener listener) {
+        view.animate().cancel();
+        ViewPropertyAnimator animator = view.animate()
+                .alpha(0f)
+                .setDuration(duration)
+                .setInterpolator(Interpolators.ALPHA_OUT)
+                .setStartDelay(delay)
+                .withEndAction(() -> {
+                    if (view.getVisibility() != View.GONE) {
+                        view.setVisibility(View.INVISIBLE);
+                    }
+                });
+        if (listener != null) {
+            animator.setListener(listener);
+        }
+        if (view.hasOverlappingRendering()) {
+            view.animate().withLayer();
+        }
+    }
+
     public static void fadeOut(View view, float fadeOutAmount) {
         fadeOut(view, fadeOutAmount, true /* remap */);
     }
@@ -119,8 +147,12 @@
         fadeIn(view, ANIMATION_DURATION_LENGTH, /* delay= */ 0, endRunnable);
     }
 
+    public static void fadeIn(final View view, Animator.AnimatorListener listener) {
+        fadeIn(view, ANIMATION_DURATION_LENGTH, /* delay= */ 0, listener);
+    }
+
     public static void fadeIn(final View view, long duration, int delay) {
-        fadeIn(view, duration, delay, /* endRunnable= */ null);
+        fadeIn(view, duration, delay, /* endRunnable= */ (Runnable) null);
     }
 
     public static void fadeIn(final View view, long duration, int delay,
@@ -141,6 +173,26 @@
         }
     }
 
+    public static void fadeIn(final View view, long duration, int delay,
+            @Nullable Animator.AnimatorListener listener) {
+        view.animate().cancel();
+        if (view.getVisibility() == View.INVISIBLE) {
+            view.setAlpha(0.0f);
+            view.setVisibility(View.VISIBLE);
+        }
+        ViewPropertyAnimator animator = view.animate()
+                .alpha(1f)
+                .setDuration(duration)
+                .setStartDelay(delay)
+                .setInterpolator(Interpolators.ALPHA_IN);
+        if (listener != null) {
+            animator.setListener(listener);
+        }
+        if (view.hasOverlappingRendering() && view.getLayerType() != View.LAYER_TYPE_HARDWARE) {
+            view.animate().withLayer();
+        }
+    }
+
     public static void fadeIn(View view, float fadeInAmount) {
         fadeIn(view, fadeInAmount, false /* remap */);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
index ff4570e..2e1e395 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
@@ -29,8 +29,11 @@
 
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.flags.FeatureFlagsClassic;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.statusbar.dagger.CentralSurfacesModule;
+import com.android.systemui.statusbar.domain.interactor.SilentNotificationStatusIconsVisibilityInteractor;
 import com.android.systemui.statusbar.notification.collection.NotifCollection;
 import com.android.systemui.statusbar.notification.collection.PipelineDumpable;
 import com.android.systemui.statusbar.notification.collection.PipelineDumper;
@@ -59,7 +62,9 @@
     private static final long MAX_RANKING_DELAY_MILLIS = 500L;
 
     private final Context mContext;
+    private final FeatureFlagsClassic mFeatureFlags;
     private final NotificationManager mNotificationManager;
+    private final SilentNotificationStatusIconsVisibilityInteractor mStatusIconInteractor;
     private final SystemClock mSystemClock;
     private final Executor mMainExecutor;
     private final List<NotificationHandler> mNotificationHandlers = new ArrayList<>();
@@ -75,13 +80,17 @@
     @Inject
     public NotificationListener(
             Context context,
+            FeatureFlagsClassic featureFlags,
             NotificationManager notificationManager,
+            SilentNotificationStatusIconsVisibilityInteractor statusIconInteractor,
             SystemClock systemClock,
             @Main Executor mainExecutor,
             PluginManager pluginManager) {
         super(pluginManager);
         mContext = context;
+        mFeatureFlags = featureFlags;
         mNotificationManager = notificationManager;
+        mStatusIconInteractor = statusIconInteractor;
         mSystemClock = systemClock;
         mMainExecutor = mainExecutor;
     }
@@ -95,6 +104,7 @@
     }
 
     /** Registers a listener that's notified when any notification-related settings change. */
+    @Deprecated
     public void addNotificationSettingsListener(NotificationSettingsListener listener) {
         mSettingsListeners.add(listener);
     }
@@ -230,8 +240,12 @@
 
     @Override
     public void onSilentStatusBarIconsVisibilityChanged(boolean hideSilentStatusIcons) {
-        for (NotificationSettingsListener listener : mSettingsListeners) {
-            listener.onStatusBarIconsBehaviorChanged(hideSilentStatusIcons);
+        if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_ICON_CONTAINER_REFACTOR)) {
+            mStatusIconInteractor.setHideSilentStatusIcons(hideSilentStatusIcons);
+        } else {
+            for (NotificationSettingsListener listener : mSettingsListeners) {
+                listener.onStatusBarIconsBehaviorChanged(hideSilentStatusIcons);
+            }
         }
     }
 
@@ -294,6 +308,7 @@
         return ranking;
     }
 
+    @Deprecated
     public interface NotificationSettingsListener {
 
         default void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) { }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index f7dc261..61ebcc0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -48,12 +48,11 @@
 
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.CoreStartable;
 import com.android.systemui.Dumpable;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.power.domain.interactor.PowerInteractor;
 import com.android.systemui.res.R;
-import com.android.systemui.shade.domain.interactor.ShadeInteractor;
 import com.android.systemui.statusbar.dagger.CentralSurfacesDependenciesModule;
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.RemoteInputControllerLogger;
@@ -66,7 +65,6 @@
 import com.android.systemui.statusbar.policy.RemoteInputView;
 import com.android.systemui.util.DumpUtilsKt;
 import com.android.systemui.util.ListenerSet;
-import com.android.systemui.util.kotlin.JavaAdapter;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -80,7 +78,7 @@
  * interaction, keeping track of notifications to remove when NotificationPresenter is collapsed,
  * and handling clicks on remote views.
  */
-public class NotificationRemoteInputManager implements CoreStartable {
+public class NotificationRemoteInputManager implements Dumpable {
     public static final boolean ENABLE_REMOTE_INPUT =
             SystemProperties.getBoolean("debug.enable_remote_input", true);
     public static boolean FORCE_REMOTE_INPUT_HISTORY =
@@ -96,8 +94,6 @@
     private final NotificationVisibilityProvider mVisibilityProvider;
     private final PowerInteractor mPowerInteractor;
     private final ActionClickLogger mLogger;
-    private final JavaAdapter mJavaAdapter;
-    private final ShadeInteractor mShadeInteractor;
     protected final Context mContext;
     protected final NotifPipelineFlags mNotifPipelineFlags;
     private final UserManager mUserManager;
@@ -265,8 +261,7 @@
             RemoteInputControllerLogger remoteInputControllerLogger,
             NotificationClickNotifier clickNotifier,
             ActionClickLogger logger,
-            JavaAdapter javaAdapter,
-            ShadeInteractor shadeInteractor) {
+            DumpManager dumpManager) {
         mContext = context;
         mNotifPipelineFlags = notifPipelineFlags;
         mLockscreenUserManager = lockscreenUserManager;
@@ -274,8 +269,6 @@
         mVisibilityProvider = visibilityProvider;
         mPowerInteractor = powerInteractor;
         mLogger = logger;
-        mJavaAdapter = javaAdapter;
-        mShadeInteractor = shadeInteractor;
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
@@ -284,25 +277,8 @@
         mRemoteInputUriController = remoteInputUriController;
         mRemoteInputControllerLogger = remoteInputControllerLogger;
         mClickNotifier = clickNotifier;
-    }
 
-    @Override
-    public void start() {
-        mJavaAdapter.alwaysCollectFlow(mShadeInteractor.isAnyExpanded(),
-                this::onShadeOrQsExpanded);
-    }
-
-    private void onShadeOrQsExpanded(boolean expanded) {
-        if (expanded && mStatusBarStateController.getState() != StatusBarState.KEYGUARD) {
-            try {
-                mBarService.clearNotificationEffects();
-            } catch (RemoteException e) {
-                // Won't fail unless the world has ended.
-            }
-        }
-        if (!expanded) {
-            onPanelCollapsed();
-        }
+        dumpManager.registerDumpable(this);
     }
 
     /** Add a listener for various remote input events.  Works with NEW pipeline only. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index 537f8a8..37a4ef1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -42,16 +42,15 @@
 import com.android.internal.logging.UiEventLogger;
 import com.android.keyguard.KeyguardClockSwitch;
 import com.android.systemui.DejankUtils;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
+import com.android.systemui.Dumpable;
 import com.android.systemui.res.R;
-import com.android.systemui.shade.domain.interactor.ShadeInteractor;
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dump.DumpManager;
+import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
+import com.android.systemui.shade.ShadeExpansionStateManager;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 import com.android.systemui.statusbar.policy.CallbackController;
 import com.android.systemui.util.Compile;
-import com.android.systemui.util.kotlin.JavaAdapter;
-
-import dagger.Lazy;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -65,7 +64,8 @@
 @SysUISingleton
 public class StatusBarStateControllerImpl implements
         SysuiStatusBarStateController,
-        CallbackController<StateListener> {
+        CallbackController<StateListener>,
+        Dumpable {
     private static final String TAG = "SbStateController";
     private static final boolean DEBUG_IMMERSIVE_APPS =
             SystemProperties.getBoolean("persist.debug.immersive_apps", false);
@@ -95,8 +95,6 @@
     private final ArrayList<RankedListener> mListeners = new ArrayList<>();
     private final UiEventLogger mUiEventLogger;
     private final InteractionJankMonitor mInteractionJankMonitor;
-    private final JavaAdapter mJavaAdapter;
-    private final Lazy<ShadeInteractor> mShadeInteractorLazy;
     private int mState;
     private int mLastState;
     private int mUpcomingState;
@@ -158,22 +156,18 @@
     @Inject
     public StatusBarStateControllerImpl(
             UiEventLogger uiEventLogger,
+            DumpManager dumpManager,
             InteractionJankMonitor interactionJankMonitor,
-            JavaAdapter javaAdapter,
-            Lazy<ShadeInteractor> shadeInteractorLazy) {
+            ShadeExpansionStateManager shadeExpansionStateManager
+    ) {
         mUiEventLogger = uiEventLogger;
         mInteractionJankMonitor = interactionJankMonitor;
-        mJavaAdapter = javaAdapter;
-        mShadeInteractorLazy = shadeInteractorLazy;
         for (int i = 0; i < HISTORY_SIZE; i++) {
             mHistoricalRecords[i] = new HistoricalState();
         }
-    }
+        shadeExpansionStateManager.addFullExpansionListener(this::onShadeExpansionFullyChanged);
 
-    @Override
-    public void start() {
-        mJavaAdapter.alwaysCollectFlow(mShadeInteractorLazy.get().isAnyExpanded(),
-                this::onShadeOrQsExpanded);
+        dumpManager.registerDumpable(this);
     }
 
     @Override
@@ -351,7 +345,7 @@
         }
     }
 
-    private void onShadeOrQsExpanded(Boolean isExpanded) {
+    private void onShadeExpansionFullyChanged(Boolean isExpanded) {
         if (mIsExpanded != isExpanded) {
             mIsExpanded = isExpanded;
             String tag = getClass().getSimpleName() + "#setIsExpanded";
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
index 8104755..aa32d5c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
@@ -21,7 +21,6 @@
 import android.annotation.IntDef;
 import android.view.View;
 
-import com.android.systemui.CoreStartable;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 
@@ -30,7 +29,7 @@
 /**
  * Sends updates to {@link StateListener}s about changes to the status bar state and dozing state
  */
-public interface SysuiStatusBarStateController extends StatusBarStateController, CoreStartable {
+public interface SysuiStatusBarStateController extends StatusBarStateController {
 
     // TODO: b/115739177 (remove this explicit ordering if we can)
     @Retention(SOURCE)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
index 1484f9a..1fe6b83 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
@@ -23,7 +23,6 @@
 
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.statusbar.IStatusBarService;
-import com.android.systemui.CoreStartable;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.animation.AnimationFeatureFlags;
 import com.android.systemui.animation.DialogLaunchAnimator;
@@ -40,7 +39,6 @@
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shade.ShadeSurface;
 import com.android.systemui.shade.carrier.ShadeCarrierGroupController;
-import com.android.systemui.shade.domain.interactor.ShadeInteractor;
 import com.android.systemui.statusbar.ActionClickLogger;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationClickNotifier;
@@ -66,14 +64,11 @@
 import com.android.systemui.statusbar.phone.StatusBarRemoteInputCallback;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.RemoteInputUriController;
-import com.android.systemui.util.kotlin.JavaAdapter;
 
 import dagger.Binds;
 import dagger.Lazy;
 import dagger.Module;
 import dagger.Provides;
-import dagger.multibindings.ClassKey;
-import dagger.multibindings.IntoMap;
 
 /**
  * This module provides instances needed to construct {@link CentralSurfacesImpl}. These are moved to
@@ -84,6 +79,7 @@
 @Module(includes = {StatusBarNotificationPresenterModule.class})
 public interface CentralSurfacesDependenciesModule {
     /** */
+    @SysUISingleton
     @Provides
     static NotificationRemoteInputManager provideNotificationRemoteInputManager(
             Context context,
@@ -97,8 +93,7 @@
             RemoteInputControllerLogger remoteInputControllerLogger,
             NotificationClickNotifier clickNotifier,
             ActionClickLogger actionClickLogger,
-            JavaAdapter javaAdapter,
-            ShadeInteractor shadeInteractor) {
+            DumpManager dumpManager) {
         return new NotificationRemoteInputManager(
                 context,
                 notifPipelineFlags,
@@ -111,17 +106,10 @@
                 remoteInputControllerLogger,
                 clickNotifier,
                 actionClickLogger,
-                javaAdapter,
-                shadeInteractor);
+                dumpManager);
     }
 
     /** */
-    @Binds
-    @IntoMap
-    @ClassKey(NotificationRemoteInputManager.class)
-    CoreStartable bindsStartNotificationRemoteInputManager(NotificationRemoteInputManager nrim);
-
-    /** */
     @SysUISingleton
     @Provides
     static NotificationMediaManager provideNotificationMediaManager(
@@ -176,23 +164,20 @@
         return new CommandQueue(context, displayTracker, registry, dumpHandler, powerInteractor);
     }
 
-    /** */
+    /**
+     */
     @Binds
     ManagedProfileController provideManagedProfileController(
             ManagedProfileControllerImpl controllerImpl);
 
-    /** */
+    /**
+     */
     @Binds
     SysuiStatusBarStateController providesSysuiStatusBarStateController(
             StatusBarStateControllerImpl statusBarStateControllerImpl);
 
-    /** */
-    @Binds
-    @IntoMap
-    @ClassKey(SysuiStatusBarStateController.class)
-    CoreStartable bindsStartStatusBarStateController(StatusBarStateControllerImpl sbsc);
-
-    /** */
+    /**
+     */
     @Binds
     StatusBarIconController provideStatusBarIconController(
             StatusBarIconControllerImpl controllerImpl);
@@ -227,14 +212,16 @@
     ShadeCarrierGroupController.SlotIndexResolver provideSlotIndexResolver(
             ShadeCarrierGroupController.SubscriptionManagerSlotIndexResolver impl);
 
-    /** */
+    /**
+     */
     @Provides
     @SysUISingleton
     static ActivityLaunchAnimator provideActivityLaunchAnimator() {
         return new ActivityLaunchAnimator();
     }
 
-    /** */
+    /**
+     */
     @Provides
     @SysUISingleton
     static DialogLaunchAnimator provideDialogLaunchAnimator(IDreamManager dreamManager,
@@ -266,7 +253,8 @@
         return new DialogLaunchAnimator(callback, interactionJankMonitor, animationFeatureFlags);
     }
 
-    /** */
+    /**
+     */
     @Provides
     @SysUISingleton
     static AnimationFeatureFlags provideAnimationFeatureFlags(FeatureFlags featureFlags) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/NotificationListenerSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/NotificationListenerSettingsRepository.kt
new file mode 100644
index 0000000..2c706a5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/NotificationListenerSettingsRepository.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 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.systemui.statusbar.data.repository
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.NotificationListener
+import javax.inject.Inject
+import kotlinx.coroutines.flow.MutableStateFlow
+
+/** Exposes state pertaining to settings tracked over the [NotificationListener] boundary. */
+@SysUISingleton
+class NotificationListenerSettingsRepository @Inject constructor() {
+    /** Should icons for silent notifications be shown in the status bar? */
+    val showSilentStatusIcons = MutableStateFlow(true)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/SilentNotificationStatusIconsVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/SilentNotificationStatusIconsVisibilityInteractor.kt
new file mode 100644
index 0000000..1248b1c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/SilentNotificationStatusIconsVisibilityInteractor.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 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.systemui.statusbar.domain.interactor
+
+import com.android.systemui.statusbar.data.repository.NotificationListenerSettingsRepository
+import javax.inject.Inject
+
+class SilentNotificationStatusIconsVisibilityInteractor
+@Inject
+constructor(private val repository: NotificationListenerSettingsRepository) {
+    /** Set whether icons for silent notifications be hidden in the status bar. */
+    fun setHideSilentStatusIcons(hideIcons: Boolean) {
+        repository.showSilentStatusIcons.value = !hideIcons
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
index 756151b..96279e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
@@ -21,7 +21,7 @@
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.animation.LaunchAnimator
-import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository
+import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
 import com.android.systemui.statusbar.policy.HeadsUpManager
@@ -33,7 +33,7 @@
 
 /** A provider of [NotificationLaunchAnimatorController]. */
 class NotificationLaunchAnimatorControllerProvider(
-    private val notificationExpansionRepository: NotificationExpansionRepository,
+    private val notificationLaunchAnimationInteractor: NotificationLaunchAnimationInteractor,
     private val notificationListContainer: NotificationListContainer,
     private val headsUpManager: HeadsUpManager,
     private val jankMonitor: InteractionJankMonitor
@@ -44,7 +44,7 @@
         onFinishAnimationCallback: Runnable? = null
     ): NotificationLaunchAnimatorController {
         return NotificationLaunchAnimatorController(
-            notificationExpansionRepository,
+            notificationLaunchAnimationInteractor,
             notificationListContainer,
             headsUpManager,
             notification,
@@ -60,7 +60,7 @@
  * notification expanding into an opening window.
  */
 class NotificationLaunchAnimatorController(
-    private val notificationExpansionRepository: NotificationExpansionRepository,
+    private val notificationLaunchAnimationInteractor: NotificationLaunchAnimationInteractor,
     private val notificationListContainer: NotificationListContainer,
     private val headsUpManager: HeadsUpManager,
     private val notification: ExpandableNotificationRow,
@@ -143,7 +143,7 @@
         if (ActivityLaunchAnimator.DEBUG_LAUNCH_ANIMATION) {
             Log.d(TAG, "onIntentStarted(willAnimate=$willAnimate)")
         }
-        notificationExpansionRepository.setIsExpandAnimationRunning(willAnimate)
+        notificationLaunchAnimationInteractor.setIsLaunchAnimationRunning(willAnimate)
         notificationEntry.isExpandAnimationRunning = willAnimate
 
         if (!willAnimate) {
@@ -180,7 +180,7 @@
 
         // TODO(b/184121838): Should we call InteractionJankMonitor.cancel if the animation started
         // here?
-        notificationExpansionRepository.setIsExpandAnimationRunning(false)
+        notificationLaunchAnimationInteractor.setIsLaunchAnimationRunning(false)
         notificationEntry.isExpandAnimationRunning = false
         removeHun(animate = true)
         onFinishAnimationCallback?.run()
@@ -200,7 +200,7 @@
         jankMonitor.end(InteractionJankMonitor.CUJ_NOTIFICATION_APP_START)
 
         notification.isExpandAnimationRunning = false
-        notificationExpansionRepository.setIsExpandAnimationRunning(false)
+        notificationLaunchAnimationInteractor.setIsLaunchAnimationRunning(false)
         notificationEntry.isExpandAnimationRunning = false
         notificationListContainer.setExpandingNotification(null)
         applyParams(null)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
index e763797..7b3a93a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
@@ -225,7 +225,7 @@
 
     /** @see NotifPipeline#getEntry(String) () */
     @Nullable
-    NotificationEntry getEntry(@NonNull String key) {
+    public NotificationEntry getEntry(@NonNull String key) {
         return mNotificationSet.get(key);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt
index c2a021d..07e84bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt
@@ -52,9 +52,10 @@
     fun onAfterRenderList(entries: List<ListEntry>, controller: NotifStackController) =
         traceSection("StackCoordinator.onAfterRenderList") {
             controller.setNotifStats(calculateNotifStats(entries))
-            notificationIconAreaController.updateNotificationIcons(entries)
             if (featureFlags.isEnabled(Flags.NOTIFICATION_ICON_CONTAINER_REFACTOR)) {
                 renderListInteractor.setRenderedList(entries)
+            } else {
+                notificationIconAreaController.updateNotificationIcons(entries)
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 8561869..fa366c6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -54,7 +54,7 @@
 import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.data.NotificationDataLayerModule;
-import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository;
+import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor;
 import com.android.systemui.statusbar.notification.icon.ConversationIconManager;
 import com.android.systemui.statusbar.notification.icon.IconManager;
 import com.android.systemui.statusbar.notification.init.NotificationsController;
@@ -204,12 +204,12 @@
     @Provides
     @SysUISingleton
     static NotificationLaunchAnimatorControllerProvider provideNotifLaunchAnimControllerProvider(
-            NotificationExpansionRepository notificationExpansionRepository,
+            NotificationLaunchAnimationInteractor notificationLaunchAnimationInteractor,
             NotificationListContainer notificationListContainer,
             HeadsUpManager headsUpManager,
             InteractionJankMonitor jankMonitor) {
         return new NotificationLaunchAnimatorControllerProvider(
-                notificationExpansionRepository,
+                notificationLaunchAnimationInteractor,
                 notificationListContainer,
                 headsUpManager,
                 jankMonitor);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpNotificationIconViewStateRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpNotificationIconViewStateRepository.kt
new file mode 100644
index 0000000..afed6be
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpNotificationIconViewStateRepository.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 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.systemui.statusbar.notification.data.repository
+
+import android.graphics.Rect
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+import kotlinx.coroutines.flow.MutableStateFlow
+
+/** View-states pertaining to heads-up notification icons. */
+@SysUISingleton
+class HeadsUpNotificationIconViewStateRepository @Inject constructor() {
+    /** Notification key for a notification icon to show isolated, or `null` if none. */
+    val isolatedNotification = MutableStateFlow<String?>(null)
+    /** Area to display the isolated notification, or `null` if none. */
+    val isolatedIconLocation = MutableStateFlow<Rect?>(null)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/NotificationExpansionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/NotificationExpansionRepository.kt
deleted file mode 100644
index 6f0a97a..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/NotificationExpansionRepository.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2023 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.systemui.statusbar.notification.data.repository
-
-import android.util.Log
-import com.android.systemui.animation.ActivityLaunchAnimator
-import com.android.systemui.dagger.SysUISingleton
-import javax.inject.Inject
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.asStateFlow
-
-private const val TAG = "NotificationExpansionRepository"
-
-/** A repository tracking the status of notification expansion animations. */
-@SysUISingleton
-class NotificationExpansionRepository @Inject constructor() {
-    private val _isExpandAnimationRunning = MutableStateFlow(false)
-
-    /**
-     * Emits true if an animation that expands a notification object into an opening window is
-     * running and false otherwise.
-     *
-     * See [com.android.systemui.statusbar.notification.NotificationLaunchAnimatorController].
-     */
-    val isExpandAnimationRunning: Flow<Boolean> = _isExpandAnimationRunning.asStateFlow()
-
-    /** Sets whether the notification expansion animation is currently running. */
-    fun setIsExpandAnimationRunning(running: Boolean) {
-        if (ActivityLaunchAnimator.DEBUG_LAUNCH_ANIMATION) {
-            Log.d(TAG, "setIsExpandAnimationRunning(running=$running)")
-        }
-        _isExpandAnimationRunning.value = running
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/NotificationLaunchAnimationRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/NotificationLaunchAnimationRepository.kt
new file mode 100644
index 0000000..9b56299
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/NotificationLaunchAnimationRepository.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 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.systemui.statusbar.notification.data.repository
+
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+import kotlinx.coroutines.flow.MutableStateFlow
+
+/** A repository tracking the status of notification launch animations. */
+@SysUISingleton
+class NotificationLaunchAnimationRepository @Inject constructor() {
+    val isLaunchAnimationRunning = MutableStateFlow(false)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationIconInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationIconInteractor.kt
new file mode 100644
index 0000000..17b6e9f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationIconInteractor.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 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.systemui.statusbar.notification.domain.interactor
+
+import android.graphics.Rect
+import com.android.systemui.statusbar.notification.data.repository.HeadsUpNotificationIconViewStateRepository
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+
+/** Domain logic pertaining to heads up notification icons. */
+class HeadsUpNotificationIconInteractor
+@Inject
+constructor(
+    private val repository: HeadsUpNotificationIconViewStateRepository,
+) {
+    /** Notification key for a notification icon to show isolated, or `null` if none. */
+    val isolatedIconLocation: Flow<Rect?> = repository.isolatedIconLocation
+
+    /** Area to display the isolated notification, or `null` if none. */
+    val isolatedNotification: Flow<String?> = repository.isolatedNotification
+
+    /** Updates the location where isolated notification icons are shown. */
+    fun setIsolatedIconLocation(rect: Rect?) {
+        repository.isolatedIconLocation.value = rect
+    }
+
+    /** Updates which notification will have its icon displayed isolated. */
+    fun setIsolatedIconNotificationKey(key: String?) {
+        repository.isolatedNotification.value = key
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractor.kt
new file mode 100644
index 0000000..22ce4f1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractor.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 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.systemui.statusbar.notification.domain.interactor
+
+import android.util.Log
+import com.android.systemui.animation.ActivityLaunchAnimator
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.notification.data.repository.NotificationLaunchAnimationRepository
+import javax.inject.Inject
+import kotlinx.coroutines.flow.StateFlow
+
+/** A repository tracking the status of notification expansion animations. */
+@SysUISingleton
+class NotificationLaunchAnimationInteractor
+@Inject
+constructor(private val repository: NotificationLaunchAnimationRepository) {
+
+    /**
+     * Emits true if an animation that expands a notification object into an opening window is
+     * running and false otherwise.
+     *
+     * See [com.android.systemui.statusbar.notification.NotificationLaunchAnimatorController].
+     */
+    val isLaunchAnimationRunning: StateFlow<Boolean>
+        get() = repository.isLaunchAnimationRunning
+
+    /** Sets whether the notification expansion launch animation is currently running. */
+    fun setIsLaunchAnimationRunning(running: Boolean) {
+        if (ActivityLaunchAnimator.DEBUG_LAUNCH_ANIMATION) {
+            Log.d(TAG, "setIsLaunchAnimationRunning(running=$running)")
+        }
+        repository.isLaunchAnimationRunning.value = running
+    }
+
+    companion object {
+        private const val TAG = "NotificationLaunchAnimationInteractor"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
index c5396dd..604ecbc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
@@ -15,12 +15,16 @@
  */
 package com.android.systemui.statusbar.notification.domain.interactor
 
+import android.graphics.drawable.Icon
 import com.android.systemui.statusbar.notification.collection.ListEntry
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
 import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository
 import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
 import javax.inject.Inject
 import kotlinx.coroutines.flow.update
 
+private typealias ModelStore = Map<String, ActiveNotificationModel>
+
 /**
  * Logic for passing information from the
  * [com.android.systemui.statusbar.notification.collection.NotifPipeline] to the presentation
@@ -30,6 +34,7 @@
 @Inject
 constructor(
     private val repository: ActiveNotificationListRepository,
+    private val sectionStyleProvider: SectionStyleProvider,
 ) {
     /**
      * Sets the current list of rendered notification entries as displayed in the notification
@@ -38,21 +43,100 @@
      * @see com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository.activeNotifications
      */
     fun setRenderedList(entries: List<ListEntry>) {
-        repository.activeNotifications.update { modelsByKey ->
+        repository.activeNotifications.update { existingModels ->
             entries.associateBy(
                 keySelector = { it.key },
-                valueTransform = { it.toModel(modelsByKey[it.key]) }
+                valueTransform = { it.toModel(existingModels) },
             )
         }
     }
 
-    private fun ListEntry.toModel(existing: ActiveNotificationModel?): ActiveNotificationModel {
-        val isCurrent =
-            when {
-                existing == null -> false
-                key == existing.key -> true
-                else -> false
-            }
-        return if (isCurrent) existing!! else ActiveNotificationModel(key = key)
+    private fun ListEntry.toModel(
+        existingModels: ModelStore,
+    ): ActiveNotificationModel =
+        existingModels.createOrReuse(
+            key = key,
+            groupKey = representativeEntry?.sbn?.groupKey,
+            isAmbient = sectionStyleProvider.isMinimized(this),
+            isRowDismissed = representativeEntry?.isRowDismissed == true,
+            isSilent = sectionStyleProvider.isSilent(this),
+            isLastMessageFromReply = representativeEntry?.isLastMessageFromReply == true,
+            isSuppressedFromStatusBar = representativeEntry?.shouldSuppressStatusBar() == true,
+            isPulsing = representativeEntry?.showingPulsing() == true,
+            aodIcon = representativeEntry?.icons?.aodIcon?.sourceIcon,
+            shelfIcon = representativeEntry?.icons?.shelfIcon?.sourceIcon,
+            statusBarIcon = representativeEntry?.icons?.statusBarIcon?.sourceIcon,
+        )
+
+    private fun ModelStore.createOrReuse(
+        key: String,
+        groupKey: String?,
+        isAmbient: Boolean,
+        isRowDismissed: Boolean,
+        isSilent: Boolean,
+        isLastMessageFromReply: Boolean,
+        isSuppressedFromStatusBar: Boolean,
+        isPulsing: Boolean,
+        aodIcon: Icon?,
+        shelfIcon: Icon?,
+        statusBarIcon: Icon?
+    ): ActiveNotificationModel {
+        return this[key]?.takeIf {
+            it.isCurrent(
+                key = key,
+                groupKey = groupKey,
+                isAmbient = isAmbient,
+                isRowDismissed = isRowDismissed,
+                isSilent = isSilent,
+                isLastMessageFromReply = isLastMessageFromReply,
+                isSuppressedFromStatusBar = isSuppressedFromStatusBar,
+                isPulsing = isPulsing,
+                aodIcon = aodIcon,
+                shelfIcon = shelfIcon,
+                statusBarIcon = statusBarIcon
+            )
+        }
+            ?: ActiveNotificationModel(
+                key = key,
+                groupKey = groupKey,
+                isAmbient = isAmbient,
+                isRowDismissed = isRowDismissed,
+                isSilent = isSilent,
+                isLastMessageFromReply = isLastMessageFromReply,
+                isSuppressedFromStatusBar = isSuppressedFromStatusBar,
+                isPulsing = isPulsing,
+                aodIcon = aodIcon,
+                shelfIcon = shelfIcon,
+                statusBarIcon = statusBarIcon,
+            )
+    }
+
+    private fun ActiveNotificationModel.isCurrent(
+        key: String,
+        groupKey: String?,
+        isAmbient: Boolean,
+        isRowDismissed: Boolean,
+        isSilent: Boolean,
+        isLastMessageFromReply: Boolean,
+        isSuppressedFromStatusBar: Boolean,
+        isPulsing: Boolean,
+        aodIcon: Icon?,
+        shelfIcon: Icon?,
+        statusBarIcon: Icon?
+    ): Boolean {
+        return when {
+            key != this.key -> false
+            groupKey != this.groupKey -> false
+            isAmbient != this.isAmbient -> false
+            isRowDismissed != this.isRowDismissed -> false
+            isSilent != this.isSilent -> false
+            isLastMessageFromReply != this.isLastMessageFromReply -> false
+            isSuppressedFromStatusBar != this.isSuppressedFromStatusBar -> false
+            isPulsing != this.isPulsing -> false
+            aodIcon != this.aodIcon -> false
+            shelfIcon != this.shelfIcon -> false
+            statusBarIcon != this.statusBarIcon -> false
+            else -> true
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/SeenNotificationsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/SeenNotificationsInteractor.kt
index f3e122c..1f7ab96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/SeenNotificationsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/SeenNotificationsInteractor.kt
@@ -32,6 +32,7 @@
     val hasFilteredOutSeenNotifications: StateFlow<Boolean> =
         notificationListRepository.hasFilteredOutSeenNotifications
 
+    /** Set whether already-seen notifications are currently filtered out of the shade. */
     fun setHasFilteredOutSeenNotifications(value: Boolean) {
         notificationListRepository.hasFilteredOutSeenNotifications.value = value
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java
index e74b3fc..ba91654 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java
@@ -19,6 +19,9 @@
 import static android.graphics.PorterDuff.Mode.SRC_ATOP;
 
 import android.annotation.ColorInt;
+import android.annotation.DrawableRes;
+import android.annotation.StringRes;
+import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
@@ -35,6 +38,7 @@
 
 import com.android.settingslib.Utils;
 import com.android.systemui.res.R;
+import com.android.systemui.statusbar.notification.footer.shared.FooterViewRefactor;
 import com.android.systemui.statusbar.notification.row.FooterViewButton;
 import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
@@ -44,6 +48,8 @@
 import java.io.PrintWriter;
 
 public class FooterView extends StackScrollerDecorView {
+    private static final String TAG = "FooterView";
+
     private FooterViewButton mClearAllButton;
     private FooterViewButton mManageButton;
     private boolean mShowHistory;
@@ -57,6 +63,9 @@
     private String mSeenNotifsFilteredText;
     private Drawable mSeenNotifsFilteredIcon;
 
+    private @StringRes int mMessageStringId;
+    private @DrawableRes int mMessageIconId;
+
     public FooterView(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
@@ -84,6 +93,50 @@
         });
     }
 
+    /** Set the string for a message to be shown instead of the buttons. */
+    public void setMessageString(@StringRes int messageId) {
+        if (FooterViewRefactor.isUnexpectedlyInLegacyMode()) return;
+        if (mMessageStringId == messageId) {
+            return; // nothing changed
+        }
+        mMessageStringId = messageId;
+        updateMessageString();
+    }
+
+    private void updateMessageString() {
+        if (mMessageStringId == 0) {
+            return; // not initialized yet
+        }
+        String messageString = getContext().getString(mMessageStringId);
+        mSeenNotifsFooterTextView.setText(messageString);
+    }
+
+
+    /** Set the icon to be shown before the message (see {@link #setMessageString(int)}). */
+    public void setMessageIcon(@DrawableRes int iconId) {
+        if (FooterViewRefactor.isUnexpectedlyInLegacyMode()) return;
+        if (mMessageIconId == iconId) {
+            return; // nothing changed
+        }
+        mMessageIconId = iconId;
+        updateMessageIcon();
+    }
+
+    private void updateMessageIcon() {
+        if (mMessageIconId == 0) {
+            return; // not initialized yet
+        }
+        int unlockIconSize = getResources()
+                .getDimensionPixelSize(R.dimen.notifications_unseen_footer_icon_size);
+        @SuppressLint("UseCompatLoadingForDrawables")
+        Drawable messageIcon = getContext().getDrawable(mMessageIconId);
+        if (messageIcon != null) {
+            messageIcon.setBounds(0, 0, unlockIconSize, unlockIconSize);
+            mSeenNotifsFooterTextView
+                    .setCompoundDrawablesRelative(messageIcon, null, null, null);
+        }
+    }
+
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
@@ -148,9 +201,11 @@
             mManageButton.setText(mManageNotificationText);
             mManageButton.setContentDescription(mManageNotificationText);
         }
-        mSeenNotifsFooterTextView.setText(mSeenNotifsFilteredText);
-        mSeenNotifsFooterTextView
-                .setCompoundDrawablesRelative(mSeenNotifsFilteredIcon, null, null, null);
+        if (!FooterViewRefactor.isEnabled()) {
+            mSeenNotifsFooterTextView.setText(mSeenNotifsFilteredText);
+            mSeenNotifsFooterTextView
+                    .setCompoundDrawablesRelative(mSeenNotifsFilteredIcon, null, null, null);
+        }
     }
 
     /** Whether the start button shows "History" (true) or "Manage" (false). */
@@ -167,6 +222,11 @@
                 mContext.getString(R.string.accessibility_clear_all));
         updateResources();
         updateContent();
+
+        if (FooterViewRefactor.isEnabled()) {
+            updateMessageString();
+            updateMessageIcon();
+        }
     }
 
     /**
@@ -200,11 +260,13 @@
         mManageNotificationText = getContext().getString(R.string.manage_notifications_text);
         mManageNotificationHistoryText = getContext()
                 .getString(R.string.manage_notifications_history_text);
-        int unlockIconSize = getResources()
-                .getDimensionPixelSize(R.dimen.notifications_unseen_footer_icon_size);
-        mSeenNotifsFilteredText = getContext().getString(R.string.unlock_to_see_notif_text);
-        mSeenNotifsFilteredIcon = getContext().getDrawable(R.drawable.ic_friction_lock_closed);
-        mSeenNotifsFilteredIcon.setBounds(0, 0, unlockIconSize, unlockIconSize);
+        if (!FooterViewRefactor.isEnabled()) {
+            int unlockIconSize = getResources()
+                    .getDimensionPixelSize(R.dimen.notifications_unseen_footer_icon_size);
+            mSeenNotifsFilteredText = getContext().getString(R.string.unlock_to_see_notif_text);
+            mSeenNotifsFilteredIcon = getContext().getDrawable(R.drawable.ic_friction_lock_closed);
+            mSeenNotifsFilteredIcon.setBounds(0, 0, unlockIconSize, unlockIconSize);
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewbinder/FooterViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewbinder/FooterViewBinder.kt
new file mode 100644
index 0000000..6d823437
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewbinder/FooterViewBinder.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 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.systemui.statusbar.notification.footer.ui.viewbinder
+
+import androidx.lifecycle.lifecycleScope
+import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.statusbar.notification.footer.ui.view.FooterView
+import com.android.systemui.statusbar.notification.footer.ui.viewmodel.FooterViewModel
+import kotlinx.coroutines.DisposableHandle
+import kotlinx.coroutines.launch
+
+/** Binds a [FooterView] to its [view model][FooterViewModel]. */
+object FooterViewBinder {
+    fun bind(
+        footer: FooterView,
+        viewModel: FooterViewModel,
+    ): DisposableHandle {
+        return footer.repeatWhenAttached {
+            // Listen for changes when the view is attached.
+            lifecycleScope.launch {
+                viewModel.message.collect { message ->
+                    footer.setFooterLabelVisible(message.visible)
+                    footer.setMessageString(message.messageId)
+                    footer.setMessageIcon(message.iconId)
+                }
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterMessageViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterMessageViewModel.kt
new file mode 100644
index 0000000..bc912fb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterMessageViewModel.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 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.systemui.statusbar.notification.footer.ui.viewmodel
+
+import android.annotation.DrawableRes
+import android.annotation.StringRes
+
+/** A ViewModel for the string message that can be shown in the footer. */
+data class FooterMessageViewModel(
+    @StringRes val messageId: Int,
+    @DrawableRes val iconId: Int,
+    val visible: Boolean,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModel.kt
new file mode 100644
index 0000000..ffa5ff0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModel.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 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.systemui.statusbar.notification.footer.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.notification.domain.interactor.SeenNotificationsInteractor
+import com.android.systemui.statusbar.notification.footer.shared.FooterViewRefactor
+import com.android.systemui.statusbar.notification.footer.ui.view.FooterView
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
+
+/** ViewModel for [FooterView]. */
+@SysUISingleton
+class FooterViewModel
+@Inject
+constructor(seenNotificationsInteractor: SeenNotificationsInteractor) {
+    init {
+        /* Check if */ FooterViewRefactor.isUnexpectedlyInLegacyMode()
+    }
+
+    val message: Flow<FooterMessageViewModel> =
+        seenNotificationsInteractor.hasFilteredOutSeenNotifications.map { hasFilteredOutNotifs ->
+            FooterMessageViewModel(
+                messageId = R.string.unlock_to_see_notif_text,
+                iconId = R.drawable.ic_friction_lock_closed,
+                visible = hasFilteredOutNotifs,
+            )
+        }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractor.kt
new file mode 100644
index 0000000..00d873e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractor.kt
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2023 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.
+ *
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.statusbar.notification.icon.domain.interactor
+
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
+import com.android.systemui.statusbar.data.repository.NotificationListenerSettingsRepository
+import com.android.systemui.statusbar.notification.data.repository.NotificationsKeyguardViewStateRepository
+import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
+import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
+import com.android.wm.shell.bubbles.Bubbles
+import java.util.Optional
+import javax.inject.Inject
+import kotlin.jvm.optionals.getOrNull
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flatMapLatest
+
+/** Domain logic related to notification icons. */
+class NotificationIconsInteractor
+@Inject
+constructor(
+    private val activeNotificationsInteractor: ActiveNotificationsInteractor,
+    private val bubbles: Optional<Bubbles>,
+    private val keyguardViewStateRepository: NotificationsKeyguardViewStateRepository,
+) {
+    /** Returns a subset of all active notifications based on the supplied filtration parameters. */
+    fun filteredNotifSet(
+        showAmbient: Boolean = true,
+        showLowPriority: Boolean = true,
+        showDismissed: Boolean = true,
+        showRepliedMessages: Boolean = true,
+        showPulsing: Boolean = true,
+    ): Flow<Set<ActiveNotificationModel>> {
+        return combine(
+            activeNotificationsInteractor.notifications,
+            keyguardViewStateRepository.areNotificationsFullyHidden,
+        ) { notifications, notifsFullyHidden ->
+            notifications
+                .asSequence()
+                .filter { model: ActiveNotificationModel ->
+                    shouldShowNotificationIcon(
+                        model = model,
+                        showAmbient = showAmbient,
+                        showLowPriority = showLowPriority,
+                        showDismissed = showDismissed,
+                        showRepliedMessages = showRepliedMessages,
+                        showPulsing = showPulsing,
+                        notifsFullyHidden = notifsFullyHidden,
+                    )
+                }
+                .toSet()
+        }
+    }
+
+    private fun shouldShowNotificationIcon(
+        model: ActiveNotificationModel,
+        showAmbient: Boolean,
+        showLowPriority: Boolean,
+        showDismissed: Boolean,
+        showRepliedMessages: Boolean,
+        showPulsing: Boolean,
+        notifsFullyHidden: Boolean,
+    ): Boolean {
+        return when {
+            !showAmbient && model.isAmbient -> false
+            !showLowPriority && model.isSilent -> false
+            !showDismissed && model.isRowDismissed -> false
+            !showRepliedMessages && model.isLastMessageFromReply -> false
+            !showAmbient && model.isSuppressedFromStatusBar -> false
+            !showPulsing && model.isPulsing && !notifsFullyHidden -> false
+            bubbles.getOrNull()?.isBubbleExpanded(model.key) == true -> false
+            else -> true
+        }
+    }
+}
+
+/** Domain logic related to notification icons shown on the always-on display. */
+class AlwaysOnDisplayNotificationIconsInteractor
+@Inject
+constructor(
+    deviceEntryInteractor: DeviceEntryInteractor,
+    iconsInteractor: NotificationIconsInteractor,
+) {
+    val aodNotifs: Flow<Set<ActiveNotificationModel>> =
+        deviceEntryInteractor.isBypassEnabled.flatMapLatest { isBypassEnabled ->
+            iconsInteractor.filteredNotifSet(
+                showAmbient = false,
+                showDismissed = false,
+                showRepliedMessages = false,
+                showPulsing = !isBypassEnabled,
+            )
+        }
+}
+
+/** Domain logic related to notification icons shown in the status bar. */
+class StatusBarNotificationIconsInteractor
+@Inject
+constructor(
+    iconsInteractor: NotificationIconsInteractor,
+    settingsRepository: NotificationListenerSettingsRepository,
+) {
+    val statusBarNotifs: Flow<Set<ActiveNotificationModel>> =
+        settingsRepository.showSilentStatusIcons.flatMapLatest { showSilentIcons ->
+            iconsInteractor.filteredNotifSet(
+                showAmbient = false,
+                showLowPriority = showSilentIcons,
+                showDismissed = false,
+                showRepliedMessages = false,
+            )
+        }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt
index de011db..246933a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt
@@ -17,43 +17,23 @@
 
 import android.content.Context
 import android.graphics.Rect
-import android.os.Bundle
-import android.os.Trace
-import android.view.LayoutInflater
 import android.view.View
-import android.widget.FrameLayout
-import androidx.annotation.VisibleForTesting
-import androidx.collection.ArrayMap
-import com.android.internal.statusbar.StatusBarIcon
 import com.android.systemui.common.ui.ConfigurationState
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.demomode.DemoMode
-import com.android.systemui.demomode.DemoModeController
 import com.android.systemui.flags.FeatureFlagsClassic
 import com.android.systemui.flags.Flags
 import com.android.systemui.flags.RefactorFlag
-import com.android.systemui.res.R
-import com.android.systemui.statusbar.NotificationListener
-import com.android.systemui.statusbar.NotificationMediaManager
 import com.android.systemui.statusbar.NotificationShelfController
 import com.android.systemui.statusbar.StatusBarIconView
-import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
 import com.android.systemui.statusbar.notification.collection.ListEntry
-import com.android.systemui.statusbar.notification.collection.NotificationEntry
-import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
 import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel
 import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerShelfViewModel
-import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerStatusBarViewModel
 import com.android.systemui.statusbar.notification.shelf.ui.viewbinder.NotificationShelfViewBinderWrapperControllerImpl
 import com.android.systemui.statusbar.phone.DozeParameters
-import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.phone.NotificationIconAreaController
 import com.android.systemui.statusbar.phone.NotificationIconContainer
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController
-import com.android.systemui.statusbar.window.StatusBarWindowController
-import com.android.wm.shell.bubbles.Bubbles
-import java.util.Optional
-import java.util.function.Function
+import com.android.systemui.statusbar.policy.ConfigurationController
 import javax.inject.Inject
 import kotlinx.coroutines.DisposableHandle
 
@@ -68,57 +48,22 @@
 class NotificationIconAreaControllerViewBinderWrapperImpl
 @Inject
 constructor(
-    private val context: Context,
     private val configuration: ConfigurationState,
-    private val wakeUpCoordinator: NotificationWakeUpCoordinator,
-    private val bypassController: KeyguardBypassController,
-    private val mediaManager: NotificationMediaManager,
-    notificationListener: NotificationListener,
+    private val configurationController: ConfigurationController,
     private val dozeParameters: DozeParameters,
-    private val sectionStyleProvider: SectionStyleProvider,
-    private val bubblesOptional: Optional<Bubbles>,
-    demoModeController: DemoModeController,
     private val featureFlags: FeatureFlagsClassic,
-    private val statusBarWindowController: StatusBarWindowController,
     private val screenOffAnimationController: ScreenOffAnimationController,
+    private val shelfIconViewStore: ShelfNotificationIconViewStore,
     private val shelfIconsViewModel: NotificationIconContainerShelfViewModel,
-    private val statusBarIconsViewModel: NotificationIconContainerStatusBarViewModel,
+    private val aodIconViewStore: AlwaysOnDisplayNotificationIconViewStore,
     private val aodIconsViewModel: NotificationIconContainerAlwaysOnDisplayViewModel,
-) : NotificationIconAreaController, NotificationWakeUpCoordinator.WakeUpListener, DemoMode {
+) : NotificationIconAreaController {
 
-    private val updateStatusBarIcons = Runnable { updateStatusBarIcons() }
     private val shelfRefactor = RefactorFlag(featureFlags, Flags.NOTIFICATION_SHELF_REFACTOR)
 
-    private var iconSize = 0
-    private var iconHPadding = 0
-    private var notificationEntries = listOf<ListEntry>()
-    private var notificationIconArea: View? = null
-    private var notificationIcons: NotificationIconContainer? = null
     private var shelfIcons: NotificationIconContainer? = null
     private var aodIcons: NotificationIconContainer? = null
     private var aodBindJob: DisposableHandle? = null
-    private var showLowPriority = true
-
-    @VisibleForTesting
-    val settingsListener: NotificationListener.NotificationSettingsListener =
-        object : NotificationListener.NotificationSettingsListener {
-            override fun onStatusBarIconsBehaviorChanged(hideSilentStatusIcons: Boolean) {
-                showLowPriority = !hideSilentStatusIcons
-                updateStatusBarIcons()
-            }
-        }
-
-    init {
-        wakeUpCoordinator.addListener(this)
-        demoModeController.addCallback(this)
-        notificationListener.addNotificationSettingsListener(settingsListener)
-        initializeNotificationAreaViews(context)
-    }
-
-    @VisibleForTesting
-    fun shouldShowLowPriorityIcons(): Boolean {
-        return showLowPriority
-    }
 
     /** Called by the Keyguard*ViewController whose view contains the aod icons. */
     override fun setupAodIcons(aodIcons: NotificationIconContainer) {
@@ -135,14 +80,12 @@
                 aodIcons,
                 aodIconsViewModel,
                 configuration,
+                configurationController,
                 dozeParameters,
                 featureFlags,
                 screenOffAnimationController,
+                aodIconViewStore,
             )
-        if (changed) {
-            updateAodNotificationIcons()
-        }
-        updateIconLayoutParams(context)
     }
 
     override fun setupShelf(notificationShelfController: NotificationShelfController) =
@@ -154,65 +97,30 @@
                 icons,
                 shelfIconsViewModel,
                 configuration,
+                configurationController,
                 dozeParameters,
                 featureFlags,
                 screenOffAnimationController,
+                shelfIconViewStore,
             )
             shelfIcons = icons
         }
     }
 
-    override fun onDensityOrFontScaleChanged(context: Context) {
-        updateIconLayoutParams(context)
-    }
+    override fun onDensityOrFontScaleChanged(context: Context) = unsupported
 
     /** Returns the view that represents the notification area. */
-    override fun getNotificationInnerAreaView(): View? {
-        return notificationIconArea
-    }
+    override fun getNotificationInnerAreaView(): View? = unsupported
 
     /** Updates the notifications with the given list of notifications to display. */
-    override fun updateNotificationIcons(entries: List<ListEntry>) {
-        notificationEntries = entries
-        updateNotificationIcons()
-    }
+    override fun updateNotificationIcons(entries: List<ListEntry>) = unsupported
 
-    private fun updateStatusBarIcons() {
-        updateIconsForLayout(
-            { entry: NotificationEntry -> entry.icons.statusBarIcon },
-            notificationIcons,
-            showAmbient = false /* showAmbient */,
-            showLowPriority = showLowPriority,
-            hideDismissed = true /* hideDismissed */,
-            hideRepliedMessages = true /* hideRepliedMessages */,
-            hideCurrentMedia = false /* hideCurrentMedia */,
-            hidePulsing = false /* hidePulsing */
-        )
-    }
+    override fun updateAodNotificationIcons() = unsupported
 
-    override fun updateAodNotificationIcons() {
-        if (aodIcons == null) {
-            return
-        }
-        updateIconsForLayout(
-            { entry: NotificationEntry -> entry.icons.aodIcon },
-            aodIcons,
-            showAmbient = false /* showAmbient */,
-            showLowPriority = true /* showLowPriority */,
-            hideDismissed = true /* hideDismissed */,
-            hideRepliedMessages = true /* hideRepliedMessages */,
-            hideCurrentMedia = true /* hideCurrentMedia */,
-            hidePulsing = bypassController.bypassEnabled /* hidePulsing */
-        )
-    }
+    override fun showIconIsolated(icon: StatusBarIconView?, animated: Boolean) = unsupported
 
-    override fun showIconIsolated(icon: StatusBarIconView?, animated: Boolean) {
-        notificationIcons!!.showIconIsolated(icon, animated)
-    }
-
-    override fun setIsolatedIconLocation(iconDrawingRect: Rect, requireStateUpdate: Boolean) {
-        notificationIcons!!.setIsolatedIconLocation(iconDrawingRect, requireStateUpdate)
-    }
+    override fun setIsolatedIconLocation(iconDrawingRect: Rect, requireStateUpdate: Boolean) =
+        unsupported
 
     override fun setAnimationsEnabled(enabled: Boolean) = unsupported
 
@@ -222,271 +130,6 @@
         return if (aodIcons == null) 0 else aodIcons!!.height
     }
 
-    override fun onFullyHiddenChanged(isFullyHidden: Boolean) {
-        updateAodNotificationIcons()
-    }
-
-    override fun demoCommands(): List<String> {
-        val commands = ArrayList<String>()
-        commands.add(DemoMode.COMMAND_NOTIFICATIONS)
-        return commands
-    }
-
-    override fun dispatchDemoCommand(command: String, args: Bundle) {
-        if (notificationIconArea != null) {
-            val visible = args.getString("visible")
-            val vis = if ("false" == visible) View.INVISIBLE else View.VISIBLE
-            notificationIconArea?.visibility = vis
-        }
-    }
-
-    override fun onDemoModeFinished() {
-        if (notificationIconArea != null) {
-            notificationIconArea?.visibility = View.VISIBLE
-        }
-    }
-
-    private fun inflateIconArea(inflater: LayoutInflater): View {
-        return inflater.inflate(R.layout.notification_icon_area, null)
-    }
-
-    /** Initializes the views that will represent the notification area. */
-    private fun initializeNotificationAreaViews(context: Context) {
-        reloadDimens(context)
-        val layoutInflater = LayoutInflater.from(context)
-        notificationIconArea = inflateIconArea(layoutInflater)
-        notificationIcons = notificationIconArea?.findViewById(R.id.notificationIcons)
-        NotificationIconContainerViewBinder.bind(
-            notificationIcons!!,
-            statusBarIconsViewModel,
-            configuration,
-            dozeParameters,
-            featureFlags,
-            screenOffAnimationController,
-        )
-    }
-
-    private fun updateIconLayoutParams(context: Context) {
-        reloadDimens(context)
-        val params = generateIconLayoutParams()
-        for (i in 0 until notificationIcons!!.childCount) {
-            val child = notificationIcons!!.getChildAt(i)
-            child.layoutParams = params
-        }
-        if (shelfIcons != null) {
-            for (i in 0 until shelfIcons!!.childCount) {
-                val child = shelfIcons!!.getChildAt(i)
-                child.layoutParams = params
-            }
-        }
-        if (aodIcons != null) {
-            for (i in 0 until aodIcons!!.childCount) {
-                val child = aodIcons!!.getChildAt(i)
-                child.layoutParams = params
-            }
-        }
-    }
-
-    private fun generateIconLayoutParams(): FrameLayout.LayoutParams {
-        return FrameLayout.LayoutParams(
-            iconSize + 2 * iconHPadding,
-            statusBarWindowController.statusBarHeight
-        )
-    }
-
-    private fun reloadDimens(context: Context) {
-        val res = context.resources
-        iconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size_sp)
-        iconHPadding = res.getDimensionPixelSize(R.dimen.status_bar_icon_horizontal_margin)
-    }
-
-    private fun shouldShowNotificationIcon(
-        entry: NotificationEntry,
-        showAmbient: Boolean,
-        showLowPriority: Boolean,
-        hideDismissed: Boolean,
-        hideRepliedMessages: Boolean,
-        hideCurrentMedia: Boolean,
-        hidePulsing: Boolean
-    ): Boolean {
-        if (!showAmbient && sectionStyleProvider.isMinimized(entry)) {
-            return false
-        }
-        if (hideCurrentMedia && entry.key == mediaManager.mediaNotificationKey) {
-            return false
-        }
-        if (!showLowPriority && sectionStyleProvider.isSilent(entry)) {
-            return false
-        }
-        if (entry.isRowDismissed && hideDismissed) {
-            return false
-        }
-        if (hideRepliedMessages && entry.isLastMessageFromReply) {
-            return false
-        }
-        // showAmbient == show in shade but not shelf
-        if (!showAmbient && entry.shouldSuppressStatusBar()) {
-            return false
-        }
-        if (
-            hidePulsing &&
-                entry.showingPulsing() &&
-                (!wakeUpCoordinator.notificationsFullyHidden || !entry.isPulseSuppressed)
-        ) {
-            return false
-        }
-        return if (bubblesOptional.isPresent && bubblesOptional.get().isBubbleExpanded(entry.key)) {
-            false
-        } else true
-    }
-
-    private fun updateNotificationIcons() {
-        Trace.beginSection("NotificationIconAreaController.updateNotificationIcons")
-        updateStatusBarIcons()
-        updateShelfIcons()
-        updateAodNotificationIcons()
-        Trace.endSection()
-    }
-
-    private fun updateShelfIcons() {
-        if (shelfIcons == null) {
-            return
-        }
-        updateIconsForLayout(
-            { entry: NotificationEntry -> entry.icons.shelfIcon },
-            shelfIcons,
-            showAmbient = true,
-            showLowPriority = true,
-            hideDismissed = false,
-            hideRepliedMessages = false,
-            hideCurrentMedia = false,
-            hidePulsing = false
-        )
-    }
-
-    /**
-     * Updates the notification icons for a host layout. This will ensure that the notification host
-     * layout will have the same icons like the ones in here.
-     *
-     * @param function A function to look up an icon view based on an entry
-     * @param hostLayout which layout should be updated
-     * @param showAmbient should ambient notification icons be shown
-     * @param showLowPriority should icons from silent notifications be shown
-     * @param hideDismissed should dismissed icons be hidden
-     * @param hideRepliedMessages should messages that have been replied to be hidden
-     * @param hidePulsing should pulsing notifications be hidden
-     */
-    private fun updateIconsForLayout(
-        function: Function<NotificationEntry, StatusBarIconView?>,
-        hostLayout: NotificationIconContainer?,
-        showAmbient: Boolean,
-        showLowPriority: Boolean,
-        hideDismissed: Boolean,
-        hideRepliedMessages: Boolean,
-        hideCurrentMedia: Boolean,
-        hidePulsing: Boolean,
-    ) {
-        val toShow = ArrayList<StatusBarIconView>(notificationEntries.size)
-        // Filter out ambient notifications and notification children.
-        for (i in notificationEntries.indices) {
-            val entry = notificationEntries[i].representativeEntry
-            if (entry != null && entry.row != null) {
-                if (
-                    shouldShowNotificationIcon(
-                        entry,
-                        showAmbient,
-                        showLowPriority,
-                        hideDismissed,
-                        hideRepliedMessages,
-                        hideCurrentMedia,
-                        hidePulsing
-                    )
-                ) {
-                    val iconView = function.apply(entry)
-                    if (iconView != null) {
-                        toShow.add(iconView)
-                    }
-                }
-            }
-        }
-
-        // In case we are changing the suppression of a group, the replacement shouldn't flicker
-        // and it should just be replaced instead. We therefore look for notifications that were
-        // just replaced by the child or vice-versa to suppress this.
-        val replacingIcons = ArrayMap<String, ArrayList<StatusBarIcon>>()
-        val toRemove = ArrayList<View>()
-        for (i in 0 until hostLayout!!.childCount) {
-            val child = hostLayout.getChildAt(i) as? StatusBarIconView ?: continue
-            if (!toShow.contains(child)) {
-                var iconWasReplaced = false
-                val removedGroupKey = child.notification.groupKey
-                for (j in toShow.indices) {
-                    val candidate = toShow[j]
-                    if (
-                        candidate.sourceIcon.sameAs(child.sourceIcon) &&
-                            candidate.notification.groupKey == removedGroupKey
-                    ) {
-                        if (!iconWasReplaced) {
-                            iconWasReplaced = true
-                        } else {
-                            iconWasReplaced = false
-                            break
-                        }
-                    }
-                }
-                if (iconWasReplaced) {
-                    var statusBarIcons = replacingIcons[removedGroupKey]
-                    if (statusBarIcons == null) {
-                        statusBarIcons = ArrayList()
-                        replacingIcons[removedGroupKey] = statusBarIcons
-                    }
-                    statusBarIcons.add(child.statusBarIcon)
-                }
-                toRemove.add(child)
-            }
-        }
-        // removing all duplicates
-        val duplicates = ArrayList<String?>()
-        for (key in replacingIcons.keys) {
-            val statusBarIcons = replacingIcons[key]!!
-            if (statusBarIcons.size != 1) {
-                duplicates.add(key)
-            }
-        }
-        replacingIcons.removeAll(duplicates)
-        hostLayout.setReplacingIcons(replacingIcons)
-        val toRemoveCount = toRemove.size
-        for (i in 0 until toRemoveCount) {
-            hostLayout.removeView(toRemove[i])
-        }
-        val params = generateIconLayoutParams()
-        for (i in toShow.indices) {
-            val v = toShow[i]
-            // The view might still be transiently added if it was just removed and added again
-            hostLayout.removeTransientView(v)
-            if (v.parent == null) {
-                if (hideDismissed) {
-                    v.setOnDismissListener(updateStatusBarIcons)
-                }
-                hostLayout.addView(v, i, params)
-            }
-        }
-        hostLayout.setChangingViewPositions(true)
-        // Re-sort notification icons
-        val childCount = hostLayout.childCount
-        for (i in 0 until childCount) {
-            val actual = hostLayout.getChildAt(i)
-            val expected = toShow[i]
-            if (actual === expected) {
-                continue
-            }
-            hostLayout.removeView(expected)
-            hostLayout.addView(expected, i)
-        }
-        hostLayout.setChangingViewPositions(false)
-        hostLayout.setReplacingIcons(null)
-    }
-
     companion object {
         val unsupported: Nothing
             get() =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt
index 079004c..7592619 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt
@@ -15,11 +15,17 @@
  */
 package com.android.systemui.statusbar.notification.icon.ui.viewbinder
 
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
 import android.graphics.Rect
 import android.view.View
+import android.view.ViewPropertyAnimator
+import android.widget.FrameLayout
+import androidx.collection.ArrayMap
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.app.animation.Interpolators
+import com.android.internal.policy.SystemBarUtils
 import com.android.internal.util.ContrastColorUtil
 import com.android.systemui.common.ui.ConfigurationState
 import com.android.systemui.flags.FeatureFlagsClassic
@@ -29,78 +35,235 @@
 import com.android.systemui.statusbar.CrossFadeHelper
 import com.android.systemui.statusbar.StatusBarIconView
 import com.android.systemui.statusbar.notification.NotificationUtils
+import com.android.systemui.statusbar.notification.collection.NotifCollection
+import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder.IconViewStore
 import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel
 import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel.IconColors
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel.IconsViewData
 import com.android.systemui.statusbar.phone.DozeParameters
 import com.android.systemui.statusbar.phone.NotificationIconContainer
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.policy.onConfigChanged
 import com.android.systemui.util.children
+import com.android.systemui.util.kotlin.mapValuesNotNullTo
+import com.android.systemui.util.kotlin.sample
+import com.android.systemui.util.kotlin.stateFlow
+import com.android.systemui.util.ui.isAnimating
+import com.android.systemui.util.ui.stopAnimating
+import com.android.systemui.util.ui.value
+import javax.inject.Inject
 import kotlinx.coroutines.DisposableHandle
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.mapNotNull
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.launch
 
 /** Binds a [NotificationIconContainer] to its [view model][NotificationIconContainerViewModel]. */
 object NotificationIconContainerViewBinder {
+    @JvmStatic
     fun bind(
         view: NotificationIconContainer,
         viewModel: NotificationIconContainerViewModel,
         configuration: ConfigurationState,
+        configurationController: ConfigurationController,
         dozeParameters: DozeParameters,
         featureFlags: FeatureFlagsClassic,
         screenOffAnimationController: ScreenOffAnimationController,
+        viewStore: IconViewStore,
     ): DisposableHandle {
         val contrastColorUtil = ContrastColorUtil.getInstance(view.context)
         return view.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.CREATED) {
-                launch { viewModel.animationsEnabled.collect(view::setAnimationsEnabled) }
-                launch {
-                    viewModel.isDozing.collect { (isDozing, animate) ->
-                        val animateIfNotBlanking = animate && !dozeParameters.displayNeedsBlanking
-                        view.setDozing(isDozing, animateIfNotBlanking, /* delay= */ 0) {
-                            viewModel.completeDozeAnimation()
-                        }
-                    }
-                }
+                launch { bindAnimationsEnabled(viewModel, view) }
+                launch { bindIsDozing(viewModel, view, dozeParameters) }
                 // TODO(b/278765923): this should live where AOD is bound, not inside of the NIC
                 //  view-binder
                 launch {
-                    val iconAppearTranslation =
-                        configuration
-                            .getDimensionPixelSize(R.dimen.shelf_appear_translation)
-                            .stateIn(this)
                     bindVisibility(
                         viewModel,
                         view,
+                        configuration,
                         featureFlags,
                         screenOffAnimationController,
-                        iconAppearTranslation,
-                    ) {
-                        viewModel.completeVisibilityAnimation()
-                    }
+                    )
                 }
+                launch { bindIconColors(viewModel, view, contrastColorUtil) }
                 launch {
-                    viewModel.iconColors
-                        .mapNotNull { lookup -> lookup.iconColors(view.viewBounds) }
-                        .collect { iconLookup -> applyTint(view, iconLookup, contrastColorUtil) }
+                    bindIconViewData(
+                        viewModel,
+                        view,
+                        configuration,
+                        configurationController,
+                        viewStore,
+                    )
+                }
+                launch { bindIsolatedIcon(viewModel, view, viewStore) }
+            }
+        }
+    }
+
+    private suspend fun bindAnimationsEnabled(
+        viewModel: NotificationIconContainerViewModel,
+        view: NotificationIconContainer
+    ) {
+        viewModel.animationsEnabled.collect(view::setAnimationsEnabled)
+    }
+
+    private suspend fun bindIconColors(
+        viewModel: NotificationIconContainerViewModel,
+        view: NotificationIconContainer,
+        contrastColorUtil: ContrastColorUtil,
+    ) {
+        viewModel.iconColors
+            .mapNotNull { lookup -> lookup.iconColors(view.viewBounds) }
+            .collect { iconLookup -> applyTint(view, iconLookup, contrastColorUtil) }
+    }
+
+    private suspend fun bindIsDozing(
+        viewModel: NotificationIconContainerViewModel,
+        view: NotificationIconContainer,
+        dozeParameters: DozeParameters,
+    ) {
+        viewModel.isDozing.collect { isDozing ->
+            if (isDozing.isAnimating) {
+                val animate = !dozeParameters.displayNeedsBlanking
+                view.setDozing(
+                    /* dozing = */ isDozing.value,
+                    /* fade = */ animate,
+                    /* delay = */ 0,
+                    /* endRunnable = */ isDozing::stopAnimating,
+                )
+            } else {
+                view.setDozing(
+                    /* dozing = */ isDozing.value,
+                    /* fade= */ false,
+                    /* delay= */ 0,
+                )
+            }
+        }
+    }
+
+    private suspend fun bindIsolatedIcon(
+        viewModel: NotificationIconContainerViewModel,
+        view: NotificationIconContainer,
+        viewStore: IconViewStore,
+    ) {
+        coroutineScope {
+            launch {
+                viewModel.isolatedIconLocation.collect { location ->
+                    view.setIsolatedIconLocation(location, true)
+                }
+            }
+            launch {
+                viewModel.isolatedIcon.collect { iconInfo ->
+                    val iconView = iconInfo.value?.let { viewStore.iconView(it.notifKey) }
+                    if (iconInfo.isAnimating) {
+                        view.showIconIsolatedAnimated(iconView, iconInfo::stopAnimating)
+                    } else {
+                        view.showIconIsolated(iconView)
+                    }
                 }
             }
         }
     }
 
-    // TODO(b/305739416): Once SBIV has its own Recommended Architecture stack, this can be moved
-    //  there and cleaned up.
+    private suspend fun bindIconViewData(
+        viewModel: NotificationIconContainerViewModel,
+        view: NotificationIconContainer,
+        configuration: ConfigurationState,
+        configurationController: ConfigurationController,
+        viewStore: IconViewStore,
+    ): Unit = coroutineScope {
+        val iconSizeFlow: Flow<Int> =
+            configuration.getDimensionPixelSize(
+                com.android.internal.R.dimen.status_bar_icon_size_sp,
+            )
+        val iconHorizontalPaddingFlow: Flow<Int> =
+            configuration.getDimensionPixelSize(R.dimen.status_bar_icon_horizontal_margin)
+        val statusBarHeightFlow: StateFlow<Int> =
+            stateFlow(changedSignals = configurationController.onConfigChanged) {
+                SystemBarUtils.getStatusBarHeight(view.context)
+            }
+        val layoutParams: Flow<FrameLayout.LayoutParams> =
+            combine(iconSizeFlow, iconHorizontalPaddingFlow, statusBarHeightFlow) {
+                iconSize,
+                iconHPadding,
+                statusBarHeight,
+                ->
+                FrameLayout.LayoutParams(iconSize + 2 * iconHPadding, statusBarHeight)
+            }
+
+        launch {
+            layoutParams.collect { params: FrameLayout.LayoutParams ->
+                for (child in view.children) {
+                    child.layoutParams = params
+                }
+            }
+        }
+
+        var prevIcons = IconsViewData()
+        viewModel.iconsViewData.sample(layoutParams, ::Pair).collect {
+            (iconsData: IconsViewData, layoutParams: FrameLayout.LayoutParams),
+            ->
+            val iconsDiff = IconsViewData.computeDifference(iconsData, prevIcons)
+            prevIcons = iconsData
+
+            val replacingIcons =
+                iconsDiff.groupReplacements.mapValuesNotNullTo(ArrayMap()) { (_, v) ->
+                    viewStore.iconView(v.notifKey)?.statusBarIcon
+                }
+            view.setReplacingIcons(replacingIcons)
+
+            val childrenByNotifKey: Map<String, StatusBarIconView> =
+                view.children.filterIsInstance<StatusBarIconView>().associateByTo(ArrayMap()) {
+                    it.notification.key
+                }
+
+            iconsDiff.removed
+                .mapNotNull { key -> childrenByNotifKey[key] }
+                .forEach { child -> view.removeView(child) }
+
+            val toAdd = iconsDiff.added.mapNotNull { viewStore.iconView(it.notifKey) }
+            for ((i, sbiv) in toAdd.withIndex()) {
+                // The view might still be transiently added if it was just removed
+                // and added again
+                view.removeTransientView(sbiv)
+                view.addView(sbiv, i, layoutParams)
+            }
+
+            view.setChangingViewPositions(true)
+            // Re-sort notification icons
+            val childCount = view.childCount
+            for (i in 0 until childCount) {
+                val actual = view.getChildAt(i)
+                val expected = viewStore.iconView(iconsData.visibleKeys[i].notifKey)!!
+                if (actual === expected) {
+                    continue
+                }
+                view.removeView(expected)
+                view.addView(expected, i)
+            }
+            view.setChangingViewPositions(false)
+
+            view.setReplacingIcons(null)
+        }
+    }
+
+    // TODO(b/305739416): Once StatusBarIconView has its own Recommended Architecture stack, this
+    //  can be moved there and cleaned up.
     private fun applyTint(
         view: NotificationIconContainer,
         iconColors: IconColors,
         contrastColorUtil: ContrastColorUtil,
     ) {
-        view.children.filterIsInstance<StatusBarIconView>().forEach { iv ->
-            if (iv.width != 0) {
-                updateTintForIcon(iv, iconColors, contrastColorUtil)
-            }
-        }
+        view.children
+            .filterIsInstance<StatusBarIconView>()
+            .filter { it.width != 0 }
+            .forEach { iv -> updateTintForIcon(iv, iconColors, contrastColorUtil) }
     }
 
     private fun updateTintForIcon(
@@ -117,34 +280,41 @@
     private suspend fun bindVisibility(
         viewModel: NotificationIconContainerViewModel,
         view: NotificationIconContainer,
+        configuration: ConfigurationState,
         featureFlags: FeatureFlagsClassic,
         screenOffAnimationController: ScreenOffAnimationController,
-        iconAppearTranslation: StateFlow<Int>,
-        onAnimationEnd: () -> Unit,
-    ) {
+    ): Unit = coroutineScope {
+        val iconAppearTranslation =
+            configuration.getDimensionPixelSize(R.dimen.shelf_appear_translation).stateIn(this)
         val statusViewMigrated = featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)
-        viewModel.isVisible.collect { (isVisible, animate) ->
+        viewModel.isVisible.collect { isVisible ->
             view.animate().cancel()
+            val animatorListener =
+                object : AnimatorListenerAdapter() {
+                    override fun onAnimationEnd(animation: Animator) {
+                        isVisible.stopAnimating()
+                    }
+                }
             when {
-                !animate -> {
+                !isVisible.isAnimating -> {
                     view.alpha = 1f
                     if (!statusViewMigrated) {
                         view.translationY = 0f
                     }
-                    view.visibility = if (isVisible) View.VISIBLE else View.INVISIBLE
+                    view.visibility = if (isVisible.value) View.VISIBLE else View.INVISIBLE
                 }
                 featureFlags.isEnabled(Flags.NEW_AOD_TRANSITION) -> {
                     animateInIconTranslation(view, statusViewMigrated)
-                    if (isVisible) {
-                        CrossFadeHelper.fadeIn(view, onAnimationEnd)
+                    if (isVisible.value) {
+                        CrossFadeHelper.fadeIn(view, animatorListener)
                     } else {
-                        CrossFadeHelper.fadeOut(view, onAnimationEnd)
+                        CrossFadeHelper.fadeOut(view, animatorListener)
                     }
                 }
-                !isVisible -> {
+                !isVisible.value -> {
                     // Let's make sure the icon are translated to 0, since we cancelled it above
                     animateInIconTranslation(view, statusViewMigrated)
-                    CrossFadeHelper.fadeOut(view, onAnimationEnd)
+                    CrossFadeHelper.fadeOut(view, animatorListener)
                 }
                 view.visibility != View.VISIBLE -> {
                     // No fading here, let's just appear the icons instead!
@@ -155,14 +325,14 @@
                         animate = screenOffAnimationController.shouldAnimateAodIcons(),
                         iconAppearTranslation.value,
                         statusViewMigrated,
+                        animatorListener,
                     )
-                    onAnimationEnd()
                 }
                 else -> {
                     // Let's make sure the icons are translated to 0, since we cancelled it above
                     animateInIconTranslation(view, statusViewMigrated)
                     // We were fading out, let's fade in instead
-                    CrossFadeHelper.fadeIn(view, onAnimationEnd)
+                    CrossFadeHelper.fadeIn(view, animatorListener)
                 }
             }
         }
@@ -173,18 +343,20 @@
         animate: Boolean,
         iconAppearTranslation: Int,
         statusViewMigrated: Boolean,
+        animatorListener: Animator.AnimatorListener,
     ) {
         if (animate) {
             if (!statusViewMigrated) {
                 view.translationY = -iconAppearTranslation.toFloat()
             }
             view.alpha = 0f
-            animateInIconTranslation(view, statusViewMigrated)
             view
                 .animate()
                 .alpha(1f)
                 .setInterpolator(Interpolators.LINEAR)
                 .setDuration(AOD_ICONS_APPEAR_DURATION)
+                .apply { if (statusViewMigrated) animateInIconTranslation() }
+                .setListener(animatorListener)
                 .start()
         } else {
             view.alpha = 1.0f
@@ -196,15 +368,13 @@
 
     private fun animateInIconTranslation(view: View, statusViewMigrated: Boolean) {
         if (!statusViewMigrated) {
-            view
-                .animate()
-                .setInterpolator(Interpolators.DECELERATE_QUINT)
-                .translationY(0f)
-                .setDuration(AOD_ICONS_APPEAR_DURATION)
-                .start()
+            view.animate().animateInIconTranslation().setDuration(AOD_ICONS_APPEAR_DURATION).start()
         }
     }
 
+    private fun ViewPropertyAnimator.animateInIconTranslation(): ViewPropertyAnimator =
+        setInterpolator(Interpolators.DECELERATE_QUINT).translationY(0f)
+
     private const val AOD_ICONS_APPEAR_DURATION: Long = 200
 
     private val View.viewBounds: Rect
@@ -218,4 +388,39 @@
                 /* bottom = */ top + height,
             )
         }
+
+    /** External storage for [StatusBarIconView] instances. */
+    fun interface IconViewStore {
+        fun iconView(key: String): StatusBarIconView?
+    }
+}
+
+/** [IconViewStore] for the [com.android.systemui.statusbar.NotificationShelf] */
+class ShelfNotificationIconViewStore
+@Inject
+constructor(
+    private val notifCollection: NotifCollection,
+) : IconViewStore {
+    override fun iconView(key: String): StatusBarIconView? =
+        notifCollection.getEntry(key)?.icons?.shelfIcon
+}
+
+/** [IconViewStore] for the always-on display. */
+class AlwaysOnDisplayNotificationIconViewStore
+@Inject
+constructor(
+    private val notifCollection: NotifCollection,
+) : IconViewStore {
+    override fun iconView(key: String): StatusBarIconView? =
+        notifCollection.getEntry(key)?.icons?.aodIcon
+}
+
+/** [IconViewStore] for the status bar. */
+class StatusBarNotificationIconViewStore
+@Inject
+constructor(
+    private val notifCollection: NotifCollection,
+) : IconViewStore {
+    override fun iconView(key: String): StatusBarIconView? =
+        notifCollection.getEntry(key)?.icons?.statusBarIcon
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt
index e9de4bd..120d342 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt
@@ -30,8 +30,11 @@
 import com.android.systemui.res.R
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.statusbar.notification.domain.interactor.NotificationsKeyguardInteractor
+import com.android.systemui.statusbar.notification.icon.domain.interactor.AlwaysOnDisplayNotificationIconsInteractor
 import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel.ColorLookup
 import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel.IconColors
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel.IconInfo
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel.IconsViewData
 import com.android.systemui.statusbar.phone.DozeParameters
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController
 import com.android.systemui.util.kotlin.pairwise
@@ -39,11 +42,13 @@
 import com.android.systemui.util.ui.AnimatableEvent
 import com.android.systemui.util.ui.AnimatedValue
 import com.android.systemui.util.ui.toAnimatedValueFlow
+import com.android.systemui.util.ui.zip
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.emptyFlow
+import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
 
 /** View-model for the row of notification icons displayed on the always-on display. */
@@ -55,6 +60,7 @@
     private val deviceEntryInteractor: DeviceEntryInteractor,
     private val dozeParameters: DozeParameters,
     private val featureFlags: FeatureFlagsClassic,
+    iconsInteractor: AlwaysOnDisplayNotificationIconsInteractor,
     keyguardInteractor: KeyguardInteractor,
     keyguardTransitionInteractor: KeyguardTransitionInteractor,
     private val notificationsKeyguardInteractor: NotificationsKeyguardInteractor,
@@ -62,9 +68,6 @@
     shadeInteractor: ShadeInteractor,
 ) : NotificationIconContainerViewModel {
 
-    private val onDozeAnimationComplete = MutableSharedFlow<Unit>(extraBufferCapacity = 1)
-    private val onVisAnimationComplete = MutableSharedFlow<Unit>(extraBufferCapacity = 1)
-
     override val iconColors: Flow<ColorLookup> =
         configuration.getColorAttr(R.attr.wallpaperTextColor, DEFAULT_AOD_ICON_COLOR).map { tint ->
             ColorLookup { IconColorsImpl(tint) }
@@ -93,7 +96,7 @@
                 AnimatableEvent(isDozing, animate)
             }
             .distinctUntilChanged()
-            .toAnimatedValueFlow(completionEvents = onDozeAnimationComplete)
+            .toAnimatedValueFlow()
 
     override val isVisible: Flow<AnimatedValue<Boolean>> =
         combine(
@@ -103,46 +106,54 @@
                 isPulseExpandingAnimated(),
             ) {
                 onKeyguard: Boolean,
-                bypassEnabled: Boolean,
-                (notifsFullyHidden: Boolean, isAnimatingHide: Boolean),
-                (pulseExpanding: Boolean, isAnimatingPulse: Boolean),
+                isBypassEnabled: Boolean,
+                notifsFullyHidden: AnimatedValue<Boolean>,
+                pulseExpanding: AnimatedValue<Boolean>,
                 ->
-                val isAnimating = isAnimatingHide || isAnimatingPulse
                 when {
                     // Hide the AOD icons if we're not in the KEYGUARD state unless the screen off
                     // animation is playing, in which case we want them to be visible if we're
                     // animating in the AOD UI and will be switching to KEYGUARD shortly.
                     !onKeyguard && !screenOffAnimationController.shouldShowAodIconsWhenShade() ->
-                        AnimatedValue(false, isAnimating = false)
-                    // If we're bypassing, then we're visible
-                    bypassEnabled -> AnimatedValue(true, isAnimating)
-                    // If we are pulsing (and not bypassing), then we are hidden
-                    pulseExpanding -> AnimatedValue(false, isAnimating)
-                    // If notifs are fully gone, then we're visible
-                    notifsFullyHidden -> AnimatedValue(true, isAnimating)
-                    // Otherwise, we're hidden
-                    else -> AnimatedValue(false, isAnimating)
+                        AnimatedValue.NotAnimating(false)
+                    else ->
+                        zip(notifsFullyHidden, pulseExpanding) {
+                            areNotifsFullyHidden,
+                            isPulseExpanding,
+                            ->
+                            when {
+                                // If we're bypassing, then we're visible
+                                isBypassEnabled -> true
+                                // If we are pulsing (and not bypassing), then we are hidden
+                                isPulseExpanding -> false
+                                // If notifs are fully gone, then we're visible
+                                areNotifsFullyHidden -> true
+                                // Otherwise, we're hidden
+                                else -> false
+                            }
+                        }
                 }
             }
             .distinctUntilChanged()
 
-    override fun completeDozeAnimation() {
-        onDozeAnimationComplete.tryEmit(Unit)
-    }
+    override val iconsViewData: Flow<IconsViewData> =
+        iconsInteractor.aodNotifs.map { entries ->
+            IconsViewData(
+                visibleKeys = entries.mapNotNull { it.toIconInfo(it.aodIcon) },
+            )
+        }
 
-    override fun completeVisibilityAnimation() {
-        onVisAnimationComplete.tryEmit(Unit)
-    }
+    override val isolatedIcon: Flow<AnimatedValue<IconInfo?>> =
+        flowOf(AnimatedValue.NotAnimating(null))
+    override val isolatedIconLocation: Flow<Rect> = emptyFlow()
 
     /** Is there an expanded pulse, are we animating in response? */
     private fun isPulseExpandingAnimated(): Flow<AnimatedValue<Boolean>> {
         return notificationsKeyguardInteractor.isPulseExpanding
             .pairwise(initialValue = null)
             // If pulsing changes, start animating, unless it's the first emission
-            .map { (prev, expanding) ->
-                AnimatableEvent(expanding!!, startAnimating = prev != null)
-            }
-            .toAnimatedValueFlow(completionEvents = onVisAnimationComplete)
+            .map { (prev, expanding) -> AnimatableEvent(expanding, startAnimating = prev != null) }
+            .toAnimatedValueFlow()
     }
 
     /** Are notifications completely hidden from view, are we animating in response? */
@@ -164,11 +175,11 @@
                         // We only want the appear animations to happen when the notifications
                         // get fully hidden, since otherwise the un-hide animation overlaps.
                         featureFlags.isEnabled(Flags.NEW_AOD_TRANSITION) -> true
-                        else -> fullyHidden!!
+                        else -> fullyHidden
                     }
-                AnimatableEvent(fullyHidden!!, animate)
+                AnimatableEvent(fullyHidden, animate)
             }
-            .toAnimatedValueFlow(completionEvents = onVisAnimationComplete)
+            .toAnimatedValueFlow()
     }
 
     private class IconColorsImpl(override val tint: Int) : IconColors {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt
index f305155..c6aabb7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt
@@ -15,20 +15,37 @@
  */
 package com.android.systemui.statusbar.notification.icon.ui.viewmodel
 
+import android.graphics.Rect
+import com.android.systemui.statusbar.notification.icon.domain.interactor.NotificationIconsInteractor
 import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel.ColorLookup
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel.IconInfo
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel.IconsViewData
 import com.android.systemui.util.ui.AnimatedValue
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
 
 /** View-model for the overflow row of notification icons displayed in the notification shade. */
-class NotificationIconContainerShelfViewModel @Inject constructor() :
-    NotificationIconContainerViewModel {
+class NotificationIconContainerShelfViewModel
+@Inject
+constructor(
+    interactor: NotificationIconsInteractor,
+) : NotificationIconContainerViewModel {
+
     override val animationsEnabled: Flow<Boolean> = flowOf(true)
     override val isDozing: Flow<AnimatedValue<Boolean>> = emptyFlow()
     override val isVisible: Flow<AnimatedValue<Boolean>> = emptyFlow()
-    override fun completeDozeAnimation() {}
-    override fun completeVisibilityAnimation() {}
     override val iconColors: Flow<ColorLookup> = emptyFlow()
+    override val isolatedIcon: Flow<AnimatedValue<IconInfo?>> =
+        flowOf(AnimatedValue.NotAnimating(null))
+    override val isolatedIconLocation: Flow<Rect> = emptyFlow()
+
+    override val iconsViewData: Flow<IconsViewData> =
+        interactor.filteredNotifSet().map { entries ->
+            IconsViewData(
+                visibleKeys = entries.mapNotNull { it.toIconInfo(it.shelfIcon) },
+            )
+        }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
index ee01fcc..4d14024 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
@@ -20,20 +20,32 @@
 import com.android.systemui.plugins.DarkIconDispatcher
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
+import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationIconInteractor
+import com.android.systemui.statusbar.notification.icon.domain.interactor.StatusBarNotificationIconsInteractor
 import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel.ColorLookup
 import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel.IconColors
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel.IconInfo
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel.IconsViewData
 import com.android.systemui.statusbar.phone.domain.interactor.DarkIconInteractor
+import com.android.systemui.util.kotlin.pairwise
+import com.android.systemui.util.kotlin.sample
+import com.android.systemui.util.ui.AnimatableEvent
 import com.android.systemui.util.ui.AnimatedValue
+import com.android.systemui.util.ui.toAnimatedValueFlow
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.emptyFlow
+import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.map
 
 /** View-model for the row of notification icons displayed in the status bar, */
 class NotificationIconContainerStatusBarViewModel
 @Inject
 constructor(
     darkIconInteractor: DarkIconInteractor,
+    iconsInteractor: StatusBarNotificationIconsInteractor,
+    headsUpIconInteractor: HeadsUpNotificationIconInteractor,
     keyguardInteractor: KeyguardInteractor,
     notificationsInteractor: ActiveNotificationsInteractor,
     shadeInteractor: ShadeInteractor,
@@ -45,6 +57,7 @@
         ) { panelTouchesEnabled, isKeyguardShowing ->
             panelTouchesEnabled && !isKeyguardShowing
         }
+
     override val iconColors: Flow<ColorLookup> =
         combine(
             darkIconInteractor.tintAreas,
@@ -60,10 +73,40 @@
                 }
             }
         }
+
     override val isDozing: Flow<AnimatedValue<Boolean>> = emptyFlow()
     override val isVisible: Flow<AnimatedValue<Boolean>> = emptyFlow()
-    override fun completeDozeAnimation() {}
-    override fun completeVisibilityAnimation() {}
+
+    override val iconsViewData: Flow<IconsViewData> =
+        iconsInteractor.statusBarNotifs.map { entries ->
+            IconsViewData(
+                visibleKeys = entries.mapNotNull { it.toIconInfo(it.statusBarIcon) },
+            )
+        }
+
+    override val isolatedIcon: Flow<AnimatedValue<IconInfo?>> =
+        headsUpIconInteractor.isolatedNotification
+            .pairwise(initialValue = null)
+            .sample(combine(iconsViewData, shadeInteractor.shadeExpansion, ::Pair)) {
+                (prev, isolatedNotif),
+                (iconsViewData, shadeExpansion),
+                ->
+                val iconInfo =
+                    isolatedNotif?.let {
+                        iconsViewData.visibleKeys.firstOrNull { it.notifKey == isolatedNotif }
+                    }
+                val animate =
+                    when {
+                        isolatedNotif == prev -> false
+                        isolatedNotif == null || prev == null -> shadeExpansion == 0f
+                        else -> false
+                    }
+                AnimatableEvent(iconInfo, animate)
+            }
+            .toAnimatedValueFlow()
+
+    override val isolatedIconLocation: Flow<Rect> =
+        headsUpIconInteractor.isolatedIconLocation.filterNotNull()
 
     private class IconColorsImpl(
         override val tint: Int,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerViewModel.kt
index c98811b..a611323 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerViewModel.kt
@@ -16,6 +16,11 @@
 package com.android.systemui.statusbar.notification.icon.ui.viewmodel
 
 import android.graphics.Rect
+import android.graphics.drawable.Icon
+import androidx.collection.ArrayMap
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel.IconInfo
+import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
+import com.android.systemui.util.kotlin.mapValuesNotNullTo
 import com.android.systemui.util.ui.AnimatedValue
 import kotlinx.coroutines.flow.Flow
 
@@ -37,17 +42,14 @@
     /** The colors with which to display the notification icons. */
     val iconColors: Flow<ColorLookup>
 
-    /**
-     * Signal completion of the [isDozing] animation; if [isDozing]'s [AnimatedValue.isAnimating]
-     * property was `true`, calling this method will update it to `false`.
-     */
-    fun completeDozeAnimation()
+    /** [IconsViewData] indicating which icons to display in the view. */
+    val iconsViewData: Flow<IconsViewData>
 
-    /**
-     * Signal completion of the [isVisible] animation; if [isVisible]'s [AnimatedValue.isAnimating]
-     * property was `true`, calling this method will update it to `false`.
-     */
-    fun completeVisibilityAnimation()
+    /** An Icon to show "isolated" in the IconContainer. */
+    val isolatedIcon: Flow<AnimatedValue<IconInfo?>>
+
+    /** Location to show an isolated icon, if there is one. */
+    val isolatedIconLocation: Flow<Rect>
 
     /**
      * Lookup the colors to use for the notification icons based on the bounds of the icon
@@ -69,4 +71,126 @@
          */
         fun staticDrawableColor(viewBounds: Rect, isColorized: Boolean): Int
     }
+
+    /** Encapsulates the collection of notification icons present on the device. */
+    data class IconsViewData(
+        /** Icons that are visible in the container. */
+        val visibleKeys: List<IconInfo> = emptyList(),
+        /** Keys of icons that are "behind" the overflow dot. */
+        val collapsedKeys: Set<String> = emptySet(),
+        /** Whether the overflow dot should be shown regardless if [collapsedKeys] is empty. */
+        val forceShowDot: Boolean = false,
+    ) {
+        /** The difference between two [IconsViewData]s. */
+        data class Diff(
+            /** Icons added in the newer dataset. */
+            val added: List<IconInfo> = emptyList(),
+            /** Icons removed from the older dataset. */
+            val removed: List<String> = emptyList(),
+            /**
+             * Groups whose icon was replaced with a single new notification icon. The key of the
+             * [Map] is the notification group key, and the value is the new icon.
+             *
+             * Specifically, this models a difference where the older dataset had notification
+             * groups with a single icon in the set, and the newer dataset has a single, different
+             * icon for the same group. A view binder can use this information for special
+             * animations for this specific change.
+             */
+            val groupReplacements: Map<String, IconInfo> = emptyMap(),
+        )
+
+        companion object {
+            /**
+             * Returns an [IconsViewData.Diff] calculated from a [new] and [previous][prev]
+             * [IconsViewData] state.
+             */
+            fun computeDifference(new: IconsViewData, prev: IconsViewData): Diff {
+                val added: List<IconInfo> =
+                    new.visibleKeys.filter {
+                        it.notifKey !in prev.visibleKeys.asSequence().map { it.notifKey }
+                    }
+                val removed: List<IconInfo> =
+                    prev.visibleKeys.filter {
+                        it.notifKey !in new.visibleKeys.asSequence().map { it.notifKey }
+                    }
+                val groupsToShow: Set<IconGroupInfo> =
+                    new.visibleKeys.asSequence().map { it.groupInfo }.toSet()
+                val replacements: ArrayMap<String, IconInfo> =
+                    removed
+                        .asSequence()
+                        .filter { keyToRemove -> keyToRemove.groupInfo in groupsToShow }
+                        .groupBy { it.groupInfo.groupKey }
+                        .mapValuesNotNullTo(ArrayMap()) { (_, vs) ->
+                            vs.takeIf { it.size == 1 }?.get(0)
+                        }
+                return Diff(added, removed.map { it.notifKey }, replacements)
+            }
+        }
+    }
+
+    /** An Icon, and keys for unique identification. */
+    data class IconInfo(
+        val sourceIcon: Icon,
+        val notifKey: String,
+        val groupKey: String,
+    )
+}
+
+/**
+ * Construct an [IconInfo] out of an [ActiveNotificationModel], or return `null` if one cannot be
+ * created due to missing information.
+ */
+fun ActiveNotificationModel.toIconInfo(sourceIcon: Icon?): IconInfo? {
+    return sourceIcon?.let {
+        groupKey?.let { groupKey ->
+            IconInfo(
+                sourceIcon = sourceIcon,
+                notifKey = key,
+                groupKey = groupKey,
+            )
+        }
+    }
+}
+
+private val IconInfo.groupInfo: IconGroupInfo
+    get() = IconGroupInfo(sourceIcon, groupKey)
+
+private data class IconGroupInfo(
+    val sourceIcon: Icon,
+    val groupKey: String,
+) {
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (javaClass != other?.javaClass) return false
+
+        other as IconGroupInfo
+
+        if (groupKey != other.groupKey) return false
+        return sourceIcon.sameAs(other.sourceIcon)
+    }
+
+    override fun hashCode(): Int {
+        var result = groupKey.hashCode()
+        result = 31 * result + sourceIcon.type.hashCode()
+        when (sourceIcon.type) {
+            Icon.TYPE_BITMAP,
+            Icon.TYPE_ADAPTIVE_BITMAP -> {
+                result = 31 * result + sourceIcon.bitmap.hashCode()
+            }
+            Icon.TYPE_DATA -> {
+                result = 31 * result + sourceIcon.dataLength.hashCode()
+                result = 31 * result + sourceIcon.dataOffset.hashCode()
+            }
+            Icon.TYPE_RESOURCE -> {
+                result = 31 * result + sourceIcon.resId.hashCode()
+                result = 31 * result + sourceIcon.resPackage.hashCode()
+            }
+            Icon.TYPE_URI,
+            Icon.TYPE_URI_ADAPTIVE_BITMAP -> {
+                result = 31 * result + sourceIcon.uriString.hashCode()
+            }
+        }
+        return result
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java
index b0155f1..6ec9dbe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java
@@ -180,9 +180,4 @@
      * Add a component that can suppress visual interruptions.
      */
     void addSuppressor(NotificationInterruptSuppressor suppressor);
-
-    /**
-     * Remove a component that can suppress visual interruptions.
-     */
-    void removeSuppressor(NotificationInterruptSuppressor suppressor);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
index 778a0a9..3819843 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
@@ -175,11 +175,6 @@
     }
 
     @Override
-    public void removeSuppressor(NotificationInterruptSuppressor suppressor) {
-        mSuppressors.remove(suppressor);
-    }
-
-    @Override
     public boolean shouldBubbleUp(NotificationEntry entry) {
         final StatusBarNotification sbn = entry.getSbn();
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapper.kt
index d7f0baf..ebdeded 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapper.kt
@@ -58,10 +58,6 @@
         wrapped.addSuppressor(suppressor)
     }
 
-    override fun removeLegacySuppressor(suppressor: NotificationInterruptSuppressor) {
-        wrapped.removeSuppressor(suppressor)
-    }
-
     override fun makeUnloggedHeadsUpDecision(entry: NotificationEntry): Decision =
         wrapped.checkHeadsUp(entry, /* log= */ false).let { DecisionImpl.of(it) }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProvider.kt
index 920bbe9..454ba02 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProvider.kt
@@ -60,13 +60,6 @@
     fun addLegacySuppressor(suppressor: NotificationInterruptSuppressor)
 
     /**
-     * Removes a [component][suppressor] that can suppress visual interruptions.
-     *
-     * @param[suppressor] the suppressor to remove
-     */
-    fun removeLegacySuppressor(suppressor: NotificationInterruptSuppressor)
-
-    /**
      * Decides whether a [notification][entry] should display as heads-up or not, but does not log
      * that decision.
      *
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt
index ea29cab..78370ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt
@@ -15,8 +15,36 @@
 
 package com.android.systemui.statusbar.notification.shared
 
+import android.graphics.drawable.Icon
+
 /** Model for entries in the notification stack. */
 data class ActiveNotificationModel(
     /** Notification key associated with this entry. */
     val key: String,
+    /** Notification group key associated with this entry. */
+    val groupKey: String?,
+    /** Is this entry in the ambient / minimized section (lowest priority)? */
+    val isAmbient: Boolean,
+    /**
+     * Is this entry dismissed? This is `true` when the user has dismissed the notification in the
+     * UI, but `NotificationManager` has not yet signalled to us that it has received the dismissal.
+     */
+    val isRowDismissed: Boolean,
+    /** Is this entry in the silent section? */
+    val isSilent: Boolean,
+    /**
+     * Does this entry represent a conversation, the last message of which was from a remote input
+     * reply?
+     */
+    val isLastMessageFromReply: Boolean,
+    /** Is this entry suppressed from appearing in the status bar as an icon? */
+    val isSuppressedFromStatusBar: Boolean,
+    /** Is this entry actively pulsing on AOD or bypassed-keyguard? */
+    val isPulsing: Boolean,
+    /** Icon to display on AOD. */
+    val aodIcon: Icon?,
+    /** Icon to display in the notification shelf. */
+    val shelfIcon: Icon?,
+    /** Icon to display in the status bar. */
+    val statusBarIcon: Icon?,
 )
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 77d5a2d..1e9cfa8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -107,6 +107,7 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
+import com.android.systemui.statusbar.notification.footer.shared.FooterViewRefactor;
 import com.android.systemui.statusbar.notification.footer.ui.view.FooterView;
 import com.android.systemui.statusbar.notification.init.NotificationsController;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
@@ -694,7 +695,9 @@
         super.onFinishInflate();
 
         inflateEmptyShadeView();
-        inflateFooterView();
+        if (!FooterViewRefactor.isEnabled()) {
+            inflateFooterView();
+        }
     }
 
     /**
@@ -729,9 +732,11 @@
     }
 
     void reinflateViews() {
-        inflateFooterView();
+        if (!FooterViewRefactor.isEnabled()) {
+            inflateFooterView();
+            updateFooter();
+        }
         inflateEmptyShadeView();
-        updateFooter();
         mSectionsManager.reinflateViews();
     }
 
@@ -746,7 +751,7 @@
 
     @VisibleForTesting
     public void updateFooter() {
-        if (mFooterView == null) {
+        if (mFooterView == null || mController == null) {
             return;
         }
         // TODO: move this logic to controller, which will invoke updateFooterView directly
@@ -4546,7 +4551,8 @@
         return mFooterView != null && mFooterView.isHistoryShown();
     }
 
-    void setFooterView(@NonNull FooterView footerView) {
+    /** Bind the {@link FooterView} to the NSSL. */
+    public void setFooterView(@NonNull FooterView footerView) {
         int index = -1;
         if (mFooterView != null) {
             index = indexOfChild(mFooterView);
@@ -4557,6 +4563,16 @@
         if (mManageButtonClickListener != null) {
             mFooterView.setManageButtonClickListener(mManageButtonClickListener);
         }
+        mFooterView.setClearAllButtonClickListener(v -> {
+            if (mFooterClearAllListener != null) {
+                mFooterClearAllListener.onClearAll();
+            }
+            clearNotifications(ROWS_ALL, true /* closeShade */);
+            footerView.setSecondaryVisible(false /* visible */, true /* animate */);
+        });
+        if (FooterViewRefactor.isEnabled()) {
+            updateFooter();
+        }
     }
 
     public void setEmptyShadeView(EmptyShadeView emptyShadeView) {
@@ -4619,7 +4635,9 @@
         mFooterView.setVisible(visible, animate);
         mFooterView.setSecondaryVisible(showDismissView, animate);
         mFooterView.showHistory(showHistory);
-        mFooterView.setFooterLabelVisible(mHasFilteredOutSeenNotifications);
+        if (!FooterViewRefactor.isEnabled()) {
+            mFooterView.setFooterLabelVisible(mHasFilteredOutSeenNotifications);
+        }
     }
 
     @VisibleForTesting
@@ -5370,15 +5388,9 @@
 
     @VisibleForTesting
     protected void inflateFooterView() {
+        FooterViewRefactor.assertInLegacyMode();
         FooterView footerView = (FooterView) LayoutInflater.from(mContext).inflate(
                 R.layout.status_bar_notification_footer, this, false);
-        footerView.setClearAllButtonClickListener(v -> {
-            if (mFooterClearAllListener != null) {
-                mFooterClearAllListener.onClearAll();
-            }
-            clearNotifications(ROWS_ALL, true /* closeShade */);
-            footerView.setSecondaryVisible(false /* visible */, true /* animate */);
-        });
         setFooterView(footerView);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index 8e88a91..79448b4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -62,7 +62,7 @@
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.FeatureFlagsClassic;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.flags.RefactorFlag;
 import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository;
@@ -206,7 +206,7 @@
     private HeadsUpAppearanceController mHeadsUpAppearanceController;
     private boolean mIsInTransitionToAod = false;
 
-    private final FeatureFlags mFeatureFlags;
+    private final FeatureFlagsClassic mFeatureFlags;
     private final RefactorFlag mShelfRefactor;
     private final NotificationTargetsHelper mNotificationTargetsHelper;
     private final SecureSettings mSecureSettings;
@@ -669,7 +669,7 @@
             NotificationStackScrollLogger logger,
             NotificationStackSizeCalculator notificationStackSizeCalculator,
             NotificationIconAreaController notifIconAreaController,
-            FeatureFlags featureFlags,
+            FeatureFlagsClassic featureFlags,
             NotificationTargetsHelper notificationTargetsHelper,
             SecureSettings secureSettings,
             NotificationDismissibilityProvider dismissibilityProvider,
@@ -832,7 +832,8 @@
 
         mViewModel.ifPresent(
                 vm -> NotificationListViewBinder
-                        .bind(mView, vm, mFalsingManager, mFeatureFlags, mNotifIconAreaController));
+                        .bind(mView, vm, mFalsingManager, mFeatureFlags, mNotifIconAreaController,
+                                mConfigurationController));
 
         collectFlow(mView, mKeyguardTransitionRepo.getTransitions(),
                 this::onKeyguardTransitionChanged);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt
index dee3973..a3792cf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt
@@ -17,14 +17,23 @@
 package com.android.systemui.statusbar.notification.stack.ui.viewbinder
 
 import android.view.LayoutInflater
-import com.android.systemui.res.R
-import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.FeatureFlagsClassic
+import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.NotificationShelf
+import com.android.systemui.statusbar.notification.footer.ui.view.FooterView
+import com.android.systemui.statusbar.notification.footer.ui.viewbinder.FooterViewBinder
 import com.android.systemui.statusbar.notification.shelf.ui.viewbinder.NotificationShelfViewBinder
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
 import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationListViewModel
 import com.android.systemui.statusbar.phone.NotificationIconAreaController
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.policy.onDensityOrFontScaleChanged
+import com.android.systemui.statusbar.policy.onThemeChanged
+import com.android.systemui.util.traceSection
+import com.android.systemui.util.view.reinflateAndBindLatest
+import kotlinx.coroutines.flow.merge
 
 /** Binds a [NotificationStackScrollLayout] to its [view model][NotificationListViewModel]. */
 object NotificationListViewBinder {
@@ -33,8 +42,9 @@
         view: NotificationStackScrollLayout,
         viewModel: NotificationListViewModel,
         falsingManager: FalsingManager,
-        featureFlags: FeatureFlags,
+        featureFlags: FeatureFlagsClassic,
         iconAreaController: NotificationIconAreaController,
+        configurationController: ConfigurationController,
     ) {
         val shelf =
             LayoutInflater.from(view.context)
@@ -47,5 +57,26 @@
             iconAreaController
         )
         view.setShelf(shelf)
+
+        viewModel.footer.ifPresent { footerViewModel ->
+            // The footer needs to be re-inflated every time the theme or the font size changes.
+            view.repeatWhenAttached {
+                LayoutInflater.from(view.context).reinflateAndBindLatest(
+                    R.layout.status_bar_notification_footer,
+                    view,
+                    attachToRoot = false,
+                    // TODO(b/305930747): This may lead to duplicate invocations if both flows emit,
+                    // find a solution to only emit one event.
+                    merge(
+                        configurationController.onThemeChanged,
+                        configurationController.onDensityOrFontScaleChanged,
+                    ),
+                ) { view ->
+                    traceSection("bind FooterView") {
+                        FooterViewBinder.bind(view as FooterView, footerViewModel)
+                    }
+                }
+            }
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt
index 11f68e0..261371d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt
@@ -17,8 +17,9 @@
 package com.android.systemui.statusbar.notification.stack.ui.viewmodel
 
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.FeatureFlagsClassic
 import com.android.systemui.flags.Flags
+import com.android.systemui.statusbar.notification.footer.ui.viewmodel.FooterViewModel
 import com.android.systemui.statusbar.notification.shelf.ui.viewmodel.NotificationShelfViewModel
 import dagger.Module
 import dagger.Provides
@@ -28,6 +29,7 @@
 /** ViewModel for the list of notifications. */
 class NotificationListViewModel(
     val shelf: NotificationShelfViewModel,
+    val footer: Optional<FooterViewModel>,
 )
 
 @Module
@@ -36,12 +38,33 @@
     @Provides
     @SysUISingleton
     fun maybeProvideViewModel(
-        featureFlags: FeatureFlags,
+        featureFlags: FeatureFlagsClassic,
         shelfViewModel: Provider<NotificationShelfViewModel>,
-    ): Optional<NotificationListViewModel> =
-        if (featureFlags.isEnabled(Flags.NOTIFICATION_SHELF_REFACTOR)) {
-            Optional.of(NotificationListViewModel(shelfViewModel.get()))
+        footerViewModel: Provider<FooterViewModel>,
+    ): Optional<NotificationListViewModel> {
+        return if (featureFlags.isEnabled(Flags.NOTIFICATION_SHELF_REFACTOR)) {
+            if (com.android.systemui.Flags.notificationsFooterViewRefactor()) {
+                Optional.of(
+                    NotificationListViewModel(
+                        shelfViewModel.get(),
+                        Optional.of(footerViewModel.get())
+                    )
+                )
+            } else {
+                Optional.of(NotificationListViewModel(shelfViewModel.get(), Optional.empty()))
+            }
         } else {
+            if (com.android.systemui.Flags.notificationsFooterViewRefactor()) {
+                throw IllegalStateException(
+                    "The com.android.systemui.notifications_footer_view_refactor flag requires " +
+                        "the notification_shelf_refactor flag to be enabled. First disable the " +
+                        "footer flag using `adb shell device_config put systemui " +
+                        "com.android.systemui.notifications_footer_view_refactor false`, then " +
+                        "enable the notification_shelf_refactor flag in Flag Flipper. " +
+                        "Afterwards, you can try re-enabling the footer refactor flag via adb."
+                )
+            }
             Optional.empty()
         }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
index 07d3a1c..2d125462 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
@@ -30,7 +30,6 @@
 import android.view.WindowManager
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.ActivityIntentHelper
-import com.android.systemui.res.R
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.animation.ActivityLaunchAnimator.PendingIntentStarter
 import com.android.systemui.animation.DelegateLaunchAnimatorController
@@ -43,6 +42,7 @@
 import com.android.systemui.keyguard.WakefulnessLifecycle
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction
+import com.android.systemui.res.R
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.shade.ShadeController
 import com.android.systemui.shade.ShadeViewController
@@ -134,6 +134,19 @@
         )
     }
 
+    override fun startPendingIntentMaybeDismissingKeyguard(
+        intent: PendingIntent,
+        intentSentUiThreadCallback: Runnable?,
+        animationController: ActivityLaunchAnimator.Controller?
+    ) {
+        activityStarterInternal.startPendingIntentDismissingKeyguard(
+            intent = intent,
+            intentSentUiThreadCallback = intentSentUiThreadCallback,
+            animationController = animationController,
+            showOverLockscreen = true,
+        )
+    }
+
     /**
      * TODO(b/279084380): Change callers to just call startActivityDismissingKeyguard and deprecate
      *   this.
@@ -454,7 +467,7 @@
                     !willLaunchResolverActivity &&
                     shouldAnimateLaunch(isActivityIntent = true)
             val animController =
-                wrapAnimationController(
+                wrapAnimationControllerForShadeOrStatusBar(
                     animationController = animationController,
                     dismissShade = dismissShade,
                     isLaunchForActivity = true,
@@ -547,12 +560,18 @@
             )
         }
 
-        /** Starts a pending intent after dismissing keyguard. */
+        /**
+         * Starts a pending intent after dismissing keyguard.
+         *
+         * This can be called in a background thread (to prevent calls in [ActivityIntentHelper] in
+         * the main thread).
+         */
         fun startPendingIntentDismissingKeyguard(
             intent: PendingIntent,
             intentSentUiThreadCallback: Runnable? = null,
             associatedView: View? = null,
             animationController: ActivityLaunchAnimator.Controller? = null,
+            showOverLockscreen: Boolean = false,
         ) {
             val animationController =
                 if (associatedView is ExpandableNotificationRow) {
@@ -566,79 +585,103 @@
                         lockScreenUserManager.currentUserId,
                     ))
 
+            val actuallyShowOverLockscreen =
+                showOverLockscreen &&
+                    intent.isActivity &&
+                    activityIntentHelper.wouldPendingShowOverLockscreen(
+                        intent,
+                        lockScreenUserManager.currentUserId
+                    )
+
             val animate =
                 !willLaunchResolverActivity &&
                     animationController != null &&
-                    shouldAnimateLaunch(intent.isActivity)
+                    shouldAnimateLaunch(intent.isActivity, actuallyShowOverLockscreen)
+
+            // We wrap animationCallback with a StatusBarLaunchAnimatorController so
+            // that the shade is collapsed after the animation (or when it is cancelled,
+            // aborted, etc).
+            val statusBarController =
+                wrapAnimationControllerForShadeOrStatusBar(
+                    animationController = animationController,
+                    dismissShade = true,
+                    isLaunchForActivity = intent.isActivity,
+                )
+            val controller =
+                if (actuallyShowOverLockscreen) {
+                    wrapAnimationControllerForLockscreen(statusBarController)
+                } else {
+                    statusBarController
+                }
 
             // If we animate, don't collapse the shade and defer the keyguard dismiss (in case we
             // run the animation on the keyguard). The animation will take care of (instantly)
             // collapsing the shade and hiding the keyguard once it is done.
             val collapse = !animate
-            executeRunnableDismissingKeyguard(
-                runnable = {
-                    try {
-                        // We wrap animationCallback with a StatusBarLaunchAnimatorController so
-                        // that the shade is collapsed after the animation (or when it is cancelled,
-                        // aborted, etc).
-                        val controller: ActivityLaunchAnimator.Controller? =
-                            wrapAnimationController(
-                                animationController = animationController,
-                                dismissShade = true,
-                                isLaunchForActivity = intent.isActivity,
-                            )
-                        activityLaunchAnimator.startPendingIntentWithAnimation(
-                            controller,
-                            animate,
-                            intent.creatorPackage,
-                            object : PendingIntentStarter {
-                                override fun startPendingIntent(
-                                    animationAdapter: RemoteAnimationAdapter?
-                                ): Int {
-                                    val options =
-                                        ActivityOptions(
-                                            CentralSurfaces.getActivityOptions(
-                                                displayId,
-                                                animationAdapter
-                                            )
+            val runnable = Runnable {
+                try {
+                    activityLaunchAnimator.startPendingIntentWithAnimation(
+                        controller,
+                        animate,
+                        intent.creatorPackage,
+                        actuallyShowOverLockscreen,
+                        object : PendingIntentStarter {
+                            override fun startPendingIntent(
+                                animationAdapter: RemoteAnimationAdapter?
+                            ): Int {
+                                val options =
+                                    ActivityOptions(
+                                        CentralSurfaces.getActivityOptions(
+                                            displayId,
+                                            animationAdapter
                                         )
-                                    // TODO b/221255671: restrict this to only be set for
-                                    // notifications
-                                    options.isEligibleForLegacyPermissionPrompt = true
-                                    options.setPendingIntentBackgroundActivityStartMode(
-                                        ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
                                     )
-                                    return intent.sendAndReturnResult(
-                                        null,
-                                        0,
-                                        null,
-                                        null,
-                                        null,
-                                        null,
-                                        options.toBundle()
-                                    )
-                                }
-                            },
-                        )
-                    } catch (e: PendingIntent.CanceledException) {
-                        // the stack trace isn't very helpful here.
-                        // Just log the exception message.
-                        Log.w(TAG, "Sending intent failed: $e")
-                        if (!collapse) {
-                            // executeRunnableDismissingKeyguard did not collapse for us already.
-                            shadeControllerLazy.get().collapseOnMainThread()
-                        }
-                        // TODO: Dismiss Keyguard.
+                                // TODO b/221255671: restrict this to only be set for
+                                // notifications
+                                options.isEligibleForLegacyPermissionPrompt = true
+                                options.setPendingIntentBackgroundActivityStartMode(
+                                    ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+                                )
+                                return intent.sendAndReturnResult(
+                                    null,
+                                    0,
+                                    null,
+                                    null,
+                                    null,
+                                    null,
+                                    options.toBundle()
+                                )
+                            }
+                        },
+                    )
+                } catch (e: PendingIntent.CanceledException) {
+                    // the stack trace isn't very helpful here.
+                    // Just log the exception message.
+                    Log.w(TAG, "Sending intent failed: $e")
+                    if (!collapse) {
+                        // executeRunnableDismissingKeyguard did not collapse for us already.
+                        shadeControllerLazy.get().collapseOnMainThread()
                     }
-                    if (intent.isActivity) {
-                        assistManagerLazy.get().hideAssist()
-                    }
-                    intentSentUiThreadCallback?.let { postOnUiThread(runnable = it) }
-                },
-                afterKeyguardGone = willLaunchResolverActivity,
-                dismissShade = collapse,
-                willAnimateOnKeyguard = animate,
-            )
+                    // TODO: Dismiss Keyguard.
+                }
+                if (intent.isActivity) {
+                    assistManagerLazy.get().hideAssist()
+                }
+                intentSentUiThreadCallback?.let { postOnUiThread(runnable = it) }
+            }
+
+            if (!actuallyShowOverLockscreen) {
+                postOnUiThread(delay = 0) {
+                    executeRunnableDismissingKeyguard(
+                        runnable = runnable,
+                        afterKeyguardGone = willLaunchResolverActivity,
+                        dismissShade = collapse,
+                        willAnimateOnKeyguard = animate,
+                    )
+                }
+            } else {
+                postOnUiThread(delay = 0, runnable)
+            }
         }
 
         /** Starts an Activity. */
@@ -678,71 +721,12 @@
                 // Wrap the animation controller to dismiss the shade and set
                 // mIsLaunchingActivityOverLockscreen during the animation.
                 val delegate =
-                    wrapAnimationController(
+                    wrapAnimationControllerForShadeOrStatusBar(
                         animationController = animationController,
                         dismissShade = dismissShade,
                         isLaunchForActivity = true,
                     )
-                delegate?.let {
-                    controller =
-                        object : DelegateLaunchAnimatorController(delegate) {
-                            override fun onIntentStarted(willAnimate: Boolean) {
-                                delegate?.onIntentStarted(willAnimate)
-                                if (willAnimate) {
-                                    centralSurfaces?.setIsLaunchingActivityOverLockscreen(true)
-                                }
-                            }
-
-                            override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
-                                super.onLaunchAnimationStart(isExpandingFullyAbove)
-
-                                // Double check that the keyguard is still showing and not going
-                                // away, but if so set the keyguard occluded. Typically, WM will let
-                                // KeyguardViewMediator know directly, but we're overriding that to
-                                // play the custom launch animation, so we need to take care of that
-                                // here. The unocclude animation is not overridden, so WM will call
-                                // KeyguardViewMediator's unocclude animation runner when the
-                                // activity is exited.
-                                if (
-                                    keyguardStateController.isShowing &&
-                                        !keyguardStateController.isKeyguardGoingAway
-                                ) {
-                                    Log.d(TAG, "Setting occluded = true in #startActivity.")
-                                    keyguardViewMediatorLazy
-                                        .get()
-                                        .setOccluded(true /* isOccluded */, true /* animate */)
-                                }
-                            }
-
-                            override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
-                                // Set mIsLaunchingActivityOverLockscreen to false before actually
-                                // finishing the animation so that we can assume that
-                                // mIsLaunchingActivityOverLockscreen being true means that we will
-                                // collapse the shade (or at least run the post collapse runnables)
-                                // later on.
-                                centralSurfaces?.setIsLaunchingActivityOverLockscreen(false)
-                                delegate?.onLaunchAnimationEnd(isExpandingFullyAbove)
-                            }
-
-                            override fun onLaunchAnimationCancelled(
-                                newKeyguardOccludedState: Boolean?
-                            ) {
-                                if (newKeyguardOccludedState != null) {
-                                    keyguardViewMediatorLazy
-                                        .get()
-                                        .setOccluded(newKeyguardOccludedState, false /* animate */)
-                                }
-
-                                // Set mIsLaunchingActivityOverLockscreen to false before actually
-                                // finishing the animation so that we can assume that
-                                // mIsLaunchingActivityOverLockscreen being true means that we will
-                                // collapse the shade (or at least run the // post collapse
-                                // runnables) later on.
-                                centralSurfaces?.setIsLaunchingActivityOverLockscreen(false)
-                                delegate.onLaunchAnimationCancelled(newKeyguardOccludedState)
-                            }
-                        }
-                }
+                controller = wrapAnimationControllerForLockscreen(delegate)
             } else if (dismissShade) {
                 // The animation will take care of dismissing the shade at the end of the animation.
                 // If we don't animate, collapse it directly.
@@ -874,7 +858,7 @@
          *   window.
          * @param isLaunchForActivity whether the launch is for an activity.
          */
-        private fun wrapAnimationController(
+        private fun wrapAnimationControllerForShadeOrStatusBar(
             animationController: ActivityLaunchAnimator.Controller?,
             dismissShade: Boolean,
             isLaunchForActivity: Boolean,
@@ -909,6 +893,72 @@
             return animationController
         }
 
+        /**
+         * Wraps an animation controller so that if an activity would be launched on top of the
+         * lockscreen, the correct flags are set for it to be occluded.
+         */
+        private fun wrapAnimationControllerForLockscreen(
+            animationController: ActivityLaunchAnimator.Controller?
+        ): ActivityLaunchAnimator.Controller? {
+            return animationController?.let {
+                object : DelegateLaunchAnimatorController(it) {
+                    override fun onIntentStarted(willAnimate: Boolean) {
+                        delegate.onIntentStarted(willAnimate)
+                        if (willAnimate) {
+                            centralSurfaces?.setIsLaunchingActivityOverLockscreen(true)
+                        }
+                    }
+
+                    override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
+                        super.onLaunchAnimationStart(isExpandingFullyAbove)
+
+                        // Double check that the keyguard is still showing and not going
+                        // away, but if so set the keyguard occluded. Typically, WM will let
+                        // KeyguardViewMediator know directly, but we're overriding that to
+                        // play the custom launch animation, so we need to take care of that
+                        // here. The unocclude animation is not overridden, so WM will call
+                        // KeyguardViewMediator's unocclude animation runner when the
+                        // activity is exited.
+                        if (
+                            keyguardStateController.isShowing &&
+                                !keyguardStateController.isKeyguardGoingAway
+                        ) {
+                            Log.d(TAG, "Setting occluded = true in #startActivity.")
+                            keyguardViewMediatorLazy
+                                .get()
+                                .setOccluded(true /* isOccluded */, true /* animate */)
+                        }
+                    }
+
+                    override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
+                        // Set mIsLaunchingActivityOverLockscreen to false before actually
+                        // finishing the animation so that we can assume that
+                        // mIsLaunchingActivityOverLockscreen being true means that we will
+                        // collapse the shade (or at least run the post collapse runnables)
+                        // later on.
+                        centralSurfaces?.setIsLaunchingActivityOverLockscreen(false)
+                        delegate.onLaunchAnimationEnd(isExpandingFullyAbove)
+                    }
+
+                    override fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean?) {
+                        if (newKeyguardOccludedState != null) {
+                            keyguardViewMediatorLazy
+                                .get()
+                                .setOccluded(newKeyguardOccludedState, false /* animate */)
+                        }
+
+                        // Set mIsLaunchingActivityOverLockscreen to false before actually
+                        // finishing the animation so that we can assume that
+                        // mIsLaunchingActivityOverLockscreen being true means that we will
+                        // collapse the shade (or at least run the // post collapse
+                        // runnables) later on.
+                        centralSurfaces?.setIsLaunchingActivityOverLockscreen(false)
+                        delegate.onLaunchAnimationCancelled(newKeyguardOccludedState)
+                    }
+                }
+            }
+        }
+
         /** Retrieves the current user handle to start the Activity. */
         private fun getActivityUserHandle(intent: Intent): UserHandle {
             val packages: Array<String> =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index aa3b411..fa2e3a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -202,7 +202,6 @@
 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
 import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
-import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository;
 import com.android.systemui.statusbar.notification.init.NotificationsController;
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -296,7 +295,6 @@
     private CentralSurfacesCommandQueueCallbacks mCommandQueueCallbacks;
     private float mTransitionToFullShadeProgress = 0f;
     private final NotificationListContainer mNotifListContainer;
-    private final NotificationExpansionRepository mNotificationExpansionRepository;
     private boolean mIsShortcutListSearchEnabled;
 
     private final KeyguardStateController.Callback mKeyguardStateControllerCallback =
@@ -650,7 +648,6 @@
             Lazy<NotificationPresenter> notificationPresenterLazy,
             Lazy<NotificationActivityStarter> notificationActivityStarterLazy,
             NotificationLaunchAnimatorControllerProvider notifLaunchAnimatorControllerProvider,
-            NotificationExpansionRepository notificationExpansionRepository,
             DozeParameters dozeParameters,
             ScrimController scrimController,
             Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
@@ -759,7 +756,6 @@
         mPresenterLazy = notificationPresenterLazy;
         mNotificationActivityStarterLazy = notificationActivityStarterLazy;
         mNotificationAnimationProvider = notifLaunchAnimatorControllerProvider;
-        mNotificationExpansionRepository = notificationExpansionRepository;
         mDozeServiceHost = dozeServiceHost;
         mPowerManager = powerManager;
         mDozeParameters = dozeParameters;
@@ -813,6 +809,8 @@
                 mShadeExpansionStateManager.addExpansionListener(shadeExpansionListener);
         shadeExpansionListener.onPanelExpansionChanged(currentState);
 
+        mShadeExpansionStateManager.addFullExpansionListener(this::onShadeExpansionFullyChanged);
+
         mActivityIntentHelper = new ActivityIntentHelper(mContext);
         mActivityLaunchAnimator = activityLaunchAnimator;
 
@@ -1399,6 +1397,20 @@
         }
     }
 
+    @VisibleForTesting
+    void onShadeExpansionFullyChanged(Boolean isExpanded) {
+        if (isExpanded && mStatusBarStateController.getState() != StatusBarState.KEYGUARD) {
+            if (DEBUG) {
+                Log.v(TAG, "clearing notification effects from Height");
+            }
+            clearNotificationEffects();
+        }
+
+        if (!isExpanded) {
+            mRemoteInputManager.onPanelCollapsed();
+        }
+    }
+
     @NonNull
     @Override
     public Lifecycle getLifecycle() {
@@ -3090,7 +3102,9 @@
             }
             // TODO: Bring these out of CentralSurfaces.
             mUserInfoControllerImpl.onDensityOrFontScaleChanged();
-            mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
+            if (!mFeatureFlags.isEnabled(Flags.NOTIFICATION_ICON_CONTAINER_REFACTOR)) {
+                mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
+            }
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
index d3d11ea..66341ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
@@ -37,6 +37,8 @@
 import com.android.systemui.doze.DozeHost;
 import com.android.systemui.doze.DozeLog;
 import com.android.systemui.doze.DozeReceiver;
+import com.android.systemui.flags.FeatureFlagsClassic;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.keyguard.domain.interactor.DozeInteractor;
 import com.android.systemui.shade.NotificationShadeWindowViewController;
@@ -82,6 +84,7 @@
     private final SysuiStatusBarStateController mStatusBarStateController;
     private final DeviceProvisionedController mDeviceProvisionedController;
     private final HeadsUpManager mHeadsUpManager;
+    private final FeatureFlagsClassic mFeatureFlags;
     private final BatteryController mBatteryController;
     private final ScrimController mScrimController;
     private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
@@ -107,6 +110,7 @@
             WakefulnessLifecycle wakefulnessLifecycle,
             SysuiStatusBarStateController statusBarStateController,
             DeviceProvisionedController deviceProvisionedController,
+            FeatureFlagsClassic featureFlags,
             HeadsUpManager headsUpManager, BatteryController batteryController,
             ScrimController scrimController,
             Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
@@ -130,6 +134,7 @@
         mBiometricUnlockControllerLazy = biometricUnlockControllerLazy;
         mAssistManagerLazy = assistManagerLazy;
         mDozeScrimController = dozeScrimController;
+        mFeatureFlags = featureFlags;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mPulseExpansionHandler = pulseExpansionHandler;
         mNotificationShadeWindowController = notificationShadeWindowController;
@@ -173,8 +178,13 @@
 
     void fireNotificationPulse(NotificationEntry entry) {
         Runnable pulseSuppressedListener = () -> {
-            entry.setPulseSuppressed(true);
-            mNotificationIconAreaController.updateAodNotificationIcons();
+            if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_ICON_CONTAINER_REFACTOR)) {
+                mHeadsUpManager.removeNotification(
+                        entry.getKey(), /* releaseImmediately= */ true, /* animate= */ false);
+            } else {
+                entry.setPulseSuppressed(true);
+                mNotificationIconAreaController.updateAodNotificationIcons();
+            }
         };
         Assert.isMainThread();
         for (Callback callback : mCallbacks) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index c493eeda..8fee5c0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -26,6 +26,8 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.widget.ViewClippingUtil;
+import com.android.systemui.flags.FeatureFlagsClassic;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.res.R;
@@ -38,6 +40,7 @@
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.SourceType;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationIconInteractor;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
@@ -104,6 +107,8 @@
             };
     private boolean mAnimationsEnabled = true;
     private final KeyguardStateController mKeyguardStateController;
+    private final FeatureFlagsClassic mFeatureFlags;
+    private final HeadsUpNotificationIconInteractor mHeadsUpNotificationIconInteractor;
 
     @VisibleForTesting
     @Inject
@@ -122,6 +127,8 @@
             NotificationRoundnessManager notificationRoundnessManager,
             HeadsUpStatusBarView headsUpStatusBarView,
             Clock clockView,
+            FeatureFlagsClassic featureFlags,
+            HeadsUpNotificationIconInteractor headsUpNotificationIconInteractor,
             @Named(OPERATOR_NAME_FRAME_VIEW) Optional<View> operatorNameViewOptional) {
         super(headsUpStatusBarView);
         mNotificationIconAreaController = notificationIconAreaController;
@@ -139,6 +146,8 @@
 
         mStackScrollerController = stackScrollerController;
         mShadeViewController = shadeViewController;
+        mFeatureFlags = featureFlags;
+        mHeadsUpNotificationIconInteractor = headsUpNotificationIconInteractor;
         mStackScrollerController.setHeadsUpAppearanceController(this);
         mClockView = clockView;
         mOperatorNameViewOptional = operatorNameViewOptional;
@@ -170,6 +179,9 @@
         mHeadsUpManager.addListener(this);
         mView.setOnDrawingRectChangedListener(
                 () -> updateIsolatedIconLocation(true /* requireUpdate */));
+        if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_ICON_CONTAINER_REFACTOR)) {
+            updateIsolatedIconLocation(true);
+        }
         mWakeUpCoordinator.addListener(this);
         getShadeHeadsUpTracker().addTrackingHeadsUpListener(mSetTrackingHeadsUp);
         getShadeHeadsUpTracker().setHeadsUpAppearanceController(this);
@@ -185,6 +197,9 @@
     protected void onViewDetached() {
         mHeadsUpManager.removeListener(this);
         mView.setOnDrawingRectChangedListener(null);
+        if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_ICON_CONTAINER_REFACTOR)) {
+            mHeadsUpNotificationIconInteractor.setIsolatedIconLocation(null);
+        }
         mWakeUpCoordinator.removeListener(this);
         getShadeHeadsUpTracker().removeTrackingHeadsUpListener(mSetTrackingHeadsUp);
         getShadeHeadsUpTracker().setHeadsUpAppearanceController(null);
@@ -193,8 +208,13 @@
     }
 
     private void updateIsolatedIconLocation(boolean requireStateUpdate) {
-        mNotificationIconAreaController.setIsolatedIconLocation(
-                mView.getIconDrawingRect(), requireStateUpdate);
+        if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_ICON_CONTAINER_REFACTOR)) {
+            mHeadsUpNotificationIconInteractor
+                    .setIsolatedIconLocation(mView.getIconDrawingRect());
+        } else {
+            mNotificationIconAreaController.setIsolatedIconLocation(
+                    mView.getIconDrawingRect(), requireStateUpdate);
+        }
     }
 
     @Override
@@ -230,9 +250,14 @@
                 setShown(true);
                 animateIsolation = !isExpanded();
             }
-            updateIsolatedIconLocation(false /* requireUpdate */);
-            mNotificationIconAreaController.showIconIsolated(newEntry == null ? null
-                    : newEntry.getIcons().getStatusBarIcon(), animateIsolation);
+            if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_ICON_CONTAINER_REFACTOR)) {
+                mHeadsUpNotificationIconInteractor.setIsolatedIconNotificationKey(
+                        newEntry == null ? null : newEntry.getKey());
+            } else {
+                updateIsolatedIconLocation(false /* requireUpdate */);
+                mNotificationIconAreaController.showIconIsolated(newEntry == null ? null
+                        : newEntry.getIcons().getStatusBarIcon(), animateIsolation);
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index 3a95e6d..f4862c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -34,7 +34,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.res.R;
-import com.android.systemui.shade.domain.interactor.ShadeInteractor;
+import com.android.systemui.shade.ShadeExpansionStateManager;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.provider.OnReorderingAllowedListener;
@@ -48,7 +48,6 @@
 import com.android.systemui.statusbar.policy.HeadsUpManagerLogger;
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
 import com.android.systemui.statusbar.policy.OnHeadsUpPhoneListenerChange;
-import com.android.systemui.util.kotlin.JavaAdapter;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -106,8 +105,7 @@
     ///////////////////////////////////////////////////////////////////////////////////////////////
     //  Constructor:
     @Inject
-    public HeadsUpManagerPhone(
-            @NonNull final Context context,
+    public HeadsUpManagerPhone(@NonNull final Context context,
             HeadsUpManagerLogger logger,
             StatusBarStateController statusBarStateController,
             KeyguardBypassController bypassController,
@@ -117,8 +115,7 @@
             @Main Handler handler,
             AccessibilityManagerWrapper accessibilityManagerWrapper,
             UiEventLogger uiEventLogger,
-            JavaAdapter javaAdapter,
-            ShadeInteractor shadeInteractor) {
+            ShadeExpansionStateManager shadeExpansionStateManager) {
         super(context, logger, handler, accessibilityManagerWrapper, uiEventLogger);
         Resources resources = mContext.getResources();
         mExtensionTime = resources.getInteger(R.integer.ambient_notification_extension_time);
@@ -139,7 +136,8 @@
                 updateResources();
             }
         });
-        javaAdapter.alwaysCollectFlow(shadeInteractor.isAnyExpanded(), this::onShadeOrQsExpanded);
+
+        shadeExpansionStateManager.addFullExpansionListener(this::onShadeExpansionFullyChanged);
     }
 
     public void setAnimationStateHandler(AnimationStateHandler handler) {
@@ -232,7 +230,7 @@
         mTrackingHeadsUp = trackingHeadsUp;
     }
 
-    private void onShadeOrQsExpanded(Boolean isExpanded) {
+    private void onShadeExpansionFullyChanged(Boolean isExpanded) {
         if (isExpanded != mIsExpanded) {
             mIsExpanded = isExpanded;
             if (isExpanded) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java
index f9856b0..4284c96c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java
@@ -448,7 +448,7 @@
             }
         }
         replacingIcons.removeAll(duplicates);
-        hostLayout.setReplacingIcons(replacingIcons);
+        hostLayout.setReplacingIconsLegacy(replacingIcons);
 
         final int toRemoveCount = toRemove.size();
         for (int i = 0; i < toRemoveCount; i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index b15c0fd..535f6ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -40,6 +40,8 @@
 import com.android.app.animation.Interpolators;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.settingslib.Utils;
+import com.android.systemui.flags.Flags;
+import com.android.systemui.flags.RefactorFlag;
 import com.android.systemui.res.R;
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.notification.stack.AnimationFilter;
@@ -131,6 +133,9 @@
         }
     }.setDuration(CONTENT_FADE_DURATION);
 
+    private final RefactorFlag mIconContainerRefactorFlag =
+            RefactorFlag.forView(Flags.NOTIFICATION_ICON_CONTAINER_REFACTOR);
+
     /* Maximum number of icons on AOD when also showing overflow dot. */
     private int mMaxIconsOnAod;
 
@@ -156,7 +161,8 @@
     private int mIconSize;
     private boolean mDisallowNextAnimation;
     private boolean mAnimationsEnabled = true;
-    private ArrayMap<String, ArrayList<StatusBarIcon>> mReplacingIcons;
+    private ArrayMap<String, StatusBarIcon> mReplacingIcons;
+    private ArrayMap<String, ArrayList<StatusBarIcon>> mReplacingIconsLegacy;
     // Keep track of the last visible icon so collapsed container can report on its location
     private IconState mLastVisibleIconState;
     private IconState mFirstVisibleIconState;
@@ -167,6 +173,7 @@
     private final int[] mAbsolutePosition = new int[2];
     private View mIsolatedIconForAnimation;
     private int mThemedTextColorPrimary;
+    private Runnable mIsolatedIconAnimationEndRunnable;
 
     public NotificationIconContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -339,23 +346,29 @@
     }
 
     private boolean isReplacingIcon(View child) {
-        if (mReplacingIcons == null) {
-            return false;
-        }
         if (!(child instanceof StatusBarIconView)) {
             return false;
         }
         StatusBarIconView iconView = (StatusBarIconView) child;
         Icon sourceIcon = iconView.getSourceIcon();
         String groupKey = iconView.getNotification().getGroupKey();
-        ArrayList<StatusBarIcon> statusBarIcons = mReplacingIcons.get(groupKey);
-        if (statusBarIcons != null) {
-            StatusBarIcon replacedIcon = statusBarIcons.get(0);
-            if (sourceIcon.sameAs(replacedIcon.icon)) {
-                return true;
+        if (mIconContainerRefactorFlag.isEnabled()) {
+            if (mReplacingIcons == null) {
+                return false;
             }
+            StatusBarIcon replacedIcon = mReplacingIcons.get(groupKey);
+            return replacedIcon != null && sourceIcon.sameAs(replacedIcon.icon);
+        } else {
+            if (mReplacingIconsLegacy == null) {
+                return false;
+            }
+            ArrayList<StatusBarIcon> statusBarIcons = mReplacingIconsLegacy.get(groupKey);
+            if (statusBarIcons != null) {
+                StatusBarIcon replacedIcon = statusBarIcons.get(0);
+                return sourceIcon.sameAs(replacedIcon.icon);
+            }
+            return false;
         }
-        return false;
     }
 
     @Override
@@ -681,14 +694,36 @@
         mAnimationsEnabled = enabled;
     }
 
-    public void setReplacingIcons(ArrayMap<String, ArrayList<StatusBarIcon>> replacingIcons) {
+    public void setReplacingIconsLegacy(ArrayMap<String, ArrayList<StatusBarIcon>> replacingIcons) {
+        mIconContainerRefactorFlag.assertInLegacyMode();
+        mReplacingIconsLegacy = replacingIcons;
+    }
+
+    public void setReplacingIcons(ArrayMap<String, StatusBarIcon> replacingIcons) {
+        if (mIconContainerRefactorFlag.isUnexpectedlyInLegacyMode()) return;
         mReplacingIcons = replacingIcons;
     }
 
+    @Deprecated
     public void showIconIsolated(StatusBarIconView icon, boolean animated) {
+        mIconContainerRefactorFlag.assertInLegacyMode();
         if (animated) {
-            mIsolatedIconForAnimation = icon != null ? icon : mIsolatedIcon;
+            showIconIsolatedAnimated(icon, null);
+        } else {
+            showIconIsolated(icon);
         }
+    }
+
+    public void showIconIsolatedAnimated(StatusBarIconView icon,
+            @Nullable Runnable onAnimationEnd) {
+        if (mIconContainerRefactorFlag.isUnexpectedlyInLegacyMode()) return;
+        mIsolatedIconForAnimation = icon != null ? icon : mIsolatedIcon;
+        mIsolatedIconAnimationEndRunnable = onAnimationEnd;
+        showIconIsolated(icon);
+    }
+
+    public void showIconIsolated(StatusBarIconView icon) {
+        if (mIconContainerRefactorFlag.isUnexpectedlyInLegacyMode()) return;
         mIsolatedIcon = icon;
         updateState();
     }
@@ -813,6 +848,11 @@
                             animationProperties = UNISOLATION_PROPERTY;
                             animationProperties.setDelay(
                                     mIsolatedIcon != null ? CONTENT_FADE_DELAY : 0);
+                            Consumer<Property> endAction = getEndAction();
+                            if (endAction != null) {
+                                animationProperties.setAnimationEndAction(endAction);
+                                animationProperties.setAnimationCancelAction(endAction);
+                            }
                         } else {
                             animationProperties = UNISOLATION_PROPERTY_OTHERS;
                             animationProperties.setDelay(
@@ -836,6 +876,18 @@
             needsCannedAnimation = false;
         }
 
+        @Nullable
+        private Consumer<Property> getEndAction() {
+            if (mIsolatedIconAnimationEndRunnable == null) return null;
+            final Runnable endRunnable = mIsolatedIconAnimationEndRunnable;
+            return prop -> {
+                endRunnable.run();
+                if (mIsolatedIconAnimationEndRunnable == endRunnable) {
+                    mIsolatedIconAnimationEndRunnable = null;
+                }
+            };
+        }
+
         @Override
         public void initFrom(View view) {
             super.initFrom(view);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHideIconsForBouncerManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHideIconsForBouncerManager.kt
index fa6d279..4d9de09 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHideIconsForBouncerManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHideIconsForBouncerManager.kt
@@ -3,15 +3,12 @@
 import android.app.StatusBarManager
 import com.android.systemui.Dumpable
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
-import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.ShadeExpansionStateManager
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.window.StatusBarWindowStateController
 import com.android.systemui.util.concurrency.DelayableExecutor
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
 import java.io.PrintWriter
 import javax.inject.Inject
 
@@ -28,14 +25,14 @@
  */
 @SysUISingleton
 class StatusBarHideIconsForBouncerManager @Inject constructor(
-    @Application private val scope: CoroutineScope,
-    private val commandQueue: CommandQueue,
-    @Main private val mainExecutor: DelayableExecutor,
-    statusBarWindowStateController: StatusBarWindowStateController,
-    val shadeInteractor: ShadeInteractor,
-    dumpManager: DumpManager
+        private val commandQueue: CommandQueue,
+        @Main private val mainExecutor: DelayableExecutor,
+        statusBarWindowStateController: StatusBarWindowStateController,
+        shadeExpansionStateManager: ShadeExpansionStateManager,
+        dumpManager: DumpManager
 ) : Dumpable {
     // State variables set by external classes.
+    private var panelExpanded: Boolean = false
     private var isOccluded: Boolean = false
     private var bouncerShowing: Boolean = false
     private var topAppHidesStatusBar: Boolean = false
@@ -52,9 +49,10 @@
         statusBarWindowStateController.addListener {
                 state -> setStatusBarStateAndTriggerUpdate(state)
         }
-        scope.launch {
-            shadeInteractor.isAnyExpanded.collect {
-                updateHideIconsForBouncer(false)
+        shadeExpansionStateManager.addFullExpansionListener { isExpanded ->
+            if (panelExpanded != isExpanded) {
+                panelExpanded = isExpanded
+                updateHideIconsForBouncer(animate = false)
             }
         }
     }
@@ -103,7 +101,7 @@
             topAppHidesStatusBar &&
                     isOccluded &&
                     (statusBarWindowHidden || bouncerShowing)
-        val hideBecauseKeyguard = !isShadeOrQsExpanded() && !isOccluded && bouncerShowing
+        val hideBecauseKeyguard = !panelExpanded && !isOccluded && bouncerShowing
         val shouldHideIconsForBouncer = hideBecauseApp || hideBecauseKeyguard
         if (hideIconsForBouncer != shouldHideIconsForBouncer) {
             hideIconsForBouncer = shouldHideIconsForBouncer
@@ -127,13 +125,9 @@
         }
     }
 
-    private fun isShadeOrQsExpanded(): Boolean {
-        return shadeInteractor.isAnyExpanded.value
-    }
-
     override fun dump(pw: PrintWriter, args: Array<out String>) {
         pw.println("---- State variables set externally ----")
-        pw.println("isShadeOrQsExpanded=${isShadeOrQsExpanded()}")
+        pw.println("panelExpanded=$panelExpanded")
         pw.println("isOccluded=$isOccluded")
         pw.println("bouncerShowing=$bouncerShowing")
         pw.println("topAppHideStatusBar=$topAppHidesStatusBar")
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
index 6d8ec44..ba73c10 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
@@ -39,7 +39,6 @@
 import com.android.systemui.scene.domain.interactor.SceneInteractor;
 import com.android.systemui.scene.shared.flag.SceneContainerFlags;
 import com.android.systemui.shade.ShadeExpansionStateManager;
-import com.android.systemui.shade.domain.interactor.ShadeInteractor;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
@@ -87,9 +86,8 @@
             ConfigurationController configurationController,
             HeadsUpManager headsUpManager,
             ShadeExpansionStateManager shadeExpansionStateManager,
-            ShadeInteractor shadeInteractor,
             Provider<SceneInteractor> sceneInteractor,
-            JavaAdapter javaAdapter,
+            Provider<JavaAdapter> javaAdapter,
             SceneContainerFlags sceneContainerFlags,
             UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
             PrimaryBouncerInteractor primaryBouncerInteractor,
@@ -128,12 +126,12 @@
         });
 
         mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
-        javaAdapter.alwaysCollectFlow(shadeInteractor.isAnyExpanded(), this::onShadeOrQsExpanded);
+        shadeExpansionStateManager.addFullExpansionListener(this::onShadeExpansionFullyChanged);
 
         if (sceneContainerFlags.isEnabled()) {
-            javaAdapter.alwaysCollectFlow(
+            javaAdapter.get().alwaysCollectFlow(
                     sceneInteractor.get().isVisible(),
-                    this::onShadeOrQsExpanded);
+                    this::onShadeExpansionFullyChanged);
         }
 
         mPrimaryBouncerInteractor = primaryBouncerInteractor;
@@ -153,7 +151,7 @@
         pw.println(mTouchableRegion);
     }
 
-    private void onShadeOrQsExpanded(Boolean isExpanded) {
+    private void onShadeExpansionFullyChanged(Boolean isExpanded) {
         if (isExpanded != mIsStatusBarExpanded) {
             mIsStatusBarExpanded = isExpanded;
             if (isExpanded) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index 63c022c..e2a4714 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -38,9 +38,13 @@
 import com.android.app.animation.InterpolatorsAndroidX;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.Dumpable;
+import com.android.systemui.common.ui.ConfigurationState;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.demomode.DemoMode;
+import com.android.systemui.demomode.DemoModeController;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.FeatureFlagsClassic;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.res.R;
 import com.android.systemui.shade.ShadeExpansionStateManager;
@@ -52,8 +56,15 @@
 import com.android.systemui.statusbar.disableflags.DisableFlagsLogger.DisableState;
 import com.android.systemui.statusbar.events.SystemStatusAnimationCallback;
 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
+import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder;
+import com.android.systemui.statusbar.notification.icon.ui.viewbinder.StatusBarNotificationIconViewStore;
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerStatusBarViewModel;
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel;
+import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.NotificationIconAreaController;
+import com.android.systemui.statusbar.phone.NotificationIconContainer;
 import com.android.systemui.statusbar.phone.PhoneStatusBarView;
+import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
 import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager;
@@ -66,6 +77,7 @@
 import com.android.systemui.statusbar.pipeline.shared.ui.binder.CollapsedStatusBarViewBinder;
 import com.android.systemui.statusbar.pipeline.shared.ui.binder.StatusBarVisibilityChangeListener;
 import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.window.StatusBarWindowStateController;
 import com.android.systemui.statusbar.window.StatusBarWindowStateListener;
@@ -83,6 +95,7 @@
 import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
+
 import kotlin.Unit;
 
 /**
@@ -128,7 +141,7 @@
     private final OngoingCallController mOngoingCallController;
     private final SystemStatusAnimationScheduler mAnimationScheduler;
     private final StatusBarLocationPublisher mLocationPublisher;
-    private final FeatureFlags mFeatureFlags;
+    private final FeatureFlagsClassic mFeatureFlags;
     private final NotificationIconAreaController mNotificationIconAreaController;
     private final ShadeExpansionStateManager mShadeExpansionStateManager;
     private final StatusBarIconController mStatusBarIconController;
@@ -142,6 +155,13 @@
     private final DumpManager mDumpManager;
     private final StatusBarWindowStateController mStatusBarWindowStateController;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    private final NotificationIconContainerViewModel mStatusBarIconsViewModel;
+    private final ConfigurationState mConfigurationState;
+    private final ConfigurationController mConfigurationController;
+    private final DozeParameters mDozeParameters;
+    private final ScreenOffAnimationController mScreenOffAnimationController;
+    private final NotificationIconContainerViewBinder.IconViewStore mStatusBarIconViewStore;
+    private final DemoModeController mDemoModeController;
 
     private List<String> mBlockedIcons = new ArrayList<>();
     private Map<Startable, Startable.State> mStartableStates = new ArrayMap<>();
@@ -211,9 +231,9 @@
             StatusBarLocationPublisher locationPublisher,
             NotificationIconAreaController notificationIconAreaController,
             ShadeExpansionStateManager shadeExpansionStateManager,
-            FeatureFlags featureFlags,
+            FeatureFlagsClassic featureFlags,
             StatusBarIconController statusBarIconController,
-            StatusBarIconController.DarkIconManager.Factory darkIconManagerFactory,
+            DarkIconManager.Factory darkIconManagerFactory,
             CollapsedStatusBarViewModel collapsedStatusBarViewModel,
             CollapsedStatusBarViewBinder collapsedStatusBarViewBinder,
             StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
@@ -228,8 +248,14 @@
             @Main Executor mainExecutor,
             DumpManager dumpManager,
             StatusBarWindowStateController statusBarWindowStateController,
-            KeyguardUpdateMonitor keyguardUpdateMonitor
-    ) {
+            KeyguardUpdateMonitor keyguardUpdateMonitor,
+            NotificationIconContainerStatusBarViewModel statusBarIconsViewModel,
+            ConfigurationState configurationState,
+            ConfigurationController configurationController,
+            DozeParameters dozeParameters,
+            ScreenOffAnimationController screenOffAnimationController,
+            StatusBarNotificationIconViewStore statusBarIconViewStore,
+            DemoModeController demoModeController) {
         mStatusBarFragmentComponentFactory = statusBarFragmentComponentFactory;
         mOngoingCallController = ongoingCallController;
         mAnimationScheduler = animationScheduler;
@@ -254,18 +280,55 @@
         mDumpManager = dumpManager;
         mStatusBarWindowStateController = statusBarWindowStateController;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+        mStatusBarIconsViewModel = statusBarIconsViewModel;
+        mConfigurationState = configurationState;
+        mConfigurationController = configurationController;
+        mDozeParameters = dozeParameters;
+        mScreenOffAnimationController = screenOffAnimationController;
+        mStatusBarIconViewStore = statusBarIconViewStore;
+        mDemoModeController = demoModeController;
     }
 
+    private final DemoMode mDemoModeCallback = new DemoMode() {
+        @Override
+        public List<String> demoCommands() {
+            return List.of(DemoMode.COMMAND_NOTIFICATIONS);
+        }
+
+        @Override
+        public void dispatchDemoCommand(String command, Bundle args) {
+            if (mNotificationIconAreaInner == null) return;
+            String visible = args.getString("visible");
+            if ("false".equals(visible)) {
+                mNotificationIconAreaInner.setVisibility(View.INVISIBLE);
+            } else {
+                mNotificationIconAreaInner.setVisibility(View.VISIBLE);
+            }
+        }
+
+        @Override
+        public void onDemoModeFinished() {
+            if (mNotificationIconAreaInner == null) return;
+            mNotificationIconAreaInner.setVisibility(View.VISIBLE);
+        }
+    };
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mStatusBarWindowStateController.addListener(mStatusBarWindowStateListener);
+        if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_ICON_CONTAINER_REFACTOR)) {
+            mDemoModeController.addCallback(mDemoModeCallback);
+        }
     }
 
     @Override
     public void onDestroy() {
         super.onDestroy();
         mStatusBarWindowStateController.removeListener(mStatusBarWindowStateListener);
+        if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_ICON_CONTAINER_REFACTOR)) {
+            mDemoModeController.removeCallback(mDemoModeCallback);
+        }
     }
 
     @Override
@@ -405,14 +468,31 @@
 
     /** Initializes views related to the notification icon area. */
     public void initNotificationIconArea() {
-        ViewGroup notificationIconArea = mStatusBar.findViewById(R.id.notification_icon_area);
-        mNotificationIconAreaInner =
-                mNotificationIconAreaController.getNotificationInnerAreaView();
-        if (mNotificationIconAreaInner.getParent() != null) {
-            ((ViewGroup) mNotificationIconAreaInner.getParent())
-                    .removeView(mNotificationIconAreaInner);
+        ViewGroup notificationIconArea = mStatusBar.requireViewById(R.id.notification_icon_area);
+        if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_ICON_CONTAINER_REFACTOR)) {
+            mNotificationIconAreaInner =
+                LayoutInflater.from(getContext())
+                        .inflate(R.layout.notification_icon_area, notificationIconArea, true);
+            NotificationIconContainer notificationIcons =
+                    notificationIconArea.requireViewById(R.id.notificationIcons);
+            NotificationIconContainerViewBinder.bind(
+                    notificationIcons,
+                    mStatusBarIconsViewModel,
+                    mConfigurationState,
+                    mConfigurationController,
+                    mDozeParameters,
+                    mFeatureFlags,
+                    mScreenOffAnimationController,
+                    mStatusBarIconViewStore);
+        } else {
+            mNotificationIconAreaInner =
+                    mNotificationIconAreaController.getNotificationInnerAreaView();
+            if (mNotificationIconAreaInner.getParent() != null) {
+                ((ViewGroup) mNotificationIconAreaInner.getParent())
+                        .removeView(mNotificationIconAreaInner);
+            }
+            notificationIconArea.addView(mNotificationIconAreaInner);
         }
-        notificationIconArea.addView(mNotificationIconAreaInner);
 
         updateNotificationIconAreaAndCallChip(/* animate= */ false);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationControllerExt.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationControllerExt.kt
index 25d67af..0a2bbe5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationControllerExt.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationControllerExt.kt
@@ -13,6 +13,7 @@
  */
 package com.android.systemui.statusbar.policy
 
+import android.content.res.Configuration
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
@@ -50,3 +51,20 @@
         addCallback(listener)
         awaitClose { removeCallback(listener) }
     }
+
+/**
+ * A [Flow] that emits whenever the configuration has changed.
+ *
+ * @see ConfigurationController.ConfigurationListener.onConfigChanged
+ */
+val ConfigurationController.onConfigChanged: Flow<Configuration>
+    get() = conflatedCallbackFlow {
+        val listener =
+            object : ConfigurationController.ConfigurationListener {
+                override fun onConfigChanged(newConfig: Configuration) {
+                    trySend(newConfig)
+                }
+            }
+        addCallback(listener)
+        awaitClose { removeCallback(listener) }
+    }
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt
index 0a44bda..f0c7be6 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt
@@ -4,27 +4,74 @@
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dagger.qualifiers.Tracing
+import com.android.systemui.flags.FeatureFlagsClassic
+import com.android.systemui.flags.Flags
+import com.android.systemui.util.TraceUtils.Companion.coroutineTracingIsEnabled
+import com.android.systemui.util.tracing.TraceContextElement
 import dagger.Module
 import dagger.Provides
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import javax.inject.Qualifier
+import kotlin.coroutines.CoroutineContext
+import kotlin.coroutines.EmptyCoroutineContext
+
+/** Key associated with a [Boolean] flag that enables or disables the coroutine tracing feature. */
+@Qualifier
+annotation class CoroutineTracingEnabledKey
+
+/**
+ * Same as [@Application], but does not make use of flags. This should only be used when early usage
+ * of [@Application] would introduce a circular dependency on [FeatureFlagsClassic].
+ */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class UnflaggedApplication
+
+/**
+ * Same as [@Background], but does not make use of flags. This should only be used when early usage
+ * of [@Application] would introduce a circular dependency on [FeatureFlagsClassic].
+ */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class UnflaggedBackground
 
 /** Providers for various coroutines-related constructs. */
 @Module
-object CoroutinesModule {
+class CoroutinesModule {
     @Provides
     @SysUISingleton
     @Application
     fun applicationScope(
-        @Main dispatcher: CoroutineDispatcher,
-    ): CoroutineScope = CoroutineScope(dispatcher)
+            @Main dispatcherContext: CoroutineContext,
+    ): CoroutineScope = CoroutineScope(dispatcherContext)
+
+    @Provides
+    @SysUISingleton
+    @UnflaggedApplication
+    fun unflaggedApplicationScope(): CoroutineScope = CoroutineScope(Dispatchers.Main.immediate)
 
     @Provides
     @SysUISingleton
     @Main
+    @Deprecated(
+        "Use @Main CoroutineContext instead",
+        ReplaceWith("mainCoroutineContext()", "kotlin.coroutines.CoroutineContext")
+    )
     fun mainDispatcher(): CoroutineDispatcher = Dispatchers.Main.immediate
 
+    @Provides
+    @SysUISingleton
+    @Main
+    fun mainCoroutineContext(@Tracing tracingCoroutineContext: CoroutineContext): CoroutineContext {
+        return Dispatchers.Main.immediate + tracingCoroutineContext
+    }
+
     /**
      * Provide a [CoroutineDispatcher] backed by a thread pool containing at most X threads, where
      * X is the number of CPU cores available.
@@ -37,5 +84,42 @@
     @Provides
     @SysUISingleton
     @Background
+    @Deprecated(
+        "Use @Background CoroutineContext instead",
+        ReplaceWith("bgCoroutineContext()", "kotlin.coroutines.CoroutineContext")
+    )
     fun bgDispatcher(): CoroutineDispatcher = Dispatchers.IO
+
+
+    @Provides
+    @Background
+    @SysUISingleton
+    fun bgCoroutineContext(@Tracing tracingCoroutineContext: CoroutineContext): CoroutineContext {
+        return Dispatchers.IO + tracingCoroutineContext
+    }
+
+    @Provides
+    @UnflaggedBackground
+    @SysUISingleton
+    fun unflaggedBackgroundCoroutineContext(): CoroutineContext {
+        return Dispatchers.IO
+    }
+
+    @OptIn(ExperimentalCoroutinesApi::class)
+    @Provides
+    @Tracing
+    @SysUISingleton
+    fun tracingCoroutineContext(
+        @CoroutineTracingEnabledKey enableTracing: Boolean
+    ): CoroutineContext = if (enableTracing) TraceContextElement() else EmptyCoroutineContext
+
+    companion object {
+        @[Provides CoroutineTracingEnabledKey]
+        fun provideIsCoroutineTracingEnabledKey(featureFlags: FeatureFlagsClassic): Boolean {
+            return if (featureFlags.isEnabled(Flags.COROUTINE_TRACING)) {
+                coroutineTracingIsEnabled = true
+                true
+            } else false
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
index 31b90ba..8fe57e11 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
@@ -61,10 +61,10 @@
  *
  * Useful for code that needs to compare the current value to the previous value.
  */
-fun <T, R> Flow<T>.pairwiseBy(
-    initialValue: T,
-    transform: suspend (previousValue: T, newValue: T) -> R,
-): Flow<R> = onStart { emit(initialValue) }.pairwiseBy(transform)
+fun <S, T : S, R> Flow<T>.pairwiseBy(
+    initialValue: S,
+    transform: suspend (previousValue: S, newValue: T) -> R,
+): Flow<R> = pairwiseBy(getInitialValue = { initialValue }, transform)
 
 /**
  * Returns a new [Flow] that combines the two most recent emissions from [this] using [transform].
@@ -75,10 +75,16 @@
  *
  * Useful for code that needs to compare the current value to the previous value.
  */
-fun <T, R> Flow<T>.pairwiseBy(
-    getInitialValue: suspend () -> T,
-    transform: suspend (previousValue: T, newValue: T) -> R,
-): Flow<R> = onStart { emit(getInitialValue()) }.pairwiseBy(transform)
+fun <S, T : S, R> Flow<T>.pairwiseBy(
+    getInitialValue: suspend () -> S,
+    transform: suspend (previousValue: S, newValue: T) -> R,
+): Flow<R> = flow {
+    var previousValue: S = getInitialValue()
+    collect { newVal ->
+        emit(transform(previousValue, newVal))
+        previousValue = newVal
+    }
+}
 
 /**
  * Returns a new [Flow] that produces the two most recent emissions from [this]. Note that the new
@@ -86,7 +92,7 @@
  *
  * Useful for code that needs to compare the current value to the previous value.
  */
-fun <T> Flow<T>.pairwise(): Flow<WithPrev<T>> = pairwiseBy(::WithPrev)
+fun <T> Flow<T>.pairwise(): Flow<WithPrev<T, T>> = pairwiseBy(::WithPrev)
 
 /**
  * Returns a new [Flow] that produces the two most recent emissions from [this]. [initialValue] will
@@ -94,10 +100,11 @@
  *
  * Useful for code that needs to compare the current value to the previous value.
  */
-fun <T> Flow<T>.pairwise(initialValue: T): Flow<WithPrev<T>> = pairwiseBy(initialValue, ::WithPrev)
+fun <S, T : S> Flow<T>.pairwise(initialValue: S): Flow<WithPrev<S, T>> =
+    pairwiseBy(initialValue, ::WithPrev)
 
 /** Holds a [newValue] emitted from a [Flow], along with the [previousValue] emitted value. */
-data class WithPrev<T>(val previousValue: T, val newValue: T)
+data class WithPrev<out S, out T : S>(val previousValue: S, val newValue: T)
 
 /**
  * Returns a new [Flow] that combines the [Set] changes between each emission from [this] using
@@ -265,112 +272,120 @@
  * immediately invoke [getValue] to establish its initial value.
  */
 inline fun <T> CoroutineScope.stateFlow(
-    changedSignals: Flow<Unit>,
+    changedSignals: Flow<*>,
     crossinline getValue: () -> T,
 ): StateFlow<T> =
     changedSignals.map { getValue() }.stateIn(this, SharingStarted.Eagerly, getValue())
 
 inline fun <T1, T2, T3, T4, T5, T6, R> combine(
-        flow: Flow<T1>,
-        flow2: Flow<T2>,
-        flow3: Flow<T3>,
-        flow4: Flow<T4>,
-        flow5: Flow<T5>,
-        flow6: Flow<T6>,
-        crossinline transform: suspend (T1, T2, T3, T4, T5, T6) -> R
+    flow: Flow<T1>,
+    flow2: Flow<T2>,
+    flow3: Flow<T3>,
+    flow4: Flow<T4>,
+    flow5: Flow<T5>,
+    flow6: Flow<T6>,
+    crossinline transform: suspend (T1, T2, T3, T4, T5, T6) -> R
 ): Flow<R> {
-    return kotlinx.coroutines.flow.combine(flow, flow2, flow3, flow4, flow5, flow6) {
-        args: Array<*> ->
+    return kotlinx.coroutines.flow.combine(flow, flow2, flow3, flow4, flow5, flow6) { args: Array<*>
+        ->
         @Suppress("UNCHECKED_CAST")
         transform(
-                args[0] as T1,
-                args[1] as T2,
-                args[2] as T3,
-                args[3] as T4,
-                args[4] as T5,
-                args[5] as T6
+            args[0] as T1,
+            args[1] as T2,
+            args[2] as T3,
+            args[3] as T4,
+            args[4] as T5,
+            args[5] as T6
         )
     }
 }
 
 inline fun <T1, T2, T3, T4, T5, T6, T7, R> combine(
-        flow: Flow<T1>,
-        flow2: Flow<T2>,
-        flow3: Flow<T3>,
-        flow4: Flow<T4>,
-        flow5: Flow<T5>,
-        flow6: Flow<T6>,
-        flow7: Flow<T7>,
-        crossinline transform: suspend (T1, T2, T3, T4, T5, T6, T7) -> R
+    flow: Flow<T1>,
+    flow2: Flow<T2>,
+    flow3: Flow<T3>,
+    flow4: Flow<T4>,
+    flow5: Flow<T5>,
+    flow6: Flow<T6>,
+    flow7: Flow<T7>,
+    crossinline transform: suspend (T1, T2, T3, T4, T5, T6, T7) -> R
 ): Flow<R> {
     return kotlinx.coroutines.flow.combine(flow, flow2, flow3, flow4, flow5, flow6, flow7) {
         args: Array<*> ->
         @Suppress("UNCHECKED_CAST")
         transform(
-                args[0] as T1,
-                args[1] as T2,
-                args[2] as T3,
-                args[3] as T4,
-                args[4] as T5,
-                args[5] as T6,
-                args[6] as T7
+            args[0] as T1,
+            args[1] as T2,
+            args[2] as T3,
+            args[3] as T4,
+            args[4] as T5,
+            args[5] as T6,
+            args[6] as T7
         )
     }
 }
 
 inline fun <T1, T2, T3, T4, T5, T6, T7, T8, R> combine(
-        flow: Flow<T1>,
-        flow2: Flow<T2>,
-        flow3: Flow<T3>,
-        flow4: Flow<T4>,
-        flow5: Flow<T5>,
-        flow6: Flow<T6>,
-        flow7: Flow<T7>,
-        flow8: Flow<T8>,
-        crossinline transform: suspend (T1, T2, T3, T4, T5, T6, T7, T8) -> R
+    flow: Flow<T1>,
+    flow2: Flow<T2>,
+    flow3: Flow<T3>,
+    flow4: Flow<T4>,
+    flow5: Flow<T5>,
+    flow6: Flow<T6>,
+    flow7: Flow<T7>,
+    flow8: Flow<T8>,
+    crossinline transform: suspend (T1, T2, T3, T4, T5, T6, T7, T8) -> R
 ): Flow<R> {
     return kotlinx.coroutines.flow.combine(flow, flow2, flow3, flow4, flow5, flow6, flow7, flow8) {
         args: Array<*> ->
         @Suppress("UNCHECKED_CAST")
         transform(
-                args[0] as T1,
-                args[1] as T2,
-                args[2] as T3,
-                args[3] as T4,
-                args[4] as T5,
-                args[5] as T6,
-                args[6] as T7,
-                args[7] as T8
+            args[0] as T1,
+            args[1] as T2,
+            args[2] as T3,
+            args[3] as T4,
+            args[4] as T5,
+            args[5] as T6,
+            args[6] as T7,
+            args[7] as T8
         )
     }
 }
 
 inline fun <T1, T2, T3, T4, T5, T6, T7, T8, T9, R> combine(
-        flow: Flow<T1>,
-        flow2: Flow<T2>,
-        flow3: Flow<T3>,
-        flow4: Flow<T4>,
-        flow5: Flow<T5>,
-        flow6: Flow<T6>,
-        flow7: Flow<T7>,
-        flow8: Flow<T8>,
-        flow9: Flow<T9>,
-        crossinline transform: suspend (T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R
+    flow: Flow<T1>,
+    flow2: Flow<T2>,
+    flow3: Flow<T3>,
+    flow4: Flow<T4>,
+    flow5: Flow<T5>,
+    flow6: Flow<T6>,
+    flow7: Flow<T7>,
+    flow8: Flow<T8>,
+    flow9: Flow<T9>,
+    crossinline transform: suspend (T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R
 ): Flow<R> {
     return kotlinx.coroutines.flow.combine(
-        flow, flow2, flow3, flow4, flow5, flow6, flow7, flow8, flow9
+        flow,
+        flow2,
+        flow3,
+        flow4,
+        flow5,
+        flow6,
+        flow7,
+        flow8,
+        flow9
     ) { args: Array<*> ->
         @Suppress("UNCHECKED_CAST")
         transform(
-                args[0] as T1,
-                args[1] as T2,
-                args[2] as T3,
-                args[3] as T4,
-                args[4] as T5,
-                args[5] as T6,
-                args[6] as T7,
-                args[6] as T8,
-                args[6] as T9,
+            args[0] as T1,
+            args[1] as T2,
+            args[2] as T3,
+            args[3] as T4,
+            args[4] as T5,
+            args[5] as T6,
+            args[6] as T7,
+            args[6] as T8,
+            args[6] as T9,
         )
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/MapUtils.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/MapUtils.kt
new file mode 100644
index 0000000..41cd95b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/MapUtils.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 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.systemui.util.kotlin
+
+/** Like [mapValues], but discards `null` values returned from [block]. */
+fun <K, V, R> Map<K, V>.mapValuesNotNull(block: (Map.Entry<K, V>) -> R?): Map<K, R> = buildMap {
+    this@mapValuesNotNull.mapValuesNotNullTo(this, block)
+}
+
+/** Like [mapValuesTo], but discards `null` values returned from [block]. */
+fun <K, V, R, M : MutableMap<in K, in R>> Map<out K, V>.mapValuesNotNullTo(
+    destination: M,
+    block: (Map.Entry<K, V>) -> R?,
+): M {
+    for (entry in this) {
+        block(entry)?.also { destination.put(entry.key, it) }
+    }
+    return destination
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/ui/AnimatedValue.kt b/packages/SystemUI/src/com/android/systemui/util/ui/AnimatedValue.kt
index 51d2afa..1112d6f 100644
--- a/packages/SystemUI/src/com/android/systemui/util/ui/AnimatedValue.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/ui/AnimatedValue.kt
@@ -17,26 +17,58 @@
 
 package com.android.systemui.util.ui
 
+import com.android.systemui.util.ui.AnimatedValue.Animating
+import com.android.systemui.util.ui.AnimatedValue.NotAnimating
+import kotlinx.coroutines.CompletableDeferred
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.firstOrNull
-import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.transformLatest
 
 /**
  * A state comprised of a [value] of type [T] paired with a boolean indicating whether or not the
  * [value] [isAnimating] in the UI.
  */
-data class AnimatedValue<T>(
-    val value: T,
-    val isAnimating: Boolean,
-)
+sealed interface AnimatedValue<out T> {
+
+    /** A [state][value] that is not actively animating in the UI. */
+    data class NotAnimating<out T>(val value: T) : AnimatedValue<T>
+
+    /**
+     * A [state][value] that is actively animating in the UI. Invoking [onStopAnimating] will signal
+     * the source of the state to stop animating.
+     */
+    data class Animating<out T>(
+        val value: T,
+        val onStopAnimating: () -> Unit,
+    ) : AnimatedValue<T>
+}
+
+/** The state held in this [AnimatedValue]. */
+inline val <T> AnimatedValue<T>.value: T
+    get() =
+        when (this) {
+            is Animating -> value
+            is NotAnimating -> value
+        }
+
+/** Returns whether or not this [AnimatedValue] is animating or not. */
+inline val <T> AnimatedValue<T>.isAnimating: Boolean
+    get() = this is Animating<T>
+
+/**
+ * If this [AnimatedValue] [isAnimating], then signal that the animation should be stopped.
+ * Otherwise, do nothing.
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun AnimatedValue<*>.stopAnimating() {
+    if (this is Animating) onStopAnimating()
+}
 
 /**
  * An event comprised of a [value] of type [T] paired with a [boolean][startAnimating] indicating
  * whether or not this event should start an animation.
  */
-data class AnimatableEvent<T>(
+data class AnimatableEvent<out T>(
     val value: T,
     val startAnimating: Boolean,
 )
@@ -47,16 +79,87 @@
  * [AnimatableEvent.startAnimating] value is `true`. When [completionEvents] emits a value, the
  * [AnimatedValue.isAnimating] will flip to `false`.
  */
-fun <T> Flow<AnimatableEvent<T>>.toAnimatedValueFlow(
-    completionEvents: Flow<Any?>,
-): Flow<AnimatedValue<T>> = transformLatest { (value, startAnimating) ->
-    emit(AnimatedValue(value, isAnimating = startAnimating))
-    if (startAnimating) {
-        // Wait for a completion now that we've started animating
-        completionEvents
-            .map { Unit } // replace the event so that it's never `null`
-            .firstOrNull() // `null` indicates an empty flow
-            // emit the new state if the flow was not empty.
-            ?.run { emit(AnimatedValue(value, isAnimating = false)) }
+fun <T> Flow<AnimatableEvent<T>>.toAnimatedValueFlow(): Flow<AnimatedValue<T>> =
+    transformLatest { (value, startAnimating) ->
+        if (startAnimating) {
+            val onCompleted = CompletableDeferred<Unit>()
+            emit(Animating(value) { onCompleted.complete(Unit) })
+            // Wait for a completion now that we've started animating
+            onCompleted.await()
+        }
+        emit(NotAnimating(value))
+    }
+
+/**
+ * Zip two [AnimatedValue]s together into a single [AnimatedValue], using [block] to combine the
+ * [value]s of each.
+ *
+ * If either [AnimatedValue] [isAnimating], then the result is also animating. Invoking
+ * [stopAnimating] on the result is equivalent to invoking [stopAnimating] on each input.
+ */
+inline fun <A, B, Z> zip(
+    valueA: AnimatedValue<A>,
+    valueB: AnimatedValue<B>,
+    block: (A, B) -> Z,
+): AnimatedValue<Z> {
+    val zippedValue = block(valueA.value, valueB.value)
+    return when (valueA) {
+        is Animating ->
+            when (valueB) {
+                is Animating ->
+                    Animating(zippedValue) {
+                        valueA.onStopAnimating()
+                        valueB.onStopAnimating()
+                    }
+                is NotAnimating -> Animating(zippedValue, valueA.onStopAnimating)
+            }
+        is NotAnimating ->
+            when (valueB) {
+                is Animating -> Animating(zippedValue, valueB.onStopAnimating)
+                is NotAnimating -> NotAnimating(zippedValue)
+            }
     }
 }
+
+/**
+ * Flattens a nested [AnimatedValue], the result of which holds the [value] of the inner
+ * [AnimatedValue].
+ *
+ * If either the outer or inner [AnimatedValue] [isAnimating], then the flattened result is also
+ * animating. Invoking [stopAnimating] on the result is equivalent to invoking [stopAnimating] on
+ * both the outer and inner values.
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun <T> AnimatedValue<AnimatedValue<T>>.flatten(): AnimatedValue<T> = flatMap { it }
+
+/**
+ * Returns an [AnimatedValue], the [value] of which is the result of the given [value] applied to
+ * [block].
+ */
+inline fun <A, B> AnimatedValue<A>.map(block: (A) -> B): AnimatedValue<B> =
+    when (this) {
+        is Animating -> Animating(block(value), ::stopAnimating)
+        is NotAnimating -> NotAnimating(block(value))
+    }
+
+/**
+ * Returns an [AnimatedValue] from the result of [block] being invoked on the [value] original
+ * [AnimatedValue].
+ *
+ * If either the input [AnimatedValue] or the result of [block] [isAnimating], then the flattened
+ * result is also animating. Invoking [stopAnimating] on the result is equivalent to invoking
+ * [stopAnimating] on both values.
+ */
+inline fun <A, B> AnimatedValue<A>.flatMap(block: (A) -> AnimatedValue<B>): AnimatedValue<B> =
+    when (this) {
+        is NotAnimating -> block(value)
+        is Animating ->
+            when (val inner = block(value)) {
+                is Animating ->
+                    Animating(inner.value) {
+                        onStopAnimating()
+                        inner.onStopAnimating()
+                    }
+                is NotAnimating -> Animating(inner.value, onStopAnimating)
+            }
+    }
diff --git a/packages/SystemUI/tests/src/com/android/TestMocksModule.kt b/packages/SystemUI/tests/src/com/android/TestMocksModule.kt
index ff1d5b2..f49ba64 100644
--- a/packages/SystemUI/tests/src/com/android/TestMocksModule.kt
+++ b/packages/SystemUI/tests/src/com/android/TestMocksModule.kt
@@ -43,6 +43,7 @@
 import com.android.systemui.statusbar.NotificationShadeDepthController
 import com.android.systemui.statusbar.SysuiStatusBarStateController
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
+import com.android.systemui.statusbar.notification.collection.NotifCollection
 import com.android.systemui.statusbar.notification.stack.AmbientState
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
 import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator
@@ -75,6 +76,7 @@
     @get:Provides val keyguardSecurityModel: KeyguardSecurityModel = mock(),
     @get:Provides val keyguardUpdateMonitor: KeyguardUpdateMonitor = mock(),
     @get:Provides val mediaHierarchyManager: MediaHierarchyManager = mock(),
+    @get:Provides val notifCollection: NotifCollection = mock(),
     @get:Provides val notificationListener: NotificationListener = mock(),
     @get:Provides val notificationLockscreenUserManager: NotificationLockscreenUserManager = mock(),
     @get:Provides val notificationMediaManager: NotificationMediaManager = mock(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt
index 43cf1b5..ae47a7b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt
@@ -37,7 +37,6 @@
 import android.view.IWindowManager
 import android.view.View
 import com.android.internal.logging.MetricsLogger
-import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.animation.view.LaunchableFrameLayout
@@ -48,6 +47,7 @@
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.QsEventLogger
 import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.res.R
 import com.android.systemui.settings.FakeDisplayTracker
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
@@ -343,8 +343,7 @@
         testableLooper.processAllMessages()
 
         verify(activityStarter, never())
-            .startPendingIntentDismissingKeyguard(
-                any(), any(), any(ActivityLaunchAnimator.Controller::class.java))
+            .startPendingIntentMaybeDismissingKeyguard(any(), nullable(), nullable())
     }
 
     @Test
@@ -357,8 +356,7 @@
         testableLooper.processAllMessages()
 
         verify(activityStarter, never())
-            .startPendingIntentDismissingKeyguard(
-                any(), any(), any(ActivityLaunchAnimator.Controller::class.java))
+            .startPendingIntentMaybeDismissingKeyguard(any(), nullable(), nullable())
     }
 
     @Test
@@ -373,7 +371,7 @@
         testableLooper.processAllMessages()
 
         verify(activityStarter)
-            .startPendingIntentDismissingKeyguard(
+            .startPendingIntentMaybeDismissingKeyguard(
                 eq(pi), nullable(), nullable<ActivityLaunchAnimator.Controller>())
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index e1345d2..c1f2d0c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -22,11 +22,11 @@
 import android.view.Display
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.Flags as AconfigFlags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.authentication.domain.model.AuthenticationMethodModel
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.flags.Flags
 import com.android.systemui.model.SysUiState
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
@@ -45,7 +45,7 @@
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
-import org.junit.Assume.assumeTrue
+import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mockito.clearInvocations
@@ -87,6 +87,11 @@
             powerInteractor = powerInteractor,
         )
 
+    @Before
+    fun setUp() {
+        mSetFlagsRule.enableFlags(AconfigFlags.FLAG_SCENE_CONTAINER)
+    }
+
     @Test
     fun hydrateVisibility() =
         testScope.runTest {
@@ -520,7 +525,6 @@
         authenticationMethod: AuthenticationMethodModel? = null,
         startsAwake: Boolean = true,
     ): MutableStateFlow<ObservableTransitionState> {
-        assumeTrue(Flags.SCENE_CONTAINER_ENABLED)
         sceneContainerFlags.enabled = true
         utils.deviceEntryRepository.setUnlocked(isDeviceUnlocked)
         utils.deviceEntryRepository.setBypassEnabled(isBypassEnabled)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt
index f6195aa..0bed4d0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt
@@ -16,7 +16,10 @@
 
 package com.android.systemui.scene.shared.flag
 
+import android.platform.test.flag.junit.SetFlagsRule
 import androidx.test.filters.SmallTest
+import com.android.systemui.FakeFeatureFlagsImpl
+import com.android.systemui.Flags as AconfigFlags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.flags.FakeFeatureFlagsClassic
 import com.android.systemui.flags.Flags
@@ -24,8 +27,8 @@
 import com.android.systemui.flags.ResourceBooleanFlag
 import com.android.systemui.flags.UnreleasedFlag
 import com.google.common.truth.Truth.assertThat
-import org.junit.Assume.assumeTrue
 import org.junit.Before
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
@@ -36,27 +39,50 @@
     private val testCase: TestCase,
 ) : SysuiTestCase() {
 
+    @Rule @JvmField val setFlagsRule: SetFlagsRule = SetFlagsRule()
+
     private lateinit var underTest: SceneContainerFlags
 
     @Before
     fun setUp() {
+        // TODO(b/283300105): remove this reflection setting once the hard-coded
+        //  Flags.SCENE_CONTAINER_ENABLED is no longer needed.
+        val field = Flags::class.java.getField("SCENE_CONTAINER_ENABLED")
+        field.isAccessible = true
+        field.set(null, true)
+
         val featureFlags =
             FakeFeatureFlagsClassic().apply {
-                SceneContainerFlagsImpl.flags.forEach { flag ->
-                    when (flag) {
-                        is ResourceBooleanFlag -> set(flag, testCase.areAllFlagsSet)
-                        is ReleasedFlag -> set(flag, testCase.areAllFlagsSet)
-                        is UnreleasedFlag -> set(flag, testCase.areAllFlagsSet)
-                        else -> error("Unsupported flag type ${flag.javaClass}")
+                SceneContainerFlagsImpl.classicFlagTokens.forEach { flagToken ->
+                    when (flagToken) {
+                        is ResourceBooleanFlag -> set(flagToken, testCase.areAllFlagsSet)
+                        is ReleasedFlag -> set(flagToken, testCase.areAllFlagsSet)
+                        is UnreleasedFlag -> set(flagToken, testCase.areAllFlagsSet)
+                        else -> error("Unsupported flag type ${flagToken.javaClass}")
                     }
                 }
             }
-        underTest = SceneContainerFlagsImpl(featureFlags, testCase.isComposeAvailable)
+        // TODO(b/306421592): get the aconfig FeatureFlags from the SetFlagsRule.
+        val aconfigFlags = FakeFeatureFlagsImpl()
+
+        listOf(
+                AconfigFlags.FLAG_SCENE_CONTAINER,
+            )
+            .forEach { flagToken ->
+                setFlagsRule.enableFlags(flagToken)
+                aconfigFlags.setFlag(flagToken, testCase.areAllFlagsSet)
+            }
+
+        underTest =
+            SceneContainerFlagsImpl(
+                featureFlagsClassic = featureFlags,
+                featureFlags = aconfigFlags,
+                isComposeAvailable = testCase.isComposeAvailable,
+            )
     }
 
     @Test
     fun isEnabled() {
-        assumeTrue(Flags.SCENE_CONTAINER_ENABLED)
         assertThat(underTest.isEnabled()).isEqualTo(testCase.expectedEnabled)
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index 2ce4b04..6223e25 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -84,7 +84,6 @@
 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.classifier.FalsingCollectorFake;
 import com.android.systemui.classifier.FalsingManagerFake;
-import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository;
 import com.android.systemui.common.ui.view.LongPressHandlingView;
 import com.android.systemui.doze.DozeLog;
 import com.android.systemui.dump.DumpManager;
@@ -121,8 +120,6 @@
 import com.android.systemui.power.domain.interactor.PowerInteractor;
 import com.android.systemui.qs.QSFragmentLegacy;
 import com.android.systemui.res.R;
-import com.android.systemui.scene.SceneTestUtils;
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags;
 import com.android.systemui.screenrecord.RecordingController;
 import com.android.systemui.shade.data.repository.FakeShadeRepository;
 import com.android.systemui.shade.data.repository.ShadeRepository;
@@ -140,7 +137,6 @@
 import com.android.systemui.statusbar.StatusBarStateControllerImpl;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.VibratorHelper;
-import com.android.systemui.statusbar.disableflags.data.repository.FakeDisableFlagsRepository;
 import com.android.systemui.statusbar.notification.ConversationNotificationManager;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
@@ -172,7 +168,6 @@
 import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
 import com.android.systemui.statusbar.phone.TapAgainViewController;
 import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository;
 import com.android.systemui.statusbar.policy.CastController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -181,10 +176,8 @@
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcherView;
 import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController;
-import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository;
 import com.android.systemui.statusbar.window.StatusBarWindowStateController;
 import com.android.systemui.unfold.SysUIUnfoldComponent;
-import com.android.systemui.user.domain.interactor.UserSwitcherInteractor;
 import com.android.systemui.util.kotlin.JavaAdapter;
 import com.android.systemui.util.time.FakeSystemClock;
 import com.android.systemui.util.time.SystemClock;
@@ -204,8 +197,6 @@
 import java.util.Optional;
 
 import kotlinx.coroutines.CoroutineDispatcher;
-import kotlinx.coroutines.flow.StateFlowKt;
-import kotlinx.coroutines.test.TestScope;
 
 public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
 
@@ -333,6 +324,7 @@
             mEmptySpaceClickListenerCaptor;
     @Mock protected ActivityStarter mActivityStarter;
     @Mock protected KeyguardFaceAuthInteractor mKeyguardFaceAuthInteractor;
+    @Mock private ShadeInteractor mShadeInteractor;
     @Mock private JavaAdapter mJavaAdapter;
     @Mock private CastController mCastController;
     @Mock private KeyguardRootView mKeyguardRootView;
@@ -343,9 +335,6 @@
     protected KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor;
     protected FakeKeyguardRepository mFakeKeyguardRepository;
     protected KeyguardInteractor mKeyguardInteractor;
-    protected SceneTestUtils mUtils = new SceneTestUtils(this);
-    protected TestScope mTestScope = mUtils.getTestScope();
-    protected ShadeInteractor mShadeInteractor;
     protected PowerInteractor mPowerInteractor;
     protected NotificationPanelViewController.TouchHandler mTouchHandler;
     protected ConfigurationController mConfigurationController;
@@ -381,31 +370,10 @@
         mKeyguardInteractor = keyguardInteractorDeps.getKeyguardInteractor();
         mShadeRepository = new FakeShadeRepository();
         mPowerInteractor = keyguardInteractorDeps.getPowerInteractor();
-        when(mKeyguardTransitionInteractor.isInTransitionToStateWhere(any())).thenReturn(
-                StateFlowKt.MutableStateFlow(false));
-        mShadeInteractor = new ShadeInteractor(
-                mTestScope.getBackgroundScope(),
-                new FakeDeviceProvisioningRepository(),
-                new FakeDisableFlagsRepository(),
-                mDozeParameters,
-                new FakeSceneContainerFlags(),
-                mUtils::sceneInteractor,
-                mFakeKeyguardRepository,
-                mKeyguardTransitionInteractor,
-                mPowerInteractor,
-                new FakeUserSetupRepository(),
-                mock(UserSwitcherInteractor.class),
-                new SharedNotificationContainerInteractor(
-                        new FakeConfigurationRepository(),
-                        mContext,
-                        new ResourcesSplitShadeStateController()
-                ),
-                mShadeRepository
-        );
 
         SystemClock systemClock = new FakeSystemClock();
-        mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger,
-                mInteractionJankMonitor, mJavaAdapter, () -> mShadeInteractor);
+        mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager,
+                mInteractionJankMonitor, mShadeExpansionStateManager);
 
         KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext);
         keyguardStatusView.setId(R.id.keyguard_status_view);
@@ -564,9 +532,8 @@
                 new NotificationWakeUpCoordinator(
                         mDumpManager,
                         mock(HeadsUpManager.class),
-                        new StatusBarStateControllerImpl(new UiEventLoggerFake(),
-                                mInteractionJankMonitor,
-                                mJavaAdapter, () -> mShadeInteractor),
+                        new StatusBarStateControllerImpl(new UiEventLoggerFake(), mDumpManager,
+                                mInteractionJankMonitor, mShadeExpansionStateManager),
                         mKeyguardBypassController,
                         mDozeParameters,
                         mScreenOffAnimationController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
index b421e1b..4e3e165 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -79,7 +79,8 @@
 import com.android.systemui.statusbar.NotificationShadeDepthController
 import com.android.systemui.statusbar.NotificationShadeWindowController
 import com.android.systemui.statusbar.SysuiStatusBarStateController
-import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository
+import com.android.systemui.statusbar.notification.data.repository.NotificationLaunchAnimationRepository
+import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor
 import com.android.systemui.statusbar.notification.stack.AmbientState
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
 import com.android.systemui.statusbar.phone.CentralSurfaces
@@ -163,7 +164,9 @@
     @Mock lateinit var sysUIKeyEventHandler: SysUIKeyEventHandler
     @Mock lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor
     @Mock lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
-    private val notificationExpansionRepository = NotificationExpansionRepository()
+    private val notificationLaunchAnimationRepository = NotificationLaunchAnimationRepository()
+    private val notificationLaunchAnimationInteractor =
+            NotificationLaunchAnimationInteractor(notificationLaunchAnimationRepository)
 
     private lateinit var fakeClock: FakeSystemClock
     private lateinit var interactionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
@@ -234,7 +237,7 @@
                 primaryBouncerToGoneTransitionViewModel,
                 mCommunalViewModel,
                 mCommunalRepository,
-                notificationExpansionRepository,
+                notificationLaunchAnimationInteractor,
                 featureFlagsClassic,
                 fakeClock,
                 BouncerMessageInteractor(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
index 9c57101..3d5d26a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
@@ -69,7 +69,8 @@
 import com.android.systemui.statusbar.NotificationShadeDepthController
 import com.android.systemui.statusbar.NotificationShadeWindowController
 import com.android.systemui.statusbar.SysuiStatusBarStateController
-import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository
+import com.android.systemui.statusbar.notification.data.repository.NotificationLaunchAnimationRepository
+import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor
 import com.android.systemui.statusbar.notification.stack.AmbientState
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
@@ -226,7 +227,7 @@
                 primaryBouncerToGoneTransitionViewModel,
                 mCommunalViewModel,
                 mCommunalRepository,
-                NotificationExpansionRepository(),
+                NotificationLaunchAnimationInteractor(NotificationLaunchAnimationRepository()),
                 featureFlags,
                 FakeSystemClock(),
                 BouncerMessageInteractor(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java
index ec00b17..0fcfaf9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java
@@ -188,8 +188,8 @@
     public void setup() {
         MockitoAnnotations.initMocks(this);
         when(mPanelViewControllerLazy.get()).thenReturn(mNotificationPanelViewController);
-        mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger,
-                mInteractionJankMonitor, mock(JavaAdapter.class), () -> mShadeInteractor);
+        mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager,
+                mInteractionJankMonitor, mShadeExpansionStateManager);
 
         FakeDeviceProvisioningRepository deviceProvisioningRepository =
                 new FakeDeviceProvisioningRepository();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
index 3412679..2b3fd34 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
@@ -37,8 +37,12 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.flags.FakeFeatureFlagsClassic;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
+import com.android.systemui.statusbar.data.repository.NotificationListenerSettingsRepository;
+import com.android.systemui.statusbar.domain.interactor.SilentNotificationStatusIconsVisibilityInteractor;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.time.FakeSystemClock;
 
@@ -68,9 +72,14 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
+        FakeFeatureFlagsClassic featureFlags = new FakeFeatureFlagsClassic();
+        featureFlags.setDefault(Flags.NOTIFICATION_ICON_CONTAINER_REFACTOR);
         mListener = new NotificationListener(
                 mContext,
+                featureFlags,
                 mNotificationManager,
+                new SilentNotificationStatusIconsVisibilityInteractor(
+                        new NotificationListenerSettingsRepository()),
                 mFakeSystemClock,
                 mFakeExecutor,
                 mPluginManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
index 560ebc6..764f7b6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
@@ -33,9 +33,9 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.power.domain.interactor.PowerInteractor;
-import com.android.systemui.shade.domain.interactor.ShadeInteractor;
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.RemoteInputControllerLogger;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -43,7 +43,6 @@
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.policy.RemoteInputUriController;
-import com.android.systemui.util.kotlin.JavaAdapter;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -88,8 +87,7 @@
                 new RemoteInputControllerLogger(logcatLogBuffer()),
                 mClickNotifier,
                 new ActionClickLogger(logcatLogBuffer()),
-                mock(JavaAdapter.class),
-                mock(ShadeInteractor.class));
+                mock(DumpManager.class));
         mEntry = new NotificationEntryBuilder()
                 .setPkg(TEST_PACKAGE_NAME)
                 .setOpPkg(TEST_PACKAGE_NAME)
@@ -147,8 +145,7 @@
                 RemoteInputControllerLogger remoteInputControllerLogger,
                 NotificationClickNotifier clickNotifier,
                 ActionClickLogger actionClickLogger,
-                JavaAdapter javaAdapter,
-                ShadeInteractor shadeInteractor) {
+                DumpManager dumpManager) {
             super(
                     context,
                     notifPipelineFlags,
@@ -161,8 +158,7 @@
                     remoteInputControllerLogger,
                     clickNotifier,
                     actionClickLogger,
-                    javaAdapter,
-                    shadeInteractor);
+                    dumpManager);
         }
 
         public void setUpWithPresenterForTest(Callback callback,
@@ -174,4 +170,3 @@
 
     }
 }
-
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
index 43b0007..3327e42 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
@@ -23,31 +23,9 @@
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
-import com.android.systemui.classifier.FalsingCollectorFake
-import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
-import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepository
-import com.android.systemui.flags.FakeFeatureFlagsClassic
-import com.android.systemui.keyguard.data.repository.FakeCommandQueue
-import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor
-import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.statusbar.StatusBarStateController
-import com.android.systemui.power.data.repository.FakePowerRepository
-import com.android.systemui.power.domain.interactor.PowerInteractor
-import com.android.systemui.scene.SceneTestUtils
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags
-import com.android.systemui.shade.data.repository.FakeShadeRepository
-import com.android.systemui.shade.domain.interactor.ShadeInteractor
-import com.android.systemui.statusbar.disableflags.data.repository.FakeDisableFlagsRepository
-import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository
-import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
-import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository
-import com.android.systemui.util.mockito.mock
+import com.android.systemui.shade.ShadeExpansionStateManager
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
@@ -62,22 +40,17 @@
 import org.mockito.Mockito
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
 import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
 @TestableLooper.RunWithLooper
 class StatusBarStateControllerImplTest : SysuiTestCase() {
 
-    private val utils = SceneTestUtils(this)
-    private val testScope = utils.testScope
-    private lateinit var shadeInteractor: ShadeInteractor
-    private lateinit var fromLockscreenTransitionInteractor: FromLockscreenTransitionInteractor
-    private lateinit var fromPrimaryBouncerTransitionInteractor:
-        FromPrimaryBouncerTransitionInteractor
     @Mock lateinit var interactionJankMonitor: InteractionJankMonitor
-    @Mock lateinit var mockDarkAnimator: ObjectAnimator
+    @Mock private lateinit var mockDarkAnimator: ObjectAnimator
+    @Mock private lateinit var shadeExpansionStateManager: ShadeExpansionStateManager
 
     private lateinit var controller: StatusBarStateControllerImpl
     private lateinit var uiEventLogger: UiEventLoggerFake
@@ -91,76 +64,11 @@
         uiEventLogger = UiEventLoggerFake()
         controller = object : StatusBarStateControllerImpl(
             uiEventLogger,
-            interactionJankMonitor,
-            mock(),
-            { shadeInteractor }
+            mock(DumpManager::class.java),
+            interactionJankMonitor, shadeExpansionStateManager
         ) {
             override fun createDarkAnimator(): ObjectAnimator { return mockDarkAnimator }
         }
-
-        val powerInteractor = PowerInteractor(
-            FakePowerRepository(),
-            FalsingCollectorFake(),
-            mock(),
-            controller)
-        val keyguardRepository = FakeKeyguardRepository()
-        val keyguardTransitionRepository = FakeKeyguardTransitionRepository()
-        val featureFlags = FakeFeatureFlagsClassic()
-        val shadeRepository = FakeShadeRepository()
-        val sceneContainerFlags = FakeSceneContainerFlags()
-        val configurationRepository = FakeConfigurationRepository()
-        val keyguardInteractor = KeyguardInteractor(
-            keyguardRepository,
-            FakeCommandQueue(),
-            powerInteractor,
-            featureFlags,
-            sceneContainerFlags,
-            FakeDeviceEntryRepository(),
-            FakeKeyguardBouncerRepository(),
-            configurationRepository,
-            shadeRepository,
-            utils::sceneInteractor)
-        val keyguardTransitionInteractor = KeyguardTransitionInteractor(
-            testScope.backgroundScope,
-            keyguardTransitionRepository,
-            { keyguardInteractor },
-            { fromLockscreenTransitionInteractor },
-            { fromPrimaryBouncerTransitionInteractor })
-        fromLockscreenTransitionInteractor = FromLockscreenTransitionInteractor(
-            keyguardTransitionRepository,
-            keyguardTransitionInteractor,
-            testScope.backgroundScope,
-            keyguardInteractor,
-            featureFlags,
-            shadeRepository,
-            powerInteractor)
-        fromPrimaryBouncerTransitionInteractor = FromPrimaryBouncerTransitionInteractor(
-            keyguardTransitionRepository,
-            keyguardTransitionInteractor,
-            testScope.backgroundScope,
-            keyguardInteractor,
-            featureFlags,
-            mock(),
-            mock(),
-            powerInteractor)
-        shadeInteractor = ShadeInteractor(
-            testScope.backgroundScope,
-            FakeDeviceProvisioningRepository(),
-            FakeDisableFlagsRepository(),
-            mock(),
-            sceneContainerFlags,
-            utils::sceneInteractor,
-            keyguardRepository,
-            keyguardTransitionInteractor,
-            powerInteractor,
-            FakeUserSetupRepository(),
-            mock(),
-            SharedNotificationContainerInteractor(
-                configurationRepository,
-                mContext,
-                ResourcesSplitShadeStateController()),
-            shadeRepository,
-        )
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
index 235ac5c..6059363 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
@@ -11,7 +11,8 @@
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
-import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository
+import com.android.systemui.statusbar.notification.data.repository.NotificationLaunchAnimationRepository
+import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
@@ -44,7 +45,8 @@
     private lateinit var notificationTestHelper: NotificationTestHelper
     private lateinit var notification: ExpandableNotificationRow
     private lateinit var controller: NotificationLaunchAnimatorController
-    private val notificationExpansionRepository = NotificationExpansionRepository()
+    private val notificationLaunchAnimationInteractor =
+        NotificationLaunchAnimationInteractor(NotificationLaunchAnimationRepository())
 
     private val testScope = TestScope()
 
@@ -57,16 +59,17 @@
     fun setUp() {
         allowTestableLooperAsMainThread()
         notificationTestHelper =
-                NotificationTestHelper(mContext, mDependency, TestableLooper.get(this))
+            NotificationTestHelper(mContext, mDependency, TestableLooper.get(this))
         notification = notificationTestHelper.createRow()
-        controller = NotificationLaunchAnimatorController(
-                notificationExpansionRepository,
+        controller =
+            NotificationLaunchAnimatorController(
+                notificationLaunchAnimationInteractor,
                 notificationListContainer,
                 headsUpManager,
                 notification,
                 jankMonitor,
                 onFinishAnimationCallback
-        )
+            )
     }
 
     private fun flagNotificationAsHun() {
@@ -80,13 +83,14 @@
 
         assertTrue(HeadsUpUtil.isClickedHeadsUpNotification(notification))
         assertFalse(notification.entry.isExpandAnimationRunning)
-        val isExpandAnimationRunning by testScope.collectLastValue(
-            notificationExpansionRepository.isExpandAnimationRunning
-        )
+        val isExpandAnimationRunning by
+            testScope.collectLastValue(
+                notificationLaunchAnimationInteractor.isLaunchAnimationRunning
+            )
         assertFalse(isExpandAnimationRunning!!)
 
-        verify(headsUpManager).removeNotification(
-                notificationKey, true /* releaseImmediately */, true /* animate */)
+        verify(headsUpManager)
+            .removeNotification(notificationKey, true /* releaseImmediately */, true /* animate */)
         verify(onFinishAnimationCallback).run()
     }
 
@@ -97,13 +101,14 @@
 
         assertTrue(HeadsUpUtil.isClickedHeadsUpNotification(notification))
         assertFalse(notification.entry.isExpandAnimationRunning)
-        val isExpandAnimationRunning by testScope.collectLastValue(
-            notificationExpansionRepository.isExpandAnimationRunning
-        )
+        val isExpandAnimationRunning by
+            testScope.collectLastValue(
+                notificationLaunchAnimationInteractor.isLaunchAnimationRunning
+            )
         assertFalse(isExpandAnimationRunning!!)
 
-        verify(headsUpManager).removeNotification(
-                notificationKey, true /* releaseImmediately */, true /* animate */)
+        verify(headsUpManager)
+            .removeNotification(notificationKey, true /* releaseImmediately */, true /* animate */)
         verify(onFinishAnimationCallback).run()
     }
 
@@ -114,13 +119,14 @@
 
         assertFalse(HeadsUpUtil.isClickedHeadsUpNotification(notification))
         assertFalse(notification.entry.isExpandAnimationRunning)
-        val isExpandAnimationRunning by testScope.collectLastValue(
-            notificationExpansionRepository.isExpandAnimationRunning
-        )
+        val isExpandAnimationRunning by
+            testScope.collectLastValue(
+                notificationLaunchAnimationInteractor.isLaunchAnimationRunning
+            )
         assertFalse(isExpandAnimationRunning!!)
 
-        verify(headsUpManager).removeNotification(
-                notificationKey, true /* releaseImmediately */, false /* animate */)
+        verify(headsUpManager)
+            .removeNotification(notificationKey, true /* releaseImmediately */, false /* animate */)
         verify(onFinishAnimationCallback).run()
     }
 
@@ -128,15 +134,21 @@
     fun testAlertingSummaryHunRemovedOnNonAlertingChildLaunch() {
         val GROUP_KEY = "test_group_key"
 
-        val summary = NotificationEntryBuilder().setGroup(mContext, GROUP_KEY).setId(0).apply {
-            modifyNotification(mContext).setSmallIcon(R.drawable.ic_person)
-        }.build()
+        val summary =
+            NotificationEntryBuilder()
+                .setGroup(mContext, GROUP_KEY)
+                .setId(0)
+                .apply { modifyNotification(mContext).setSmallIcon(R.drawable.ic_person) }
+                .build()
         assertNotSame(summary.key, notification.entry.key)
 
         notificationTestHelper.createRow(summary)
 
-        GroupEntryBuilder().setKey(GROUP_KEY).setSummary(summary).addChild(notification.entry)
-                .build()
+        GroupEntryBuilder()
+            .setKey(GROUP_KEY)
+            .setSummary(summary)
+            .addChild(notification.entry)
+            .build()
         assertSame(summary, notification.entry.parent?.summary)
 
         `when`(headsUpManager.isAlerting(notificationKey)).thenReturn(false)
@@ -147,10 +159,14 @@
 
         controller.onLaunchAnimationEnd(isExpandingFullyAbove = true)
 
-        verify(headsUpManager).removeNotification(
-                summary.key, true /* releaseImmediately */, false /* animate */)
-        verify(headsUpManager, never()).removeNotification(
-                notification.entry.key, true /* releaseImmediately */, false /* animate */)
+        verify(headsUpManager)
+            .removeNotification(summary.key, true /* releaseImmediately */, false /* animate */)
+        verify(headsUpManager, never())
+            .removeNotification(
+                notification.entry.key,
+                true /* releaseImmediately */,
+                false /* animate */
+            )
     }
 
     @Test
@@ -158,9 +174,10 @@
         controller.onIntentStarted(willAnimate = true)
 
         assertTrue(notification.entry.isExpandAnimationRunning)
-        val isExpandAnimationRunning by testScope.collectLastValue(
-            notificationExpansionRepository.isExpandAnimationRunning
-        )
+        val isExpandAnimationRunning by
+            testScope.collectLastValue(
+                notificationLaunchAnimationInteractor.isLaunchAnimationRunning
+            )
         assertTrue(isExpandAnimationRunning!!)
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/data/repository/NotificationExpansionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/data/repository/NotificationExpansionRepositoryTest.kt
deleted file mode 100644
index f28d9ab..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/data/repository/NotificationExpansionRepositoryTest.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2023 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.systemui.statusbar.notification.data.repository
-
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.coroutines.collectLastValue
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.test.runTest
-import org.junit.Test
-
-@SmallTest
-class NotificationExpansionRepositoryTest : SysuiTestCase() {
-    private val underTest = NotificationExpansionRepository()
-
-    @Test
-    fun setIsExpandAnimationRunning_startsAsFalse() = runTest {
-        val latest by collectLastValue(underTest.isExpandAnimationRunning)
-
-        assertThat(latest).isFalse()
-    }
-
-    @Test
-    fun setIsExpandAnimationRunning_false_emitsTrue() = runTest {
-        val latest by collectLastValue(underTest.isExpandAnimationRunning)
-
-        underTest.setIsExpandAnimationRunning(true)
-
-        assertThat(latest).isTrue()
-    }
-
-    @Test
-    fun setIsExpandAnimationRunning_false_emitsFalse() = runTest {
-        val latest by collectLastValue(underTest.isExpandAnimationRunning)
-        underTest.setIsExpandAnimationRunning(true)
-
-        // WHEN the animation is no longer running
-        underTest.setIsExpandAnimationRunning(false)
-
-        // THEN the flow emits false
-        assertThat(latest).isFalse()
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractorTest.kt
new file mode 100644
index 0000000..a0faab5
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractorTest.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2023 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.systemui.statusbar.notification.domain.interactor
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.statusbar.notification.data.repository.NotificationLaunchAnimationRepository
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+
+@SmallTest
+class NotificationLaunchAnimationInteractorTest : SysuiTestCase() {
+    private val repository = NotificationLaunchAnimationRepository()
+    private val underTest = NotificationLaunchAnimationInteractor(repository)
+
+    @Test
+    fun setIsLaunchAnimationRunning_startsAsFalse() = runTest {
+        val latest by collectLastValue(underTest.isLaunchAnimationRunning)
+
+        assertThat(latest).isFalse()
+    }
+
+    @Test
+    fun setIsLaunchAnimationRunning_false_emitsTrue() = runTest {
+        val latest by collectLastValue(underTest.isLaunchAnimationRunning)
+
+        underTest.setIsLaunchAnimationRunning(true)
+
+        assertThat(latest).isTrue()
+    }
+
+    @Test
+    fun setIsLaunchAnimationRunning_false_emitsFalse() = runTest {
+        val latest by collectLastValue(underTest.isLaunchAnimationRunning)
+        underTest.setIsLaunchAnimationRunning(true)
+
+        // WHEN the animation is no longer running
+        underTest.setIsLaunchAnimationRunning(false)
+
+        // THEN the flow emits false
+        assertThat(latest).isFalse()
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt
index 8c5c439..ca8ea4e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt
@@ -35,6 +35,7 @@
     private val underTest =
         RenderNotificationListInteractor(
             notifsRepository,
+            sectionStyleProvider = mock(),
         )
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterViewTest.java
index f72142f..cc87d7c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterViewTest.java
@@ -22,8 +22,15 @@
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertTrue;
 
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
 
+import android.content.Context;
 import android.testing.AndroidTestingRunner;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -31,6 +38,7 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.res.R;
 
@@ -44,9 +52,13 @@
 
     FooterView mView;
 
+    Context mSpyContext = spy(mContext);
+
     @Before
     public void setUp() {
-        mView = (FooterView) LayoutInflater.from(mContext).inflate(
+        mSetFlagsRule.enableFlags(Flags.FLAG_NOTIFICATIONS_FOOTER_VIEW_REFACTOR);
+
+        mView = (FooterView) LayoutInflater.from(mSpyContext).inflate(
                 R.layout.status_bar_notification_footer, null, false);
         mView.setDuration(0);
     }
@@ -102,6 +114,37 @@
     }
 
     @Test
+    public void testSetMessageString_resourceOnlyFetchedOnce() {
+        mView.setMessageString(R.string.unlock_to_see_notif_text);
+        verify(mSpyContext).getString(eq(R.string.unlock_to_see_notif_text));
+
+        clearInvocations(mSpyContext);
+
+        assertThat(((TextView) mView.findViewById(R.id.unlock_prompt_footer))
+                .getText().toString()).contains("Unlock");
+
+        // Set it a few more times, it shouldn't lead to the resource being fetched again
+        mView.setMessageString(R.string.unlock_to_see_notif_text);
+        mView.setMessageString(R.string.unlock_to_see_notif_text);
+
+        verify(mSpyContext, never()).getString(anyInt());
+    }
+
+    @Test
+    public void testSetMessageIcon_resourceOnlyFetchedOnce() {
+        mView.setMessageIcon(R.drawable.ic_friction_lock_closed);
+        verify(mSpyContext).getDrawable(eq(R.drawable.ic_friction_lock_closed));
+
+        clearInvocations(mSpyContext);
+
+        // Set it a few more times, it shouldn't lead to the resource being fetched again
+        mView.setMessageIcon(R.drawable.ic_friction_lock_closed);
+        mView.setMessageIcon(R.drawable.ic_friction_lock_closed);
+
+        verify(mSpyContext, never()).getDrawable(anyInt());
+    }
+
+    @Test
     public void testSetFooterLabelVisible() {
         mView.setFooterLabelVisible(true);
         assertThat(mView.findViewById(R.id.manage_text).getVisibility()).isEqualTo(View.GONE);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelTest.kt
new file mode 100644
index 0000000..57a7c3c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelTest.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 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.systemui.statusbar.notification.footer.ui.viewmodel
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository
+import com.android.systemui.statusbar.notification.domain.interactor.SeenNotificationsInteractor
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class FooterViewModelTest : SysuiTestCase() {
+    private val repository = ActiveNotificationListRepository()
+    private val interactor = SeenNotificationsInteractor(repository)
+    private val underTest = FooterViewModel(interactor)
+
+    @Test
+    fun testMessageVisible_whenFilteredNotifications() = runTest {
+        val message by collectLastValue(underTest.message)
+
+        repository.hasFilteredOutSeenNotifications.value = true
+
+        assertThat(message?.visible).isTrue()
+    }
+
+    @Test
+    fun testMessageVisible_whenNoFilteredNotifications() = runTest {
+        val message by collectLastValue(underTest.message)
+
+        repository.hasFilteredOutSeenNotifications.value = false
+
+        assertThat(message?.visible).isFalse()
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt
new file mode 100644
index 0000000..ec80e5f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2023 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.systemui.statusbar.notification.icon.domain.interactor
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.SysUITestModule
+import com.android.TestMocksModule
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepository
+import com.android.systemui.statusbar.data.repository.NotificationListenerSettingsRepository
+import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository
+import com.android.systemui.statusbar.notification.data.repository.FakeNotificationsKeyguardViewStateRepository
+import com.android.systemui.statusbar.notification.shared.activeNotificationModel
+import com.android.systemui.statusbar.notification.shared.byIsAmbient
+import com.android.systemui.statusbar.notification.shared.byIsLastMessageFromReply
+import com.android.systemui.statusbar.notification.shared.byIsPulsing
+import com.android.systemui.statusbar.notification.shared.byIsRowDismissed
+import com.android.systemui.statusbar.notification.shared.byIsSilent
+import com.android.systemui.statusbar.notification.shared.byIsSuppressedFromStatusBar
+import com.android.systemui.statusbar.notification.shared.byKey
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.android.wm.shell.bubbles.Bubbles
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import java.util.Optional
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class NotificationIconsInteractorTest : SysuiTestCase() {
+
+    private val bubbles: Bubbles = mock()
+
+    @Component(modules = [SysUITestModule::class])
+    @SysUISingleton
+    interface TestComponent {
+        val underTest: NotificationIconsInteractor
+
+        val activeNotificationListRepository: ActiveNotificationListRepository
+        val keyguardViewStateRepository: FakeNotificationsKeyguardViewStateRepository
+        val testScope: TestScope
+
+        @Component.Factory
+        interface Factory {
+            fun create(@BindsInstance test: SysuiTestCase, mocks: TestMocksModule): TestComponent
+        }
+    }
+
+    val testComponent: TestComponent =
+        DaggerNotificationIconsInteractorTest_TestComponent.factory()
+            .create(test = this, mocks = TestMocksModule(bubbles = Optional.of(bubbles)))
+
+    @Before
+    fun setup() =
+        with(testComponent) {
+            activeNotificationListRepository.activeNotifications.value =
+                testIcons.associateBy { it.key }
+        }
+
+    @Test
+    fun filteredEntrySet() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by collectLastValue(underTest.filteredNotifSet())
+                assertThat(filteredSet).containsExactlyElementsIn(testIcons)
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_noExpandedBubbles() =
+        with(testComponent) {
+            testScope.runTest {
+                whenever(bubbles.isBubbleExpanded(eq("notif1"))).thenReturn(true)
+                val filteredSet by collectLastValue(underTest.filteredNotifSet())
+                assertThat(filteredSet).comparingElementsUsing(byKey).doesNotContain("notif1")
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_noAmbient() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by collectLastValue(underTest.filteredNotifSet(showAmbient = false))
+                assertThat(filteredSet).comparingElementsUsing(byIsAmbient).doesNotContain(true)
+                assertThat(filteredSet)
+                    .comparingElementsUsing(byIsSuppressedFromStatusBar)
+                    .doesNotContain(true)
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_noLowPriority() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by
+                    collectLastValue(underTest.filteredNotifSet(showLowPriority = false))
+                assertThat(filteredSet).comparingElementsUsing(byIsSilent).doesNotContain(true)
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_noDismissed() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by
+                    collectLastValue(underTest.filteredNotifSet(showDismissed = false))
+                assertThat(filteredSet)
+                    .comparingElementsUsing(byIsRowDismissed)
+                    .doesNotContain(true)
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_noRepliedMessages() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by
+                    collectLastValue(underTest.filteredNotifSet(showRepliedMessages = false))
+                assertThat(filteredSet)
+                    .comparingElementsUsing(byIsLastMessageFromReply)
+                    .doesNotContain(true)
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_noPulsing_notifsNotFullyHidden() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by collectLastValue(underTest.filteredNotifSet(showPulsing = false))
+                keyguardViewStateRepository.setNotificationsFullyHidden(false)
+                assertThat(filteredSet).comparingElementsUsing(byIsPulsing).doesNotContain(true)
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_noPulsing_notifsFullyHidden() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by collectLastValue(underTest.filteredNotifSet(showPulsing = false))
+                keyguardViewStateRepository.setNotificationsFullyHidden(true)
+                assertThat(filteredSet).comparingElementsUsing(byIsPulsing).contains(true)
+            }
+        }
+}
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class AlwaysOnDisplayNotificationIconsInteractorTest : SysuiTestCase() {
+
+    private val bubbles: Bubbles = mock()
+
+    @Component(modules = [SysUITestModule::class])
+    @SysUISingleton
+    interface TestComponent {
+        val underTest: AlwaysOnDisplayNotificationIconsInteractor
+
+        val activeNotificationListRepository: ActiveNotificationListRepository
+        val deviceEntryRepository: FakeDeviceEntryRepository
+        val keyguardViewStateRepository: FakeNotificationsKeyguardViewStateRepository
+        val testScope: TestScope
+
+        @Component.Factory
+        interface Factory {
+            fun create(@BindsInstance test: SysuiTestCase, mocks: TestMocksModule): TestComponent
+        }
+    }
+
+    val testComponent: TestComponent =
+        DaggerAlwaysOnDisplayNotificationIconsInteractorTest_TestComponent.factory()
+            .create(test = this, mocks = TestMocksModule(bubbles = Optional.of(bubbles)))
+
+    @Before
+    fun setup() =
+        with(testComponent) {
+            activeNotificationListRepository.activeNotifications.value =
+                testIcons.associateBy { it.key }
+        }
+
+    @Test
+    fun filteredEntrySet_noExpandedBubbles() =
+        with(testComponent) {
+            testScope.runTest {
+                whenever(bubbles.isBubbleExpanded(eq("notif1"))).thenReturn(true)
+                val filteredSet by collectLastValue(underTest.aodNotifs)
+                assertThat(filteredSet).comparingElementsUsing(byKey).doesNotContain("notif1")
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_noAmbient() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by collectLastValue(underTest.aodNotifs)
+                assertThat(filteredSet).comparingElementsUsing(byIsAmbient).doesNotContain(true)
+                assertThat(filteredSet)
+                    .comparingElementsUsing(byIsSuppressedFromStatusBar)
+                    .doesNotContain(true)
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_noDismissed() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by collectLastValue(underTest.aodNotifs)
+                assertThat(filteredSet)
+                    .comparingElementsUsing(byIsRowDismissed)
+                    .doesNotContain(true)
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_noRepliedMessages() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by collectLastValue(underTest.aodNotifs)
+                assertThat(filteredSet)
+                    .comparingElementsUsing(byIsLastMessageFromReply)
+                    .doesNotContain(true)
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_showPulsing_notifsNotFullyHidden_bypassDisabled() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by collectLastValue(underTest.aodNotifs)
+                deviceEntryRepository.setBypassEnabled(false)
+                keyguardViewStateRepository.setNotificationsFullyHidden(false)
+                assertThat(filteredSet).comparingElementsUsing(byIsPulsing).contains(true)
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_showPulsing_notifsFullyHidden_bypassDisabled() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by collectLastValue(underTest.aodNotifs)
+                deviceEntryRepository.setBypassEnabled(false)
+                keyguardViewStateRepository.setNotificationsFullyHidden(true)
+                assertThat(filteredSet).comparingElementsUsing(byIsPulsing).contains(true)
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_noPulsing_notifsNotFullyHidden_bypassEnabled() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by collectLastValue(underTest.aodNotifs)
+                deviceEntryRepository.setBypassEnabled(true)
+                keyguardViewStateRepository.setNotificationsFullyHidden(false)
+                assertThat(filteredSet).comparingElementsUsing(byIsPulsing).doesNotContain(true)
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_showPulsing_notifsFullyHidden_bypassEnabled() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by collectLastValue(underTest.aodNotifs)
+                deviceEntryRepository.setBypassEnabled(true)
+                keyguardViewStateRepository.setNotificationsFullyHidden(true)
+                assertThat(filteredSet).comparingElementsUsing(byIsPulsing).contains(true)
+            }
+        }
+}
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class StatusBarNotificationIconsInteractorTest : SysuiTestCase() {
+
+    private val bubbles: Bubbles = mock()
+
+    @Component(modules = [SysUITestModule::class])
+    @SysUISingleton
+    interface TestComponent {
+        val underTest: StatusBarNotificationIconsInteractor
+
+        val activeNotificationListRepository: ActiveNotificationListRepository
+        val keyguardViewStateRepository: FakeNotificationsKeyguardViewStateRepository
+        val notificationListenerSettingsRepository: NotificationListenerSettingsRepository
+        val testScope: TestScope
+
+        @Component.Factory
+        interface Factory {
+            fun create(@BindsInstance test: SysuiTestCase, mocks: TestMocksModule): TestComponent
+        }
+    }
+
+    val testComponent: TestComponent =
+        DaggerStatusBarNotificationIconsInteractorTest_TestComponent.factory()
+            .create(test = this, mocks = TestMocksModule(bubbles = Optional.of(bubbles)))
+
+    @Before
+    fun setup() =
+        with(testComponent) {
+            activeNotificationListRepository.activeNotifications.value =
+                testIcons.associateBy { it.key }
+        }
+
+    @Test
+    fun filteredEntrySet_noExpandedBubbles() =
+        with(testComponent) {
+            testScope.runTest {
+                whenever(bubbles.isBubbleExpanded(eq("notif1"))).thenReturn(true)
+                val filteredSet by collectLastValue(underTest.statusBarNotifs)
+                assertThat(filteredSet).comparingElementsUsing(byKey).doesNotContain("notif1")
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_noAmbient() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by collectLastValue(underTest.statusBarNotifs)
+                assertThat(filteredSet).comparingElementsUsing(byIsAmbient).doesNotContain(true)
+                assertThat(filteredSet)
+                    .comparingElementsUsing(byIsSuppressedFromStatusBar)
+                    .doesNotContain(true)
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_noLowPriority_whenDontShowSilentIcons() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by collectLastValue(underTest.statusBarNotifs)
+                notificationListenerSettingsRepository.showSilentStatusIcons.value = false
+                assertThat(filteredSet).comparingElementsUsing(byIsSilent).doesNotContain(true)
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_showLowPriority_whenShowSilentIcons() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by collectLastValue(underTest.statusBarNotifs)
+                notificationListenerSettingsRepository.showSilentStatusIcons.value = true
+                assertThat(filteredSet).comparingElementsUsing(byIsSilent).contains(true)
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_noDismissed() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by collectLastValue(underTest.statusBarNotifs)
+                assertThat(filteredSet)
+                    .comparingElementsUsing(byIsRowDismissed)
+                    .doesNotContain(true)
+            }
+        }
+
+    @Test
+    fun filteredEntrySet_noRepliedMessages() =
+        with(testComponent) {
+            testScope.runTest {
+                val filteredSet by collectLastValue(underTest.statusBarNotifs)
+                assertThat(filteredSet)
+                    .comparingElementsUsing(byIsLastMessageFromReply)
+                    .doesNotContain(true)
+            }
+        }
+}
+
+private val testIcons =
+    listOf(
+        activeNotificationModel(
+            key = "notif1",
+        ),
+        activeNotificationModel(
+            key = "notif2",
+            isAmbient = true,
+        ),
+        activeNotificationModel(
+            key = "notif3",
+            isRowDismissed = true,
+        ),
+        activeNotificationModel(
+            key = "notif4",
+            isSilent = true,
+        ),
+        activeNotificationModel(
+            key = "notif5",
+            isLastMessageFromReply = true,
+        ),
+        activeNotificationModel(
+            key = "notif6",
+            isSuppressedFromStatusBar = true,
+        ),
+        activeNotificationModel(
+            key = "notif7",
+            isPulsing = true,
+        ),
+    )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImplTest.kt
deleted file mode 100644
index e57986d..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImplTest.kt
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2023 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.systemui.statusbar.notification.icon.ui.viewbinder
-
-import android.testing.AndroidTestingRunner
-import android.testing.TestableLooper.RunWithLooper
-import androidx.test.filters.SmallTest
-import com.android.SysUITestModule
-import com.android.TestMocksModule
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.domain.BiometricsDomainLayerModule
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.flags.FakeFeatureFlagsClassicModule
-import com.android.systemui.flags.Flags
-import com.android.systemui.statusbar.phone.DozeParameters
-import com.android.systemui.user.domain.UserDomainLayerModule
-import dagger.BindsInstance
-import dagger.Component
-import org.junit.Assert.assertFalse
-import org.junit.Assert.assertTrue
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
-
-@SmallTest
-@RunWith(AndroidTestingRunner::class)
-@RunWithLooper(setAsMainLooper = true)
-class NotificationIconAreaControllerViewBinderWrapperImplTest : SysuiTestCase() {
-
-    @Mock private lateinit var dozeParams: DozeParameters
-
-    private lateinit var testComponent: TestComponent
-    private val underTest
-        get() = testComponent.underTest
-
-    @Before
-    fun setup() {
-        MockitoAnnotations.initMocks(this)
-        allowTestableLooperAsMainThread()
-
-        testComponent =
-            DaggerNotificationIconAreaControllerViewBinderWrapperImplTest_TestComponent.factory()
-                .create(
-                    test = this,
-                    featureFlags =
-                        FakeFeatureFlagsClassicModule {
-                            set(Flags.FACE_AUTH_REFACTOR, value = false)
-                            set(Flags.MIGRATE_KEYGUARD_STATUS_VIEW, value = false)
-                        },
-                    mocks =
-                        TestMocksModule(
-                            dozeParameters = dozeParams,
-                        ),
-                )
-    }
-
-    @Test
-    fun testNotificationIcons_settingHideIcons() {
-        underTest.settingsListener.onStatusBarIconsBehaviorChanged(true)
-        assertFalse(underTest.shouldShowLowPriorityIcons())
-    }
-
-    @Test
-    fun testNotificationIcons_settingShowIcons() {
-        underTest.settingsListener.onStatusBarIconsBehaviorChanged(false)
-        assertTrue(underTest.shouldShowLowPriorityIcons())
-    }
-
-    @SysUISingleton
-    @Component(
-        modules =
-            [
-                SysUITestModule::class,
-                BiometricsDomainLayerModule::class,
-                UserDomainLayerModule::class,
-            ]
-    )
-    interface TestComponent {
-
-        val underTest: NotificationIconAreaControllerViewBinderWrapperImpl
-
-        @Component.Factory
-        interface Factory {
-            fun create(
-                @BindsInstance test: SysuiTestCase,
-                mocks: TestMocksModule,
-                featureFlags: FakeFeatureFlagsClassicModule,
-            ): TestComponent
-        }
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
index 31efebb..41c7071 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
@@ -44,7 +44,9 @@
 import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository
 import com.android.systemui.user.domain.UserDomainLayerModule
 import com.android.systemui.util.mockito.whenever
-import com.android.systemui.util.ui.AnimatedValue
+import com.android.systemui.util.ui.isAnimating
+import com.android.systemui.util.ui.stopAnimating
+import com.android.systemui.util.ui.value
 import com.google.common.truth.Truth.assertThat
 import dagger.BindsInstance
 import dagger.Component
@@ -243,6 +245,7 @@
                 )
             )
             val animationsEnabled by collectLastValue(underTest.animationsEnabled)
+            runCurrent()
 
             keyguardRepository.setKeyguardShowing(true)
             keyguardRepository.setKeyguardOccluded(false)
@@ -266,6 +269,7 @@
     fun isDozing_startAodTransition() =
         scope.runTest {
             val isDozing by collectLastValue(underTest.isDozing)
+            runCurrent()
             keyguardTransitionRepository.sendTransitionStep(
                 TransitionStep(
                     from = KeyguardState.GONE,
@@ -274,13 +278,15 @@
                 )
             )
             runCurrent()
-            assertThat(isDozing).isEqualTo(AnimatedValue(true, isAnimating = true))
+            assertThat(isDozing?.value).isTrue()
+            assertThat(isDozing?.isAnimating).isTrue()
         }
 
     @Test
     fun isDozing_startDozeTransition() =
         scope.runTest {
             val isDozing by collectLastValue(underTest.isDozing)
+            runCurrent()
             keyguardTransitionRepository.sendTransitionStep(
                 TransitionStep(
                     from = KeyguardState.GONE,
@@ -289,13 +295,15 @@
                 )
             )
             runCurrent()
-            assertThat(isDozing).isEqualTo(AnimatedValue(true, isAnimating = false))
+            assertThat(isDozing?.value).isTrue()
+            assertThat(isDozing?.isAnimating).isFalse()
         }
 
     @Test
     fun isDozing_startDozeToAodTransition() =
         scope.runTest {
             val isDozing by collectLastValue(underTest.isDozing)
+            runCurrent()
             keyguardTransitionRepository.sendTransitionStep(
                 TransitionStep(
                     from = KeyguardState.DOZING,
@@ -304,13 +312,15 @@
                 )
             )
             runCurrent()
-            assertThat(isDozing).isEqualTo(AnimatedValue(true, isAnimating = true))
+            assertThat(isDozing?.value).isTrue()
+            assertThat(isDozing?.isAnimating).isTrue()
         }
 
     @Test
     fun isNotDozing_startAodToGoneTransition() =
         scope.runTest {
             val isDozing by collectLastValue(underTest.isDozing)
+            runCurrent()
             keyguardTransitionRepository.sendTransitionStep(
                 TransitionStep(
                     from = KeyguardState.AOD,
@@ -319,13 +329,15 @@
                 )
             )
             runCurrent()
-            assertThat(isDozing).isEqualTo(AnimatedValue(false, isAnimating = true))
+            assertThat(isDozing?.value).isFalse()
+            assertThat(isDozing?.isAnimating).isTrue()
         }
 
     @Test
     fun isDozing_stopAnimation() =
         scope.runTest {
             val isDozing by collectLastValue(underTest.isDozing)
+            runCurrent()
             keyguardTransitionRepository.sendTransitionStep(
                 TransitionStep(
                     from = KeyguardState.AOD,
@@ -335,7 +347,8 @@
             )
             runCurrent()
 
-            underTest.completeDozeAnimation()
+            assertThat(isDozing?.isAnimating).isEqualTo(true)
+            isDozing?.stopAnimating()
             runCurrent()
 
             assertThat(isDozing?.isAnimating).isEqualTo(false)
@@ -345,6 +358,7 @@
     fun isNotVisible_pulseExpanding() =
         scope.runTest {
             val isVisible by collectLastValue(underTest.isVisible)
+            runCurrent()
             notifsKeyguardRepository.setPulseExpanding(true)
             runCurrent()
 
@@ -355,6 +369,7 @@
     fun isNotVisible_notOnKeyguard_dontShowAodIconsWhenShade() =
         scope.runTest {
             val isVisible by collectLastValue(underTest.isVisible)
+            runCurrent()
             keyguardTransitionRepository.sendTransitionStep(
                 TransitionStep(
                     to = KeyguardState.GONE,
@@ -364,13 +379,15 @@
             whenever(screenOffAnimController.shouldShowAodIconsWhenShade()).thenReturn(false)
             runCurrent()
 
-            assertThat(isVisible).isEqualTo(AnimatedValue(false, isAnimating = false))
+            assertThat(isVisible?.value).isFalse()
+            assertThat(isVisible?.isAnimating).isFalse()
         }
 
     @Test
     fun isVisible_bypassEnabled() =
         scope.runTest {
             val isVisible by collectLastValue(underTest.isVisible)
+            runCurrent()
             deviceEntryRepository.setBypassEnabled(true)
             runCurrent()
 
@@ -381,6 +398,7 @@
     fun isNotVisible_pulseExpanding_notBypassing() =
         scope.runTest {
             val isVisible by collectLastValue(underTest.isVisible)
+            runCurrent()
             notifsKeyguardRepository.setPulseExpanding(true)
             deviceEntryRepository.setBypassEnabled(false)
             runCurrent()
@@ -398,26 +416,30 @@
             notifsKeyguardRepository.setNotificationsFullyHidden(true)
             runCurrent()
 
-            assertThat(isVisible).isEqualTo(AnimatedValue(true, isAnimating = true))
+            assertThat(isVisible?.value).isTrue()
+            assertThat(isVisible?.isAnimating).isTrue()
         }
 
     @Test
     fun isVisible_notifsFullyHidden_bypassDisabled_aodDisabled() =
         scope.runTest {
             val isVisible by collectLastValue(underTest.isVisible)
+            runCurrent()
             notifsKeyguardRepository.setPulseExpanding(false)
             deviceEntryRepository.setBypassEnabled(false)
             whenever(dozeParams.alwaysOn).thenReturn(false)
             notifsKeyguardRepository.setNotificationsFullyHidden(true)
             runCurrent()
 
-            assertThat(isVisible).isEqualTo(AnimatedValue(true, isAnimating = false))
+            assertThat(isVisible?.value).isTrue()
+            assertThat(isVisible?.isAnimating).isFalse()
         }
 
     @Test
     fun isVisible_notifsFullyHidden_bypassDisabled_displayNeedsBlanking() =
         scope.runTest {
             val isVisible by collectLastValue(underTest.isVisible)
+            runCurrent()
             notifsKeyguardRepository.setPulseExpanding(false)
             deviceEntryRepository.setBypassEnabled(false)
             whenever(dozeParams.alwaysOn).thenReturn(true)
@@ -425,7 +447,8 @@
             notifsKeyguardRepository.setNotificationsFullyHidden(true)
             runCurrent()
 
-            assertThat(isVisible).isEqualTo(AnimatedValue(true, isAnimating = false))
+            assertThat(isVisible?.value).isTrue()
+            assertThat(isVisible?.isAnimating).isFalse()
         }
 
     @Test
@@ -440,13 +463,15 @@
             notifsKeyguardRepository.setNotificationsFullyHidden(true)
             runCurrent()
 
-            assertThat(isVisible).isEqualTo(AnimatedValue(true, isAnimating = true))
+            assertThat(isVisible?.value).isTrue()
+            assertThat(isVisible?.isAnimating).isTrue()
         }
 
     @Test
     fun isVisible_stopAnimation() =
         scope.runTest {
             val isVisible by collectLastValue(underTest.isVisible)
+            runCurrent()
             notifsKeyguardRepository.setPulseExpanding(false)
             deviceEntryRepository.setBypassEnabled(false)
             whenever(dozeParams.alwaysOn).thenReturn(true)
@@ -454,7 +479,8 @@
             notifsKeyguardRepository.setNotificationsFullyHidden(true)
             runCurrent()
 
-            underTest.completeVisibilityAnimation()
+            assertThat(isVisible?.isAnimating).isEqualTo(true)
+            isVisible?.stopAnimating()
             runCurrent()
 
             assertThat(isVisible?.isAnimating).isEqualTo(false)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt
index e21ebeb..ba68fbb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt
@@ -18,6 +18,7 @@
 package com.android.systemui.statusbar.notification.icon.ui.viewmodel
 
 import android.graphics.Rect
+import android.graphics.drawable.Icon
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.SysUITestModule
@@ -39,12 +40,19 @@
 import com.android.systemui.power.data.repository.FakePowerRepository
 import com.android.systemui.power.shared.model.WakeSleepReason
 import com.android.systemui.power.shared.model.WakefulnessState
+import com.android.systemui.shade.data.repository.FakeShadeRepository
+import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository
+import com.android.systemui.statusbar.notification.data.repository.HeadsUpNotificationIconViewStateRepository
+import com.android.systemui.statusbar.notification.shared.activeNotificationModel
 import com.android.systemui.statusbar.phone.DozeParameters
 import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher
 import com.android.systemui.statusbar.phone.data.repository.FakeDarkIconRepository
 import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository
 import com.android.systemui.user.domain.UserDomainLayerModule
+import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.ui.isAnimating
+import com.android.systemui.util.ui.value
 import com.google.common.truth.Truth.assertThat
 import dagger.BindsInstance
 import dagger.Component
@@ -327,6 +335,58 @@
             }
         }
 
+    @Test
+    fun isolatedIcon_animateOnAppear_shadeCollapsed() =
+        with(testComponent) {
+            scope.runTest {
+                val icon: Icon = mock()
+                shadeRepository.setLegacyShadeExpansion(0f)
+                activeNotificationsRepository.activeNotifications.value =
+                    listOf(
+                            activeNotificationModel(
+                                key = "notif1",
+                                groupKey = "group",
+                                statusBarIcon = icon
+                            )
+                        )
+                        .associateBy { it.key }
+                val isolatedIcon by collectLastValue(underTest.isolatedIcon)
+                runCurrent()
+
+                headsUpViewStateRepository.isolatedNotification.value = "notif1"
+                runCurrent()
+
+                assertThat(isolatedIcon?.value?.notifKey).isEqualTo("notif1")
+                assertThat(isolatedIcon?.isAnimating).isTrue()
+            }
+        }
+
+    @Test
+    fun isolatedIcon_dontAnimateOnAppear_shadeExpanded() =
+        with(testComponent) {
+            scope.runTest {
+                val icon: Icon = mock()
+                shadeRepository.setLegacyShadeExpansion(.5f)
+                activeNotificationsRepository.activeNotifications.value =
+                    listOf(
+                            activeNotificationModel(
+                                key = "notif1",
+                                groupKey = "group",
+                                statusBarIcon = icon
+                            )
+                        )
+                        .associateBy { it.key }
+                val isolatedIcon by collectLastValue(underTest.isolatedIcon)
+                runCurrent()
+
+                headsUpViewStateRepository.isolatedNotification.value = "notif1"
+                runCurrent()
+
+                assertThat(isolatedIcon?.value?.notifKey).isEqualTo("notif1")
+                assertThat(isolatedIcon?.isAnimating).isFalse()
+            }
+        }
+
     @SysUISingleton
     @Component(
         modules =
@@ -340,11 +400,14 @@
 
         val underTest: NotificationIconContainerStatusBarViewModel
 
+        val activeNotificationsRepository: ActiveNotificationListRepository
         val darkIconRepository: FakeDarkIconRepository
         val deviceProvisioningRepository: FakeDeviceProvisioningRepository
+        val headsUpViewStateRepository: HeadsUpNotificationIconViewStateRepository
         val keyguardTransitionRepository: FakeKeyguardTransitionRepository
         val keyguardRepository: FakeKeyguardRepository
         val powerRepository: FakePowerRepository
+        val shadeRepository: FakeShadeRepository
         val scope: TestScope
 
         @Component.Factory
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt
index ed94058..ca105f3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt
@@ -15,7 +15,53 @@
 
 package com.android.systemui.statusbar.notification.shared
 
+import android.graphics.drawable.Icon
 import com.google.common.truth.Correspondence
 
 val byKey: Correspondence<ActiveNotificationModel, String> =
     Correspondence.transforming({ it?.key }, "has a key of")
+val byIsAmbient: Correspondence<ActiveNotificationModel, Boolean> =
+    Correspondence.transforming({ it?.isAmbient }, "has an isAmbient value of")
+val byIsSuppressedFromStatusBar: Correspondence<ActiveNotificationModel, Boolean> =
+    Correspondence.transforming(
+        { it?.isSuppressedFromStatusBar },
+        "has an isSuppressedFromStatusBar value of",
+    )
+val byIsSilent: Correspondence<ActiveNotificationModel, Boolean> =
+    Correspondence.transforming({ it?.isSilent }, "has an isSilent value of")
+val byIsRowDismissed: Correspondence<ActiveNotificationModel, Boolean> =
+    Correspondence.transforming({ it?.isRowDismissed }, "has an isRowDismissed value of")
+val byIsLastMessageFromReply: Correspondence<ActiveNotificationModel, Boolean> =
+    Correspondence.transforming(
+        { it?.isLastMessageFromReply },
+        "has an isLastMessageFromReply value of"
+    )
+val byIsPulsing: Correspondence<ActiveNotificationModel, Boolean> =
+    Correspondence.transforming({ it?.isPulsing }, "has an isPulsing value of")
+
+fun activeNotificationModel(
+    key: String,
+    groupKey: String? = null,
+    isAmbient: Boolean = false,
+    isRowDismissed: Boolean = false,
+    isSilent: Boolean = false,
+    isLastMessageFromReply: Boolean = false,
+    isSuppressedFromStatusBar: Boolean = false,
+    isPulsing: Boolean = false,
+    aodIcon: Icon? = null,
+    shelfIcon: Icon? = null,
+    statusBarIcon: Icon? = null,
+) =
+    ActiveNotificationModel(
+        key = key,
+        groupKey = groupKey,
+        isAmbient = isAmbient,
+        isRowDismissed = isRowDismissed,
+        isSilent = isSilent,
+        isLastMessageFromReply = isLastMessageFromReply,
+        isSuppressedFromStatusBar = isSuppressedFromStatusBar,
+        isPulsing = isPulsing,
+        aodIcon = aodIcon,
+        shelfIcon = shelfIcon,
+        statusBarIcon = statusBarIcon,
+    )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 033c96a..8f36d4f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -19,6 +19,8 @@
 import static android.view.View.GONE;
 import static android.view.WindowInsets.Type.ime;
 
+import static com.android.systemui.Flags.FLAG_NOTIFICATIONS_FOOTER_VIEW_REFACTOR;
+import static com.android.systemui.flags.SetFlagsRuleExtensionsKt.setFlagDefault;
 import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
 import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE;
 import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.RUBBER_BAND_FACTOR_NORMAL;
@@ -165,6 +167,11 @@
         mFeatureFlags.setDefault(Flags.NOTIFICATION_SHELF_REFACTOR);
         mFeatureFlags.setDefault(Flags.NEW_AOD_TRANSITION);
         mFeatureFlags.setDefault(Flags.UNCLEARED_TRANSIENT_HUN_FIX);
+        // Some tests in this file test the FooterView. Since we're refactoring the FooterView
+        // business logic out of the NSSL, the behavior tested in this file will eventually be
+        // tested directly in the new FooterView stack. For now, we just want to make sure that the
+        // old behavior is preserved when the flag is off.
+        setFlagDefault(mSetFlagsRule, FLAG_NOTIFICATIONS_FOOTER_VIEW_REFACTOR);
 
         // Inject dependencies before initializing the layout
         mDependency.injectTestDependency(FeatureFlags.class, mFeatureFlags);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index 49906dc..08ef477 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
@@ -62,6 +62,10 @@
         )
 
     private val testableResources = mContext.getOrCreateTestableResources()
+    private val maxPanelHeight =
+        mContext.resources.displayMetrics.heightPixels -
+                px(R.dimen.notification_panel_margin_top) -
+                px(R.dimen.notification_panel_margin_bottom)
 
     private fun px(@DimenRes id: Int): Float =
             testableResources.resources.getDimensionPixelSize(id).toFloat()
@@ -147,7 +151,7 @@
         stackScrollAlgorithm.initView(context)
         hostView.removeAllViews()
         hostView.addView(emptyShadeView)
-        ambientState.layoutMaxHeight = 1280
+        ambientState.layoutMaxHeight = maxPanelHeight.toInt()
 
         stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
 
@@ -155,7 +159,7 @@
                 context.resources.getDimensionPixelSize(R.dimen.notification_panel_margin_bottom)
         val fullHeight = ambientState.layoutMaxHeight + marginBottom - ambientState.stackY
         val centeredY = ambientState.stackY + fullHeight / 2f - emptyShadeView.height / 2f
-        assertThat(emptyShadeView.viewState?.yTranslation).isEqualTo(centeredY)
+        assertThat(emptyShadeView.viewState.yTranslation).isEqualTo(centeredY)
     }
 
     @Test
@@ -356,7 +360,7 @@
         whenever(notificationRow.canViewBeCleared()).thenReturn(false)
         ambientState.isClearAllInProgress = true
         ambientState.isShadeExpanded = true
-        ambientState.stackEndHeight = 1000f // plenty space for the footer in the stack
+        ambientState.stackEndHeight = maxPanelHeight // plenty space for the footer in the stack
         hostView.addView(footerView)
 
         stackScrollAlgorithm.resetViewStates(ambientState, 0)
@@ -370,7 +374,7 @@
         whenever(notificationRow.canViewBeCleared()).thenReturn(true)
         ambientState.isClearAllInProgress = true
         ambientState.isShadeExpanded = true
-        ambientState.stackEndHeight = 1000f // plenty space for the footer in the stack
+        ambientState.stackEndHeight = maxPanelHeight // plenty space for the footer in the stack
         hostView.addView(footerView)
 
         stackScrollAlgorithm.resetViewStates(ambientState, 0)
@@ -382,7 +386,7 @@
     fun resetViewStates_clearAllInProgress_allRowsRemoved_emptyShade_footerHidden() {
         ambientState.isClearAllInProgress = true
         ambientState.isShadeExpanded = true
-        ambientState.stackEndHeight = 1000f // plenty space for the footer in the stack
+        ambientState.stackEndHeight = maxPanelHeight // plenty space for the footer in the stack
         hostView.removeAllViews() // remove all rows
         hostView.addView(footerView)
 
@@ -1006,7 +1010,7 @@
     }
 
     private fun resetViewStates_stackMargin_changesHunYTranslation() {
-        val stackTopMargin = 50
+        val stackTopMargin = bigGap.toInt() // a gap smaller than the headsUpInset
         val headsUpTranslationY = stackScrollAlgorithm.mHeadsUpInset - stackTopMargin
 
         // we need the shelf to mock the real-life behaviour of StackScrollAlgorithm#updateChild
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt
index 68f2728..7de05ad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt
@@ -19,11 +19,14 @@
 import android.os.RemoteException
 import android.os.UserHandle
 import android.testing.AndroidTestingRunner
+import android.view.View
+import android.widget.FrameLayout
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.ActivityIntentHelper
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ActivityLaunchAnimator
+import com.android.systemui.animation.LaunchableView
 import com.android.systemui.assist.AssistManager
 import com.android.systemui.keyguard.KeyguardViewMediator
 import com.android.systemui.keyguard.WakefulnessLifecycle
@@ -41,6 +44,7 @@
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.nullable
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
@@ -49,6 +53,7 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
 import org.mockito.Mockito.anyBoolean
 import org.mockito.Mockito.mock
@@ -116,16 +121,51 @@
     @Test
     fun startPendingIntentDismissingKeyguard_keyguardShowing_dismissWithAction() {
         val pendingIntent = mock(PendingIntent::class.java)
+        whenever(pendingIntent.isActivity).thenReturn(true)
         whenever(keyguardStateController.isShowing).thenReturn(true)
         whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
 
         underTest.startPendingIntentDismissingKeyguard(pendingIntent)
+        mainExecutor.runAllReady()
 
         verify(statusBarKeyguardViewManager)
             .dismissWithAction(any(OnDismissAction::class.java), eq(null), anyBoolean(), eq(null))
     }
 
     @Test
+    fun startPendingIntentMaybeDismissingKeyguard_keyguardShowing_showOverLockscreen_activityLaunchAnimator() {
+        val pendingIntent = mock(PendingIntent::class.java)
+        val parent = FrameLayout(context)
+        val view =
+            object : View(context), LaunchableView {
+                override fun setShouldBlockVisibilityChanges(block: Boolean) {}
+            }
+        parent.addView(view)
+        val controller = ActivityLaunchAnimator.Controller.fromView(view)
+        whenever(pendingIntent.isActivity).thenReturn(true)
+        whenever(keyguardStateController.isShowing).thenReturn(true)
+        whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+        whenever(activityIntentHelper.wouldPendingShowOverLockscreen(eq(pendingIntent), anyInt()))
+            .thenReturn(true)
+
+        underTest.startPendingIntentMaybeDismissingKeyguard(
+            intent = pendingIntent,
+            animationController = controller,
+            intentSentUiThreadCallback = null,
+        )
+        mainExecutor.runAllReady()
+
+        verify(activityLaunchAnimator)
+            .startPendingIntentWithAnimation(
+                nullable(),
+                eq(true),
+                nullable(),
+                eq(true),
+                any(),
+            )
+    }
+
+    @Test
     fun startPendingIntentDismissingKeyguard_associatedView_getAnimatorController() {
         val pendingIntent = mock(PendingIntent::class.java)
         val associatedView = mock(ExpandableNotificationRow::class.java)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index a59cd87..41eaf85 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -158,7 +158,6 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
-import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository;
 import com.android.systemui.statusbar.notification.init.NotificationsController;
 import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptLogger;
@@ -502,7 +501,6 @@
                 (Lazy<NotificationPresenter>) () -> mNotificationPresenter,
                 (Lazy<NotificationActivityStarter>) () -> mNotificationActivityStarter,
                 mNotifLaunchAnimControllerProvider,
-                new NotificationExpansionRepository(),
                 mDozeParameters,
                 mScrimController,
                 mBiometricUnlockControllerLazy,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
index 593c587..472709c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
@@ -42,6 +42,8 @@
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.doze.DozeHost;
 import com.android.systemui.doze.DozeLog;
+import com.android.systemui.flags.FakeFeatureFlagsClassic;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.keyguard.domain.interactor.DozeInteractor;
 import com.android.systemui.shade.NotificationShadeWindowViewController;
@@ -96,18 +98,21 @@
     @Mock private BiometricUnlockController mBiometricUnlockController;
     @Mock private AuthController mAuthController;
     @Mock private DozeHost.Callback mCallback;
-
     @Mock private DozeInteractor mDozeInteractor;
+
+    private final FakeFeatureFlagsClassic mFeatureFlags = new FakeFeatureFlagsClassic();
+
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
+        mFeatureFlags.setDefault(Flags.NOTIFICATION_ICON_CONTAINER_REFACTOR);
         mDozeServiceHost = new DozeServiceHost(mDozeLog, mPowerManager, mWakefullnessLifecycle,
-                mStatusBarStateController, mDeviceProvisionedController, mHeadsUpManager,
-                mBatteryController, mScrimController, () -> mBiometricUnlockController,
-                () -> mAssistManager, mDozeScrimController,
-                mKeyguardUpdateMonitor, mPulseExpansionHandler,
-                mNotificationShadeWindowController, mNotificationWakeUpCoordinator,
-                mAuthController, mNotificationIconAreaController, mDozeInteractor);
+                mStatusBarStateController, mDeviceProvisionedController, mFeatureFlags,
+                mHeadsUpManager, mBatteryController, mScrimController,
+                () -> mBiometricUnlockController, () -> mAssistManager, mDozeScrimController,
+                mKeyguardUpdateMonitor, mPulseExpansionHandler, mNotificationShadeWindowController,
+                mNotificationWakeUpCoordinator, mAuthController, mNotificationIconAreaController,
+                mDozeInteractor);
 
         mDozeServiceHost.initialize(
                 mCentralSurfaces,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
index d84bb72..529e2c9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
@@ -34,6 +34,8 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.flags.FakeFeatureFlagsClassic;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shade.ShadeHeadsUpTracker;
@@ -42,6 +44,7 @@
 import com.android.systemui.statusbar.HeadsUpStatusBarView;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationIconInteractor;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
 import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager;
@@ -82,10 +85,12 @@
     private KeyguardStateController mKeyguardStateController;
     private CommandQueue mCommandQueue;
     private NotificationRoundnessManager mNotificationRoundnessManager;
+    private final FakeFeatureFlagsClassic mFeatureFlags = new FakeFeatureFlagsClassic();
 
     @Before
     public void setUp() throws Exception {
         allowTestableLooperAsMainThread();
+        mFeatureFlags.setDefault(Flags.NOTIFICATION_ICON_CONTAINER_REFACTOR);
         mTestHelper = new NotificationTestHelper(
                 mContext,
                 mDependency,
@@ -119,6 +124,8 @@
                 mNotificationRoundnessManager,
                 mHeadsUpStatusBarView,
                 new Clock(mContext, null),
+                mFeatureFlags,
+                mock(HeadsUpNotificationIconInteractor.class),
                 Optional.of(mOperatorNameView));
         mHeadsUpAppearanceController.setAppearFraction(0.0f, 0.0f);
     }
@@ -203,6 +210,7 @@
                 mNotificationRoundnessManager,
                 mHeadsUpStatusBarView,
                 new Clock(mContext, null),
+                mFeatureFlags, mock(HeadsUpNotificationIconInteractor.class),
                 Optional.empty());
 
         assertEquals(expandedHeight, newController.mExpandedHeight, 0.0f);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
index 48b95d4..cda2a74 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
@@ -34,7 +34,7 @@
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.res.R;
-import com.android.systemui.shade.domain.interactor.ShadeInteractor;
+import com.android.systemui.shade.ShadeExpansionStateManager;
 import com.android.systemui.statusbar.AlertingNotificationManager;
 import com.android.systemui.statusbar.AlertingNotificationManagerTest;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
@@ -45,7 +45,6 @@
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.HeadsUpManagerLogger;
-import com.android.systemui.util.kotlin.JavaAdapter;
 
 import org.junit.After;
 import org.junit.Before;
@@ -57,8 +56,6 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
-import kotlinx.coroutines.flow.StateFlowKt;
-
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
@@ -73,9 +70,8 @@
     @Mock private KeyguardBypassController mBypassController;
     @Mock private ConfigurationControllerImpl mConfigurationController;
     @Mock private AccessibilityManagerWrapper mAccessibilityManagerWrapper;
+    @Mock private ShadeExpansionStateManager mShadeExpansionStateManager;
     @Mock private UiEventLogger mUiEventLogger;
-    @Mock private JavaAdapter mJavaAdapter;
-    @Mock private ShadeInteractor mShadeInteractor;
 
     private static final class TestableHeadsUpManagerPhone extends HeadsUpManagerPhone {
         TestableHeadsUpManagerPhone(
@@ -89,8 +85,7 @@
                 Handler handler,
                 AccessibilityManagerWrapper accessibilityManagerWrapper,
                 UiEventLogger uiEventLogger,
-                JavaAdapter javaAdapter,
-                ShadeInteractor shadeInteractor
+                ShadeExpansionStateManager shadeExpansionStateManager
         ) {
             super(
                     context,
@@ -103,8 +98,7 @@
                     handler,
                     accessibilityManagerWrapper,
                     uiEventLogger,
-                    javaAdapter,
-                    shadeInteractor
+                    shadeExpansionStateManager
             );
             mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
             mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
@@ -123,8 +117,7 @@
                 mTestHandler,
                 mAccessibilityManagerWrapper,
                 mUiEventLogger,
-                mJavaAdapter,
-                mShadeInteractor
+                mShadeExpansionStateManager
         );
     }
 
@@ -136,7 +129,6 @@
     @Before
     @Override
     public void setUp() {
-        when(mShadeInteractor.isAnyExpanded()).thenReturn(StateFlowKt.MutableStateFlow(false));
         final AccessibilityManagerWrapper accessibilityMgr =
                 mDependency.injectMockDependency(AccessibilityManagerWrapper.class);
         when(accessibilityMgr.getRecommendedTimeoutMillis(anyInt(), anyInt()))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index beac995..1e31977 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -86,7 +86,8 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.provider.LaunchFullScreenIntentProvider;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
-import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository;
+import com.android.systemui.statusbar.notification.data.repository.NotificationLaunchAnimationRepository;
+import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor;
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
@@ -222,7 +223,8 @@
         HeadsUpManager headsUpManager = mock(HeadsUpManager.class);
         NotificationLaunchAnimatorControllerProvider notificationAnimationProvider =
                 new NotificationLaunchAnimatorControllerProvider(
-                        new NotificationExpansionRepository(),
+                        new NotificationLaunchAnimationInteractor(
+                                new NotificationLaunchAnimationRepository()),
                         mock(NotificationListContainer.class),
                         headsUpManager,
                         mJankMonitor);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index bcb34d6..9a77f0c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -48,23 +48,29 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.res.R;
 import com.android.systemui.SysuiBaseFragmentTest;
 import com.android.systemui.animation.AnimatorTestRule;
+import com.android.systemui.common.ui.ConfigurationState;
+import com.android.systemui.demomode.DemoModeController;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.FeatureFlagsClassic;
 import com.android.systemui.log.LogBuffer;
 import com.android.systemui.log.LogcatEchoTracker;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.res.R;
 import com.android.systemui.shade.ShadeExpansionStateManager;
 import com.android.systemui.shade.ShadeViewController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.OperatorNameViewController;
 import com.android.systemui.statusbar.disableflags.DisableFlagsLogger;
 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
+import com.android.systemui.statusbar.notification.icon.ui.viewbinder.StatusBarNotificationIconViewStore;
+import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerStatusBarViewModel;
+import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
 import com.android.systemui.statusbar.phone.NotificationIconAreaController;
+import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
 import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarLocationPublisher;
@@ -72,6 +78,7 @@
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
 import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.FakeCollapsedStatusBarViewBinder;
 import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.FakeCollapsedStatusBarViewModel;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.window.StatusBarWindowStateController;
 import com.android.systemui.statusbar.window.StatusBarWindowStateListener;
@@ -682,7 +689,7 @@
                 mLocationPublisher,
                 mMockNotificationAreaController,
                 mShadeExpansionStateManager,
-                mock(FeatureFlags.class),
+                mock(FeatureFlagsClassic.class),
                 mStatusBarIconController,
                 mIconManagerFactory,
                 mCollapsedStatusBarViewModel,
@@ -702,7 +709,14 @@
                 mExecutor,
                 mDumpManager,
                 mStatusBarWindowStateController,
-                mKeyguardUpdateMonitor);
+                mKeyguardUpdateMonitor,
+                mock(NotificationIconContainerStatusBarViewModel.class),
+                mock(ConfigurationState.class),
+                mock(ConfigurationController.class),
+                mock(DozeParameters.class),
+                mock(ScreenOffAnimationController.class),
+                mock(StatusBarNotificationIconViewStore.class),
+                mock(DemoModeController.class));
     }
 
     private void setUpDaggerComponent() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/ui/AnimatedValueTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/ui/AnimatedValueTest.kt
index 6e3a732..94100fe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/ui/AnimatedValueTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/ui/AnimatedValueTest.kt
@@ -24,8 +24,6 @@
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableSharedFlow
-import kotlinx.coroutines.flow.emptyFlow
-import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
@@ -38,64 +36,193 @@
     @Test
     fun animatableEvent_updatesValue() = runTest {
         val events = MutableSharedFlow<AnimatableEvent<Int>>()
-        val values = events.toAnimatedValueFlow(completionEvents = emptyFlow())
+        val values = events.toAnimatedValueFlow()
         val value by collectLastValue(values)
         runCurrent()
 
         events.emit(AnimatableEvent(value = 1, startAnimating = false))
 
-        assertThat(value).isEqualTo(AnimatedValue(value = 1, isAnimating = false))
+        assertThat(value?.value).isEqualTo(1)
+        assertThat(value?.isAnimating).isFalse()
     }
 
     @Test
     fun animatableEvent_startAnimation() = runTest {
         val events = MutableSharedFlow<AnimatableEvent<Int>>()
-        val values = events.toAnimatedValueFlow(completionEvents = emptyFlow())
+        val values = events.toAnimatedValueFlow()
         val value by collectLastValue(values)
         runCurrent()
 
         events.emit(AnimatableEvent(value = 1, startAnimating = true))
 
-        assertThat(value).isEqualTo(AnimatedValue(value = 1, isAnimating = true))
+        assertThat(value?.value).isEqualTo(1)
+        assertThat(value?.isAnimating).isTrue()
     }
 
     @Test
     fun animatableEvent_startAnimation_alreadyAnimating() = runTest {
         val events = MutableSharedFlow<AnimatableEvent<Int>>()
-        val values = events.toAnimatedValueFlow(completionEvents = emptyFlow())
+        val values = events.toAnimatedValueFlow()
         val value by collectLastValue(values)
         runCurrent()
 
         events.emit(AnimatableEvent(value = 1, startAnimating = true))
         events.emit(AnimatableEvent(value = 2, startAnimating = true))
 
-        assertThat(value).isEqualTo(AnimatedValue(value = 2, isAnimating = true))
+        assertThat(value?.value).isEqualTo(2)
+        assertThat(value?.isAnimating).isTrue()
     }
 
     @Test
     fun animatedValue_stopAnimating() = runTest {
         val events = MutableSharedFlow<AnimatableEvent<Int>>()
-        val stopEvent = MutableSharedFlow<Unit>()
-        val values = events.toAnimatedValueFlow(completionEvents = stopEvent)
+        val values = events.toAnimatedValueFlow()
         val value by collectLastValue(values)
         runCurrent()
 
         events.emit(AnimatableEvent(value = 1, startAnimating = true))
-        stopEvent.emit(Unit)
+        assertThat(value?.isAnimating).isTrue()
+        value?.stopAnimating()
 
-        assertThat(value).isEqualTo(AnimatedValue(value = 1, isAnimating = false))
+        assertThat(value?.value).isEqualTo(1)
+        assertThat(value?.isAnimating).isFalse()
     }
 
     @Test
-    fun animatedValue_stopAnimating_notAnimating() = runTest {
+    fun animatedValue_stopAnimatingPrevValue_doesNothing() = runTest {
         val events = MutableSharedFlow<AnimatableEvent<Int>>()
-        val stopEvent = MutableSharedFlow<Unit>()
-        val values = events.toAnimatedValueFlow(completionEvents = stopEvent)
-        values.launchIn(backgroundScope)
+        val values = events.toAnimatedValueFlow()
+        val value by collectLastValue(values)
         runCurrent()
 
-        events.emit(AnimatableEvent(value = 1, startAnimating = false))
+        events.emit(AnimatableEvent(value = 1, startAnimating = true))
+        val prevValue = value
+        assertThat(prevValue?.isAnimating).isTrue()
 
-        assertThat(stopEvent.subscriptionCount.value).isEqualTo(0)
+        events.emit(AnimatableEvent(value = 2, startAnimating = true))
+        assertThat(value?.isAnimating).isTrue()
+        prevValue?.stopAnimating()
+
+        assertThat(value?.value).isEqualTo(2)
+        assertThat(value?.isAnimating).isTrue()
+    }
+
+    @Test
+    fun zipValues_applyTransform() {
+        val animating = AnimatedValue.Animating(1) {}
+        val notAnimating = AnimatedValue.NotAnimating(2)
+        val sum = zip(animating, notAnimating) { a, b -> a + b }
+        assertThat(sum.value).isEqualTo(3)
+    }
+
+    @Test
+    fun zipValues_firstIsAnimating_resultIsAnimating() {
+        var stopped = false
+        val animating = AnimatedValue.Animating(1) { stopped = true }
+        val notAnimating = AnimatedValue.NotAnimating(2)
+        val sum = zip(animating, notAnimating) { a, b -> a + b }
+        assertThat(sum.isAnimating).isTrue()
+
+        sum.stopAnimating()
+        assertThat(stopped).isTrue()
+    }
+
+    @Test
+    fun zipValues_secondIsAnimating_resultIsAnimating() {
+        var stopped = false
+        val animating = AnimatedValue.Animating(1) { stopped = true }
+        val notAnimating = AnimatedValue.NotAnimating(2)
+        val sum = zip(notAnimating, animating) { a, b -> a + b }
+        assertThat(sum.isAnimating).isTrue()
+
+        sum.stopAnimating()
+        assertThat(stopped).isTrue()
+    }
+
+    @Test
+    fun zipValues_bothAnimating_resultIsAnimating() {
+        var firstStopped = false
+        var secondStopped = false
+        val first = AnimatedValue.Animating(1) { firstStopped = true }
+        val second = AnimatedValue.Animating(2) { secondStopped = true }
+        val sum = zip(first, second) { a, b -> a + b }
+        assertThat(sum.isAnimating).isTrue()
+
+        sum.stopAnimating()
+        assertThat(firstStopped).isTrue()
+        assertThat(secondStopped).isTrue()
+    }
+
+    @Test
+    fun zipValues_neitherAnimating_resultIsNotAnimating() {
+        val first = AnimatedValue.NotAnimating(1)
+        val second = AnimatedValue.NotAnimating(2)
+        val sum = zip(first, second) { a, b -> a + b }
+        assertThat(sum.isAnimating).isFalse()
+    }
+
+    @Test
+    fun mapAnimatedValue_isAnimating() {
+        var stopped = false
+        val animating = AnimatedValue.Animating(3) { stopped = true }
+        val squared = animating.map { it * it }
+        assertThat(squared.value).isEqualTo(9)
+        assertThat(squared.isAnimating).isTrue()
+        squared.stopAnimating()
+        assertThat(stopped).isTrue()
+    }
+
+    @Test
+    fun mapAnimatedValue_notAnimating() {
+        val notAnimating = AnimatedValue.NotAnimating(3)
+        val squared = notAnimating.map { it * it }
+        assertThat(squared.value).isEqualTo(9)
+        assertThat(squared.isAnimating).isFalse()
+    }
+
+    @Test
+    fun flattenAnimatingValue_neitherAnimating() {
+        val nested = AnimatedValue.NotAnimating(AnimatedValue.NotAnimating(10))
+        val flattened = nested.flatten()
+        assertThat(flattened.value).isEqualTo(10)
+        assertThat(flattened.isAnimating).isFalse()
+    }
+
+    @Test
+    fun flattenAnimatingValue_outerAnimating() {
+        var stopped = false
+        val inner = AnimatedValue.NotAnimating(10)
+        val nested = AnimatedValue.Animating(inner) { stopped = true }
+        val flattened = nested.flatten()
+        assertThat(flattened.value).isEqualTo(10)
+        assertThat(flattened.isAnimating).isTrue()
+        flattened.stopAnimating()
+        assertThat(stopped).isTrue()
+    }
+
+    @Test
+    fun flattenAnimatingValue_innerAnimating() {
+        var stopped = false
+        val inner = AnimatedValue.Animating(10) { stopped = true }
+        val nested = AnimatedValue.NotAnimating(inner)
+        val flattened = nested.flatten()
+        assertThat(flattened.value).isEqualTo(10)
+        assertThat(flattened.isAnimating).isTrue()
+        flattened.stopAnimating()
+        assertThat(stopped).isTrue()
+    }
+
+    @Test
+    fun flattenAnimatingValue_bothAnimating() {
+        var innerStopped = false
+        var outerStopped = false
+        val inner = AnimatedValue.Animating(10) { innerStopped = true }
+        val nested = AnimatedValue.Animating(inner) { outerStopped = true }
+        val flattened = nested.flatten()
+        assertThat(flattened.value).isEqualTo(10)
+        assertThat(flattened.isAnimating).isTrue()
+        flattened.stopAnimating()
+        assertThat(innerStopped).isTrue()
+        assertThat(outerStopped).isTrue()
     }
 }
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index 65975e4..76ebdf4 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -103,9 +103,8 @@
 import com.android.internal.os.IResultReceiver;
 import com.android.internal.util.DumpUtils;
 import com.android.server.LocalServices;
-import com.android.server.contentprotection.ContentProtectionBlocklistManager;
+import com.android.server.contentprotection.ContentProtectionAllowlistManager;
 import com.android.server.contentprotection.ContentProtectionConsentManager;
-import com.android.server.contentprotection.ContentProtectionPackageManager;
 import com.android.server.contentprotection.RemoteContentProtectionService;
 import com.android.server.infra.AbstractMasterSystemService;
 import com.android.server.infra.FrameworkResourcesServiceNameResolver;
@@ -207,9 +206,6 @@
     boolean mDevCfgEnableContentProtectionReceiver;
 
     @GuardedBy("mLock")
-    int mDevCfgContentProtectionAppsBlocklistSize;
-
-    @GuardedBy("mLock")
     int mDevCfgContentProtectionBufferSize;
 
     @GuardedBy("mLock")
@@ -237,7 +233,7 @@
 
     @Nullable private final ComponentName mContentProtectionServiceComponentName;
 
-    @Nullable private final ContentProtectionBlocklistManager mContentProtectionBlocklistManager;
+    @Nullable private final ContentProtectionAllowlistManager mContentProtectionAllowlistManager;
 
     @Nullable private final ContentProtectionConsentManager mContentProtectionConsentManager;
 
@@ -287,17 +283,15 @@
         if (getEnableContentProtectionReceiverLocked()) {
             mContentProtectionServiceComponentName = getContentProtectionServiceComponentName();
             if (mContentProtectionServiceComponentName != null) {
-                mContentProtectionBlocklistManager = createContentProtectionBlocklistManager();
-                mContentProtectionBlocklistManager.updateBlocklist(
-                        mDevCfgContentProtectionAppsBlocklistSize);
+                mContentProtectionAllowlistManager = createContentProtectionAllowlistManager();
                 mContentProtectionConsentManager = createContentProtectionConsentManager();
             } else {
-                mContentProtectionBlocklistManager = null;
+                mContentProtectionAllowlistManager = null;
                 mContentProtectionConsentManager = null;
             }
         } else {
             mContentProtectionServiceComponentName = null;
-            mContentProtectionBlocklistManager = null;
+            mContentProtectionAllowlistManager = null;
             mContentProtectionConsentManager = null;
         }
     }
@@ -445,8 +439,6 @@
                 case ContentCaptureManager
                         .DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER:
                 case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_BUFFER_SIZE:
-                case ContentCaptureManager
-                        .DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE:
                 case DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_REQUIRED_GROUPS_CONFIG:
                 case DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_OPTIONAL_GROUPS_CONFIG:
                 case DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_OPTIONAL_GROUPS_THRESHOLD:
@@ -502,14 +494,6 @@
                             ContentCaptureManager
                                     .DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER,
                             ContentCaptureManager.DEFAULT_ENABLE_CONTENT_PROTECTION_RECEIVER);
-            mDevCfgContentProtectionAppsBlocklistSize =
-                    DeviceConfig.getInt(
-                            DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
-                            ContentCaptureManager
-                                    .DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE,
-                            ContentCaptureManager.DEFAULT_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE);
-            // mContentProtectionBlocklistManager.updateBlocklist not called on purpose here to keep
-            // it immutable at this point
             mDevCfgContentProtectionBufferSize =
                     DeviceConfig.getInt(
                             DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
@@ -542,7 +526,7 @@
                                 + mDevCfgMaxBufferSize
                                 + ", idleFlush="
                                 + mDevCfgIdleFlushingFrequencyMs
-                                + ", textFluxh="
+                                + ", textFlush="
                                 + mDevCfgTextChangeFlushingFrequencyMs
                                 + ", logHistory="
                                 + mDevCfgLogHistorySize
@@ -552,8 +536,6 @@
                                 + mDevCfgDisableFlushForViewTreeAppearing
                                 + ", enableContentProtectionReceiver="
                                 + mDevCfgEnableContentProtectionReceiver
-                                + ", contentProtectionAppsBlocklistSize="
-                                + mDevCfgContentProtectionAppsBlocklistSize
                                 + ", contentProtectionBufferSize="
                                 + mDevCfgContentProtectionBufferSize
                                 + ", contentProtectionRequiredGroupsConfig="
@@ -844,9 +826,6 @@
         pw.print("enableContentProtectionReceiver: ");
         pw.println(mDevCfgEnableContentProtectionReceiver);
         pw.print(prefix2);
-        pw.print("contentProtectionAppsBlocklistSize: ");
-        pw.println(mDevCfgContentProtectionAppsBlocklistSize);
-        pw.print(prefix2);
         pw.print("contentProtectionBufferSize: ");
         pw.println(mDevCfgContentProtectionBufferSize);
         pw.print(prefix2);
@@ -877,9 +856,8 @@
     /** @hide */
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
     @NonNull
-    protected ContentProtectionBlocklistManager createContentProtectionBlocklistManager() {
-        return new ContentProtectionBlocklistManager(
-                new ContentProtectionPackageManager(getContext()));
+    protected ContentProtectionAllowlistManager createContentProtectionAllowlistManager() {
+        return new ContentProtectionAllowlistManager();
     }
 
     /** @hide */
@@ -1429,7 +1407,7 @@
         private boolean isContentProtectionReceiverEnabled(
                 @UserIdInt int userId, @NonNull String packageName) {
             if (mContentProtectionServiceComponentName == null
-                    || mContentProtectionBlocklistManager == null
+                    || mContentProtectionAllowlistManager == null
                     || mContentProtectionConsentManager == null) {
                 return false;
             }
@@ -1443,7 +1421,7 @@
                 }
             }
             return mContentProtectionConsentManager.isConsentGranted(userId)
-                    && mContentProtectionBlocklistManager.isAllowed(packageName);
+                    && mContentProtectionAllowlistManager.isAllowed(packageName);
         }
     }
 
diff --git a/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionAllowlistManager.java b/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionAllowlistManager.java
new file mode 100644
index 0000000..59af526
--- /dev/null
+++ b/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionAllowlistManager.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 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.server.contentprotection;
+
+import android.annotation.NonNull;
+import android.util.Slog;
+
+/**
+ * Manages whether the content protection is enabled for an app using a allowlist.
+ *
+ * @hide
+ */
+public class ContentProtectionAllowlistManager {
+
+    private static final String TAG = "ContentProtectionAllowlistManager";
+
+    public ContentProtectionAllowlistManager() {}
+
+    /** Returns true if the package is allowed. */
+    public boolean isAllowed(@NonNull String packageName) {
+        Slog.v(TAG, packageName);
+        return false;
+    }
+}
diff --git a/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionBlocklistManager.java b/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionBlocklistManager.java
deleted file mode 100644
index a0fd28b..0000000
--- a/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionBlocklistManager.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2023 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.server.contentprotection;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.pm.PackageInfo;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * Manages whether the content protection is enabled for an app using a blocklist.
- *
- * @hide
- */
-public class ContentProtectionBlocklistManager {
-
-    private static final String TAG = "ContentProtectionBlocklistManager";
-
-    private static final String PACKAGE_NAME_BLOCKLIST_FILENAME =
-            "/product/etc/res/raw/content_protection/package_name_blocklist.txt";
-
-    @NonNull private final ContentProtectionPackageManager mContentProtectionPackageManager;
-
-    @Nullable private Set<String> mPackageNameBlocklist;
-
-    public ContentProtectionBlocklistManager(
-            @NonNull ContentProtectionPackageManager contentProtectionPackageManager) {
-        mContentProtectionPackageManager = contentProtectionPackageManager;
-    }
-
-    public boolean isAllowed(@NonNull String packageName) {
-        if (mPackageNameBlocklist == null) {
-            // List not loaded or failed to load, don't run on anything
-            return false;
-        }
-        if (mPackageNameBlocklist.contains(packageName)) {
-            return false;
-        }
-        PackageInfo packageInfo = mContentProtectionPackageManager.getPackageInfo(packageName);
-        if (packageInfo == null) {
-            return false;
-        }
-        if (!mContentProtectionPackageManager.hasRequestedInternetPermissions(packageInfo)) {
-            return false;
-        }
-        if (mContentProtectionPackageManager.isSystemApp(packageInfo)) {
-            return false;
-        }
-        if (mContentProtectionPackageManager.isUpdatedSystemApp(packageInfo)) {
-            return false;
-        }
-        return true;
-    }
-
-    public void updateBlocklist(int blocklistSize) {
-        Slog.i(TAG, "Blocklist size updating to: " + blocklistSize);
-        mPackageNameBlocklist = readPackageNameBlocklist(blocklistSize);
-    }
-
-    @Nullable
-    private Set<String> readPackageNameBlocklist(int blocklistSize) {
-        if (blocklistSize <= 0) {
-            // Explicitly requested an empty blocklist
-            return Collections.emptySet();
-        }
-        List<String> lines = readLinesFromRawFile(PACKAGE_NAME_BLOCKLIST_FILENAME);
-        if (lines == null) {
-            return null;
-        }
-        return lines.stream().limit(blocklistSize).collect(Collectors.toSet());
-    }
-
-    @VisibleForTesting
-    @Nullable
-    protected List<String> readLinesFromRawFile(@NonNull String filename) {
-        try (FileReader fileReader = new FileReader(filename);
-                BufferedReader bufferedReader = new BufferedReader(fileReader)) {
-            return bufferedReader
-                    .lines()
-                    .map(line -> line.trim())
-                    .filter(line -> !line.isBlank())
-                    .collect(Collectors.toList());
-        } catch (Exception ex) {
-            Slog.e(TAG, "Failed to read: " + filename, ex);
-            return null;
-        }
-    }
-}
diff --git a/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionPackageManager.java b/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionPackageManager.java
deleted file mode 100644
index 4ebac07..0000000
--- a/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionPackageManager.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2023 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.server.contentprotection;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.PackageManager.PackageInfoFlags;
-import android.util.Slog;
-
-import java.util.Arrays;
-
-/**
- * Basic package manager for content protection using content capture.
- *
- * @hide
- */
-public class ContentProtectionPackageManager {
-
-    private static final String TAG = "ContentProtectionPackageManager";
-
-    private static final PackageInfoFlags PACKAGE_INFO_FLAGS =
-            PackageInfoFlags.of(PackageManager.GET_PERMISSIONS);
-
-    @NonNull private final PackageManager mPackageManager;
-
-    public ContentProtectionPackageManager(@NonNull Context context) {
-        mPackageManager = context.getPackageManager();
-    }
-
-    @Nullable
-    public PackageInfo getPackageInfo(@NonNull String packageName) {
-        try {
-            return mPackageManager.getPackageInfo(packageName, PACKAGE_INFO_FLAGS);
-        } catch (NameNotFoundException ex) {
-            Slog.w(TAG, "Package info not found for: " + packageName, ex);
-            return null;
-        }
-    }
-
-    public boolean isSystemApp(@NonNull PackageInfo packageInfo) {
-        return packageInfo.applicationInfo != null && isSystemApp(packageInfo.applicationInfo);
-    }
-
-    private boolean isSystemApp(@NonNull ApplicationInfo applicationInfo) {
-        return (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
-    }
-
-    public boolean isUpdatedSystemApp(@NonNull PackageInfo packageInfo) {
-        return packageInfo.applicationInfo != null
-                && isUpdatedSystemApp(packageInfo.applicationInfo);
-    }
-
-    private boolean isUpdatedSystemApp(@NonNull ApplicationInfo applicationInfo) {
-        return (applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
-    }
-
-    public boolean hasRequestedInternetPermissions(@NonNull PackageInfo packageInfo) {
-        return packageInfo.requestedPermissions != null
-                && Arrays.asList(packageInfo.requestedPermissions)
-                        .contains(Manifest.permission.INTERNET);
-    }
-}
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 30017be..510c06e 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -24,7 +24,6 @@
 import static android.content.Intent.ACTION_MAIN;
 import static android.content.Intent.CATEGORY_DEFAULT;
 import static android.content.Intent.CATEGORY_HOME;
-import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
 import static android.content.pm.PackageManager.CERT_INPUT_RAW_X509;
 import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
@@ -1525,9 +1524,6 @@
             ai.secondaryCpuAbi = ps.getSecondaryCpuAbiLegacy();
             ai.volumeUuid = ps.getVolumeUuid();
             ai.storageUuid = StorageManager.convert(ai.volumeUuid);
-            if (ps.isDefaultToDeviceProtectedStorage()) {
-                ai.privateFlags |= PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
-            }
             ai.setVersionCode(ps.getVersionCode());
             ai.flags = ps.getFlags();
             ai.privateFlags = ps.getPrivateFlags();
@@ -4596,6 +4592,7 @@
         flags = updateFlagsForApplication(flags, userId);
         final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
         final boolean listApex = (flags & MATCH_APEX) != 0;
+        final boolean listArchivedOnly = !listUninstalled && (flags & MATCH_ARCHIVED_PACKAGES) != 0;
 
         enforceCrossUserPermission(
                 callingUid,
@@ -4607,7 +4604,7 @@
         ArrayList<ApplicationInfo> list;
         final ArrayMap<String, ? extends PackageStateInternal> packageStates =
                 getPackageStates();
-        if (listUninstalled) {
+        if (listUninstalled || listArchivedOnly) {
             list = new ArrayList<>(packageStates.size());
             for (PackageStateInternal ps : packageStates.values()) {
                 ApplicationInfo ai;
@@ -4619,6 +4616,11 @@
                     if (!listApex && ps.getPkg().isApex()) {
                         continue;
                     }
+                    PackageUserStateInternal userState = ps.getUserStateOrDefault(userId);
+                    if (listArchivedOnly && !userState.isInstalled()
+                            && userState.getArchiveState() == null) {
+                        continue;
+                    }
                     if (filterSharedLibPackage(ps, callingUid, userId, flags)) {
                         continue;
                     }
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index a5c5ae2..7cac870 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -1630,7 +1630,8 @@
                 synchronized (mPm.mLock) {
                     if (DEBUG_INSTALL) {
                         Slog.d(TAG,
-                                "replacePackageLI: new=" + parsedPackage + ", old=" + oldPackage);
+                                "replacePackageLI: new=" + parsedPackage
+                                        + ", old=" + oldPackageState.getName());
                     }
 
                     ps = mPm.mSettings.getPackageLPr(pkgName11);
@@ -1789,7 +1790,7 @@
 
                     if (DEBUG_INSTALL) {
                         Slog.d(TAG, "replaceSystemPackageLI: new=" + parsedPackage
-                                + ", old=" + oldPackage);
+                                + ", old=" + oldPackageState.getName());
                     }
                     request.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
                     request.setApexModuleName(oldPackageState.getApexModuleName());
@@ -1799,7 +1800,7 @@
                     if (DEBUG_INSTALL) {
                         Slog.d(TAG,
                                 "replaceNonSystemPackageLI: new=" + parsedPackage + ", old="
-                                        + oldPackage);
+                                        + oldPackageState.getName());
                     }
                 }
             } else { // new package install
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 42f4cfb..ad26d1f 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -16,6 +16,7 @@
 
 package com.android.server.pm;
 
+import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
@@ -89,17 +90,14 @@
     private static class Booleans {
         @IntDef({
                 INSTALL_PERMISSION_FIXED,
-                DEFAULT_TO_DEVICE_PROTECTED_STORAGE,
                 UPDATE_AVAILABLE,
                 FORCE_QUERYABLE_OVERRIDE
         })
         public @interface Flags {
         }
         private static final int INSTALL_PERMISSION_FIXED = 1;
-        private static final int DEFAULT_TO_DEVICE_PROTECTED_STORAGE = 1 << 1;
-        private static final int UPDATE_AVAILABLE = 1 << 2;
-        private static final int FORCE_QUERYABLE_OVERRIDE = 1 << 3;
-        private static final int PERSISTENT = 1 << 4;
+        private static final int UPDATE_AVAILABLE = 1 << 1;
+        private static final int FORCE_QUERYABLE_OVERRIDE = 1 << 2;
     }
     private int mBooleans;
 
@@ -500,13 +498,6 @@
         return this;
     }
 
-    public PackageSetting setDefaultToDeviceProtectedStorage(
-            boolean defaultToDeviceProtectedStorage) {
-        setBoolean(Booleans.DEFAULT_TO_DEVICE_PROTECTED_STORAGE, defaultToDeviceProtectedStorage);
-        onChanged();
-        return this;
-    }
-
     @Override
     public boolean isExternalStorage() {
         return (getFlags() & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
@@ -524,12 +515,6 @@
         return this;
     }
 
-    public PackageSetting setIsPersistent(boolean isPersistent) {
-        setBoolean(Booleans.PERSISTENT, isPersistent);
-        onChanged();
-        return this;
-    }
-
     public PackageSetting setTargetSdkVersion(int targetSdkVersion) {
         mTargetSdkVersion = targetSdkVersion;
         onChanged();
@@ -1585,12 +1570,12 @@
      */
     @Override
     public boolean isDefaultToDeviceProtectedStorage() {
-        return getBoolean(Booleans.DEFAULT_TO_DEVICE_PROTECTED_STORAGE);
+        return (getPrivateFlags() & PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) != 0;
     }
 
     @Override
     public boolean isPersistent() {
-        return getBoolean(Booleans.PERSISTENT);
+        return (getFlags() & ApplicationInfo.FLAG_PERSISTENT) != 0;
     }
 
 
@@ -1746,10 +1731,10 @@
     }
 
     @DataClass.Generated(
-            time = 1696979728639L,
+            time = 1698097434269L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/services/core/java/com/android/server/pm/PackageSetting.java",
-            inputSignatures = "private  int mBooleans\nprivate  int mSharedUserAppId\nprivate @android.annotation.Nullable java.util.Map<java.lang.String,java.util.Set<java.lang.String>> mimeGroups\nprivate @java.lang.Deprecated @android.annotation.Nullable java.util.Set<java.lang.String> mOldCodePaths\nprivate @android.annotation.Nullable java.lang.String[] usesSdkLibraries\nprivate @android.annotation.Nullable long[] usesSdkLibrariesVersionsMajor\nprivate @android.annotation.Nullable java.lang.String[] usesStaticLibraries\nprivate @android.annotation.Nullable long[] usesStaticLibrariesVersions\nprivate @android.annotation.Nullable @java.lang.Deprecated java.lang.String legacyNativeLibraryPath\nprivate @android.annotation.NonNull java.lang.String mName\nprivate @android.annotation.Nullable java.lang.String mRealName\nprivate  int mAppId\nprivate @android.annotation.Nullable com.android.server.pm.parsing.pkg.AndroidPackageInternal pkg\nprivate @android.annotation.NonNull java.io.File mPath\nprivate @android.annotation.NonNull java.lang.String mPathString\nprivate  float mLoadingProgress\nprivate  long mLoadingCompletedTime\nprivate @android.annotation.Nullable java.lang.String mPrimaryCpuAbi\nprivate @android.annotation.Nullable java.lang.String mSecondaryCpuAbi\nprivate @android.annotation.Nullable java.lang.String mCpuAbiOverride\nprivate  long mLastModifiedTime\nprivate  long lastUpdateTime\nprivate  long versionCode\nprivate @android.annotation.NonNull com.android.server.pm.PackageSignatures signatures\nprivate @android.annotation.NonNull com.android.server.pm.PackageKeySetData keySetData\nprivate final @android.annotation.NonNull android.util.SparseArray<com.android.server.pm.pkg.PackageUserStateImpl> mUserStates\nprivate @android.annotation.NonNull com.android.server.pm.InstallSource installSource\nprivate @android.annotation.Nullable java.lang.String volumeUuid\nprivate  int categoryOverride\nprivate final @android.annotation.NonNull com.android.server.pm.pkg.PackageStateUnserialized pkgState\nprivate @android.annotation.NonNull java.util.UUID mDomainSetId\nprivate @android.annotation.Nullable java.lang.String mAppMetadataFilePath\nprivate  int mTargetSdkVersion\nprivate @android.annotation.Nullable byte[] mRestrictUpdateHash\nprivate final @android.annotation.NonNull com.android.server.utils.SnapshotCache<com.android.server.pm.PackageSetting> mSnapshot\nprivate  void setBoolean(int,boolean)\nprivate  boolean getBoolean(int)\nprivate  com.android.server.utils.SnapshotCache<com.android.server.pm.PackageSetting> makeCache()\npublic  com.android.server.pm.PackageSetting snapshot()\npublic  void dumpDebug(android.util.proto.ProtoOutputStream,long,java.util.List<android.content.pm.UserInfo>,com.android.server.pm.permission.LegacyPermissionDataProvider)\npublic  com.android.server.pm.PackageSetting setAppId(int)\npublic  com.android.server.pm.PackageSetting setCpuAbiOverride(java.lang.String)\npublic  com.android.server.pm.PackageSetting setFirstInstallTimeFromReplaced(com.android.server.pm.pkg.PackageStateInternal,int[])\npublic  com.android.server.pm.PackageSetting setFirstInstallTime(long,int)\npublic  com.android.server.pm.PackageSetting setForceQueryableOverride(boolean)\npublic  com.android.server.pm.PackageSetting setInstallerPackage(java.lang.String,int)\npublic  com.android.server.pm.PackageSetting setUpdateOwnerPackage(java.lang.String)\npublic  com.android.server.pm.PackageSetting setInstallSource(com.android.server.pm.InstallSource)\n  com.android.server.pm.PackageSetting removeInstallerPackage(java.lang.String)\npublic  com.android.server.pm.PackageSetting setIsOrphaned(boolean)\npublic  com.android.server.pm.PackageSetting setKeySetData(com.android.server.pm.PackageKeySetData)\npublic  com.android.server.pm.PackageSetting setLastModifiedTime(long)\npublic  com.android.server.pm.PackageSetting setLastUpdateTime(long)\npublic  com.android.server.pm.PackageSetting setLongVersionCode(long)\npublic  boolean setMimeGroup(java.lang.String,android.util.ArraySet<java.lang.String>)\npublic  com.android.server.pm.PackageSetting setPkg(com.android.server.pm.pkg.AndroidPackage)\npublic  com.android.server.pm.PackageSetting setPkgStateLibraryFiles(java.util.Collection<java.lang.String>)\npublic  com.android.server.pm.PackageSetting setPrimaryCpuAbi(java.lang.String)\npublic  com.android.server.pm.PackageSetting setSecondaryCpuAbi(java.lang.String)\npublic  com.android.server.pm.PackageSetting setSignatures(com.android.server.pm.PackageSignatures)\npublic  com.android.server.pm.PackageSetting setVolumeUuid(java.lang.String)\npublic  com.android.server.pm.PackageSetting setDefaultToDeviceProtectedStorage(boolean)\npublic @java.lang.Override boolean isExternalStorage()\npublic  com.android.server.pm.PackageSetting setUpdateAvailable(boolean)\npublic  void setSharedUserAppId(int)\npublic  com.android.server.pm.PackageSetting setIsPersistent(boolean)\npublic  com.android.server.pm.PackageSetting setTargetSdkVersion(int)\npublic  com.android.server.pm.PackageSetting setRestrictUpdateHash(byte[])\npublic @java.lang.Override int getSharedUserAppId()\npublic @java.lang.Override boolean hasSharedUser()\npublic @java.lang.Override java.lang.String toString()\nprotected  void copyMimeGroups(java.util.Map<java.lang.String,java.util.Set<java.lang.String>>)\npublic  void updateFrom(com.android.server.pm.PackageSetting)\n  com.android.server.pm.PackageSetting updateMimeGroups(java.util.Set<java.lang.String>)\npublic @java.lang.Deprecated @java.lang.Override com.android.server.pm.permission.LegacyPermissionState getLegacyPermissionState()\npublic  com.android.server.pm.PackageSetting setInstallPermissionsFixed(boolean)\npublic  boolean isPrivileged()\npublic  boolean isOem()\npublic  boolean isVendor()\npublic  boolean isProduct()\npublic @java.lang.Override boolean isRequiredForSystemUser()\npublic  boolean isSystemExt()\npublic  boolean isOdm()\npublic  boolean isSystem()\npublic  boolean isRequestLegacyExternalStorage()\npublic  boolean isUserDataFragile()\npublic  android.content.pm.SigningDetails getSigningDetails()\npublic  com.android.server.pm.PackageSetting setSigningDetails(android.content.pm.SigningDetails)\npublic  void copyPackageSetting(com.android.server.pm.PackageSetting,boolean)\n @com.android.internal.annotations.VisibleForTesting com.android.server.pm.pkg.PackageUserStateImpl modifyUserState(int)\npublic  com.android.server.pm.pkg.PackageUserStateImpl getOrCreateUserState(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateInternal readUserState(int)\n  void setEnabled(int,int,java.lang.String)\n  int getEnabled(int)\n  void setInstalled(boolean,int)\n  boolean getInstalled(int)\n  int getInstallReason(int)\n  void setInstallReason(int,int)\n  int getUninstallReason(int)\n  void setUninstallReason(int,int)\n @android.annotation.NonNull android.content.pm.overlay.OverlayPaths getOverlayPaths(int)\n  boolean setOverlayPathsForLibrary(java.lang.String,android.content.pm.overlay.OverlayPaths,int)\n  boolean isInstalledOrHasDataOnAnyOtherUser(int[],int)\n  int[] queryInstalledUsers(int[],boolean)\n  int[] queryUsersInstalledOrHasData(int[])\n  long getCeDataInode(int)\n  long getDeDataInode(int)\n  void setCeDataInode(long,int)\n  void setDeDataInode(long,int)\n  boolean getStopped(int)\n  void setStopped(boolean,int)\n  boolean getNotLaunched(int)\n  void setNotLaunched(boolean,int)\n  boolean getHidden(int)\n  void setHidden(boolean,int)\n  int getDistractionFlags(int)\n  void setDistractionFlags(int,int)\npublic  boolean getInstantApp(int)\n  void setInstantApp(boolean,int)\n  boolean getVirtualPreload(int)\n  void setVirtualPreload(boolean,int)\n  void setUserState(int,long,long,int,boolean,boolean,boolean,boolean,int,android.util.ArrayMap<java.lang.String,com.android.server.pm.pkg.SuspendParams>,boolean,boolean,java.lang.String,android.util.ArraySet<java.lang.String>,android.util.ArraySet<java.lang.String>,int,int,java.lang.String,java.lang.String,long,int,com.android.server.pm.pkg.ArchiveState)\n  void setUserState(int,com.android.server.pm.pkg.PackageUserStateInternal)\n  com.android.server.utils.WatchedArraySet<java.lang.String> getEnabledComponents(int)\n  com.android.server.utils.WatchedArraySet<java.lang.String> getDisabledComponents(int)\n  void setEnabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>,int)\n  void setDisabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>,int)\n  void setEnabledComponentsCopy(com.android.server.utils.WatchedArraySet<java.lang.String>,int)\n  void setDisabledComponentsCopy(com.android.server.utils.WatchedArraySet<java.lang.String>,int)\n  com.android.server.pm.pkg.PackageUserStateImpl modifyUserStateComponents(int,boolean,boolean)\n  void addDisabledComponent(java.lang.String,int)\n  void addEnabledComponent(java.lang.String,int)\n  boolean enableComponentLPw(java.lang.String,int)\n  boolean disableComponentLPw(java.lang.String,int)\n  boolean restoreComponentLPw(java.lang.String,int)\n  int getCurrentEnabledStateLPr(java.lang.String,int)\n  void removeUser(int)\npublic  int[] getNotInstalledUserIds()\n  void writePackageUserPermissionsProto(android.util.proto.ProtoOutputStream,long,java.util.List<android.content.pm.UserInfo>,com.android.server.pm.permission.LegacyPermissionDataProvider)\nprotected  void writeUsersInfoToProto(android.util.proto.ProtoOutputStream,long)\nprivate static  void writeArchiveState(android.util.proto.ProtoOutputStream,com.android.server.pm.pkg.ArchiveState)\n  com.android.server.pm.PackageSetting setPath(java.io.File)\npublic @com.android.internal.annotations.VisibleForTesting boolean overrideNonLocalizedLabelAndIcon(android.content.ComponentName,java.lang.String,java.lang.Integer,int)\npublic  void resetOverrideComponentLabelIcon(int)\npublic @android.annotation.Nullable java.lang.String getSplashScreenTheme(int)\npublic  boolean isIncremental()\npublic  boolean isLoading()\npublic  com.android.server.pm.PackageSetting setLoadingProgress(float)\npublic  com.android.server.pm.PackageSetting setLoadingCompletedTime(long)\npublic  com.android.server.pm.PackageSetting setAppMetadataFilePath(java.lang.String)\npublic @android.annotation.NonNull @java.lang.Override long getVersionCode()\npublic @android.annotation.Nullable @java.lang.Override java.util.Map<java.lang.String,java.util.Set<java.lang.String>> getMimeGroups()\npublic @android.annotation.NonNull @java.lang.Override java.lang.String getPackageName()\npublic @android.annotation.Nullable @java.lang.Override com.android.server.pm.pkg.AndroidPackage getAndroidPackage()\npublic @android.annotation.NonNull android.content.pm.SigningInfo getSigningInfo()\npublic @android.annotation.NonNull @java.lang.Override java.lang.String[] getUsesSdkLibraries()\npublic @android.annotation.NonNull @java.lang.Override long[] getUsesSdkLibrariesVersionsMajor()\npublic @android.annotation.NonNull @java.lang.Override java.lang.String[] getUsesStaticLibraries()\npublic @android.annotation.NonNull @java.lang.Override long[] getUsesStaticLibrariesVersions()\npublic @android.annotation.NonNull @java.lang.Override java.util.List<com.android.server.pm.pkg.SharedLibrary> getSharedLibraryDependencies()\npublic @android.annotation.NonNull com.android.server.pm.PackageSetting addUsesLibraryInfo(android.content.pm.SharedLibraryInfo)\npublic @android.annotation.NonNull @java.lang.Override java.util.List<java.lang.String> getUsesLibraryFiles()\npublic @android.annotation.NonNull com.android.server.pm.PackageSetting addUsesLibraryFile(java.lang.String)\npublic @java.lang.Override boolean isHiddenUntilInstalled()\npublic @android.annotation.NonNull @java.lang.Override long[] getLastPackageUsageTime()\npublic @java.lang.Override boolean isUpdatedSystemApp()\npublic @java.lang.Override boolean isApkInUpdatedApex()\npublic @android.annotation.Nullable @java.lang.Override java.lang.String getApexModuleName()\npublic  com.android.server.pm.PackageSetting setDomainSetId(java.util.UUID)\npublic  com.android.server.pm.PackageSetting setCategoryOverride(int)\npublic  com.android.server.pm.PackageSetting setLegacyNativeLibraryPath(java.lang.String)\npublic  com.android.server.pm.PackageSetting setMimeGroups(java.util.Map<java.lang.String,java.util.Set<java.lang.String>>)\npublic  com.android.server.pm.PackageSetting setOldCodePaths(java.util.Set<java.lang.String>)\npublic  com.android.server.pm.PackageSetting setUsesSdkLibraries(java.lang.String[])\npublic  com.android.server.pm.PackageSetting setUsesSdkLibrariesVersionsMajor(long[])\npublic  com.android.server.pm.PackageSetting setUsesStaticLibraries(java.lang.String[])\npublic  com.android.server.pm.PackageSetting setUsesStaticLibrariesVersions(long[])\npublic  com.android.server.pm.PackageSetting setApexModuleName(java.lang.String)\npublic @android.annotation.NonNull @java.lang.Override com.android.server.pm.pkg.PackageStateUnserialized getTransientState()\npublic @android.annotation.NonNull android.util.SparseArray<? extends PackageUserStateInternal> getUserStates()\npublic  com.android.server.pm.PackageSetting addMimeTypes(java.lang.String,java.util.Set<java.lang.String>)\npublic @android.annotation.NonNull @java.lang.Override com.android.server.pm.pkg.PackageUserState getStateForUser(android.os.UserHandle)\npublic @android.annotation.Nullable java.lang.String getPrimaryCpuAbi()\npublic @android.annotation.Nullable java.lang.String getSecondaryCpuAbi()\npublic @android.annotation.Nullable @java.lang.Override java.lang.String getSeInfo()\npublic @android.annotation.Nullable java.lang.String getPrimaryCpuAbiLegacy()\npublic @android.annotation.Nullable java.lang.String getSecondaryCpuAbiLegacy()\npublic @android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy @java.lang.Override int getHiddenApiEnforcementPolicy()\npublic @java.lang.Override boolean isApex()\npublic @java.lang.Override boolean isForceQueryableOverride()\npublic @java.lang.Override boolean isUpdateAvailable()\npublic @java.lang.Override boolean isInstallPermissionsFixed()\npublic @java.lang.Override boolean isDefaultToDeviceProtectedStorage()\npublic @java.lang.Override boolean isPersistent()\nclass PackageSetting extends com.android.server.pm.SettingBase implements [com.android.server.pm.pkg.PackageStateInternal]\nprivate static final  int INSTALL_PERMISSION_FIXED\nprivate static final  int DEFAULT_TO_DEVICE_PROTECTED_STORAGE\nprivate static final  int UPDATE_AVAILABLE\nprivate static final  int FORCE_QUERYABLE_OVERRIDE\nprivate static final  int PERSISTENT\nclass Booleans extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genGetters=true, genConstructor=false, genSetters=false, genBuilder=false)")
+            inputSignatures = "private  int mBooleans\nprivate  int mSharedUserAppId\nprivate @android.annotation.Nullable java.util.Map<java.lang.String,java.util.Set<java.lang.String>> mimeGroups\nprivate @java.lang.Deprecated @android.annotation.Nullable java.util.Set<java.lang.String> mOldCodePaths\nprivate @android.annotation.Nullable java.lang.String[] usesSdkLibraries\nprivate @android.annotation.Nullable long[] usesSdkLibrariesVersionsMajor\nprivate @android.annotation.Nullable java.lang.String[] usesStaticLibraries\nprivate @android.annotation.Nullable long[] usesStaticLibrariesVersions\nprivate @android.annotation.Nullable @java.lang.Deprecated java.lang.String legacyNativeLibraryPath\nprivate @android.annotation.NonNull java.lang.String mName\nprivate @android.annotation.Nullable java.lang.String mRealName\nprivate  int mAppId\nprivate @android.annotation.Nullable com.android.server.pm.parsing.pkg.AndroidPackageInternal pkg\nprivate @android.annotation.NonNull java.io.File mPath\nprivate @android.annotation.NonNull java.lang.String mPathString\nprivate  float mLoadingProgress\nprivate  long mLoadingCompletedTime\nprivate @android.annotation.Nullable java.lang.String mPrimaryCpuAbi\nprivate @android.annotation.Nullable java.lang.String mSecondaryCpuAbi\nprivate @android.annotation.Nullable java.lang.String mCpuAbiOverride\nprivate  long mLastModifiedTime\nprivate  long lastUpdateTime\nprivate  long versionCode\nprivate @android.annotation.NonNull com.android.server.pm.PackageSignatures signatures\nprivate @android.annotation.NonNull com.android.server.pm.PackageKeySetData keySetData\nprivate final @android.annotation.NonNull android.util.SparseArray<com.android.server.pm.pkg.PackageUserStateImpl> mUserStates\nprivate @android.annotation.NonNull com.android.server.pm.InstallSource installSource\nprivate @android.annotation.Nullable java.lang.String volumeUuid\nprivate  int categoryOverride\nprivate final @android.annotation.NonNull com.android.server.pm.pkg.PackageStateUnserialized pkgState\nprivate @android.annotation.NonNull java.util.UUID mDomainSetId\nprivate @android.annotation.Nullable java.lang.String mAppMetadataFilePath\nprivate  int mTargetSdkVersion\nprivate @android.annotation.Nullable byte[] mRestrictUpdateHash\nprivate final @android.annotation.NonNull com.android.server.utils.SnapshotCache<com.android.server.pm.PackageSetting> mSnapshot\nprivate  void setBoolean(int,boolean)\nprivate  boolean getBoolean(int)\nprivate  com.android.server.utils.SnapshotCache<com.android.server.pm.PackageSetting> makeCache()\npublic  com.android.server.pm.PackageSetting snapshot()\npublic  void dumpDebug(android.util.proto.ProtoOutputStream,long,java.util.List<android.content.pm.UserInfo>,com.android.server.pm.permission.LegacyPermissionDataProvider)\npublic  com.android.server.pm.PackageSetting setAppId(int)\npublic  com.android.server.pm.PackageSetting setCpuAbiOverride(java.lang.String)\npublic  com.android.server.pm.PackageSetting setFirstInstallTimeFromReplaced(com.android.server.pm.pkg.PackageStateInternal,int[])\npublic  com.android.server.pm.PackageSetting setFirstInstallTime(long,int)\npublic  com.android.server.pm.PackageSetting setForceQueryableOverride(boolean)\npublic  com.android.server.pm.PackageSetting setInstallerPackage(java.lang.String,int)\npublic  com.android.server.pm.PackageSetting setUpdateOwnerPackage(java.lang.String)\npublic  com.android.server.pm.PackageSetting setInstallSource(com.android.server.pm.InstallSource)\n  com.android.server.pm.PackageSetting removeInstallerPackage(java.lang.String)\npublic  com.android.server.pm.PackageSetting setIsOrphaned(boolean)\npublic  com.android.server.pm.PackageSetting setKeySetData(com.android.server.pm.PackageKeySetData)\npublic  com.android.server.pm.PackageSetting setLastModifiedTime(long)\npublic  com.android.server.pm.PackageSetting setLastUpdateTime(long)\npublic  com.android.server.pm.PackageSetting setLongVersionCode(long)\npublic  boolean setMimeGroup(java.lang.String,android.util.ArraySet<java.lang.String>)\npublic  com.android.server.pm.PackageSetting setPkg(com.android.server.pm.pkg.AndroidPackage)\npublic  com.android.server.pm.PackageSetting setPkgStateLibraryFiles(java.util.Collection<java.lang.String>)\npublic  com.android.server.pm.PackageSetting setPrimaryCpuAbi(java.lang.String)\npublic  com.android.server.pm.PackageSetting setSecondaryCpuAbi(java.lang.String)\npublic  com.android.server.pm.PackageSetting setSignatures(com.android.server.pm.PackageSignatures)\npublic  com.android.server.pm.PackageSetting setVolumeUuid(java.lang.String)\npublic @java.lang.Override boolean isExternalStorage()\npublic  com.android.server.pm.PackageSetting setUpdateAvailable(boolean)\npublic  com.android.server.pm.PackageSetting setSharedUserAppId(int)\npublic  com.android.server.pm.PackageSetting setTargetSdkVersion(int)\npublic  com.android.server.pm.PackageSetting setRestrictUpdateHash(byte[])\npublic @java.lang.Override int getSharedUserAppId()\npublic @java.lang.Override boolean hasSharedUser()\npublic @java.lang.Override java.lang.String toString()\nprivate  void copyMimeGroups(java.util.Map<java.lang.String,java.util.Set<java.lang.String>>)\npublic  void updateFrom(com.android.server.pm.PackageSetting)\n  com.android.server.pm.PackageSetting updateMimeGroups(java.util.Set<java.lang.String>)\npublic @java.lang.Deprecated @java.lang.Override com.android.server.pm.permission.LegacyPermissionState getLegacyPermissionState()\npublic  com.android.server.pm.PackageSetting setInstallPermissionsFixed(boolean)\npublic  boolean isPrivileged()\npublic  boolean isOem()\npublic  boolean isVendor()\npublic  boolean isProduct()\npublic @java.lang.Override boolean isRequiredForSystemUser()\npublic  boolean isSystemExt()\npublic  boolean isOdm()\npublic  boolean isSystem()\npublic  boolean isRequestLegacyExternalStorage()\npublic  boolean isUserDataFragile()\npublic  android.content.pm.SigningDetails getSigningDetails()\npublic  com.android.server.pm.PackageSetting setSigningDetails(android.content.pm.SigningDetails)\npublic  void copyPackageSetting(com.android.server.pm.PackageSetting,boolean)\n @com.android.internal.annotations.VisibleForTesting com.android.server.pm.pkg.PackageUserStateImpl modifyUserState(int)\npublic  com.android.server.pm.pkg.PackageUserStateImpl getOrCreateUserState(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateInternal readUserState(int)\n  void setEnabled(int,int,java.lang.String)\n  int getEnabled(int)\n  void setInstalled(boolean,int)\n  boolean getInstalled(int)\n  int getInstallReason(int)\n  void setInstallReason(int,int)\n  int getUninstallReason(int)\n  void setUninstallReason(int,int)\n @android.annotation.NonNull android.content.pm.overlay.OverlayPaths getOverlayPaths(int)\n  boolean setOverlayPathsForLibrary(java.lang.String,android.content.pm.overlay.OverlayPaths,int)\n  boolean isInstalledOrHasDataOnAnyOtherUser(int[],int)\n  int[] queryInstalledUsers(int[],boolean)\n  int[] queryUsersInstalledOrHasData(int[])\n  long getCeDataInode(int)\n  long getDeDataInode(int)\n  void setCeDataInode(long,int)\n  void setDeDataInode(long,int)\n  boolean getStopped(int)\n  void setStopped(boolean,int)\n  boolean getNotLaunched(int)\n  void setNotLaunched(boolean,int)\n  boolean getHidden(int)\n  void setHidden(boolean,int)\n  int getDistractionFlags(int)\n  void setDistractionFlags(int,int)\npublic  boolean getInstantApp(int)\n  void setInstantApp(boolean,int)\n  boolean getVirtualPreload(int)\n  void setVirtualPreload(boolean,int)\n  void setUserState(int,long,long,int,boolean,boolean,boolean,boolean,int,android.util.ArrayMap<java.lang.String,com.android.server.pm.pkg.SuspendParams>,boolean,boolean,java.lang.String,android.util.ArraySet<java.lang.String>,android.util.ArraySet<java.lang.String>,int,int,java.lang.String,java.lang.String,long,int,com.android.server.pm.pkg.ArchiveState)\n  void setUserState(int,com.android.server.pm.pkg.PackageUserStateInternal)\n  com.android.server.utils.WatchedArraySet<java.lang.String> getEnabledComponents(int)\n  com.android.server.utils.WatchedArraySet<java.lang.String> getDisabledComponents(int)\n  void setEnabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>,int)\n  void setDisabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>,int)\n  void setEnabledComponentsCopy(com.android.server.utils.WatchedArraySet<java.lang.String>,int)\n  void setDisabledComponentsCopy(com.android.server.utils.WatchedArraySet<java.lang.String>,int)\n  com.android.server.pm.pkg.PackageUserStateImpl modifyUserStateComponents(int,boolean,boolean)\n  void addDisabledComponent(java.lang.String,int)\n  void addEnabledComponent(java.lang.String,int)\n  boolean enableComponentLPw(java.lang.String,int)\n  boolean disableComponentLPw(java.lang.String,int)\n  boolean restoreComponentLPw(java.lang.String,int)\n  int getCurrentEnabledStateLPr(java.lang.String,int)\n  void removeUser(int)\npublic  int[] getNotInstalledUserIds()\n  void writePackageUserPermissionsProto(android.util.proto.ProtoOutputStream,long,java.util.List<android.content.pm.UserInfo>,com.android.server.pm.permission.LegacyPermissionDataProvider)\nprotected  void writeUsersInfoToProto(android.util.proto.ProtoOutputStream,long)\nprivate static  void writeArchiveState(android.util.proto.ProtoOutputStream,com.android.server.pm.pkg.ArchiveState)\npublic @com.android.internal.annotations.VisibleForTesting com.android.server.pm.PackageSetting setPath(java.io.File)\npublic @com.android.internal.annotations.VisibleForTesting boolean overrideNonLocalizedLabelAndIcon(android.content.ComponentName,java.lang.String,java.lang.Integer,int)\npublic  void resetOverrideComponentLabelIcon(int)\npublic @android.annotation.Nullable java.lang.String getSplashScreenTheme(int)\npublic  boolean isIncremental()\npublic  boolean isLoading()\npublic  com.android.server.pm.PackageSetting setLoadingProgress(float)\npublic  com.android.server.pm.PackageSetting setLoadingCompletedTime(long)\npublic  com.android.server.pm.PackageSetting setAppMetadataFilePath(java.lang.String)\npublic @android.annotation.NonNull @java.lang.Override long getVersionCode()\npublic @android.annotation.Nullable @java.lang.Override java.util.Map<java.lang.String,java.util.Set<java.lang.String>> getMimeGroups()\npublic @android.annotation.NonNull @java.lang.Override java.lang.String getPackageName()\npublic @android.annotation.Nullable @java.lang.Override com.android.server.pm.pkg.AndroidPackage getAndroidPackage()\npublic @android.annotation.NonNull android.content.pm.SigningInfo getSigningInfo()\npublic @android.annotation.NonNull @java.lang.Override java.lang.String[] getUsesSdkLibraries()\npublic @android.annotation.NonNull @java.lang.Override long[] getUsesSdkLibrariesVersionsMajor()\npublic @android.annotation.NonNull @java.lang.Override java.lang.String[] getUsesStaticLibraries()\npublic @android.annotation.NonNull @java.lang.Override long[] getUsesStaticLibrariesVersions()\npublic @android.annotation.NonNull @java.lang.Override java.util.List<com.android.server.pm.pkg.SharedLibrary> getSharedLibraryDependencies()\npublic @android.annotation.NonNull com.android.server.pm.PackageSetting addUsesLibraryInfo(android.content.pm.SharedLibraryInfo)\npublic @android.annotation.NonNull @java.lang.Override java.util.List<java.lang.String> getUsesLibraryFiles()\npublic @android.annotation.NonNull com.android.server.pm.PackageSetting addUsesLibraryFile(java.lang.String)\npublic @java.lang.Override boolean isHiddenUntilInstalled()\npublic @android.annotation.NonNull @java.lang.Override long[] getLastPackageUsageTime()\npublic @java.lang.Override boolean isUpdatedSystemApp()\npublic @java.lang.Override boolean isApkInUpdatedApex()\npublic @android.annotation.Nullable @java.lang.Override java.lang.String getApexModuleName()\npublic  com.android.server.pm.PackageSetting setDomainSetId(java.util.UUID)\npublic  com.android.server.pm.PackageSetting setCategoryOverride(int)\npublic  com.android.server.pm.PackageSetting setLegacyNativeLibraryPath(java.lang.String)\npublic  com.android.server.pm.PackageSetting setMimeGroups(java.util.Map<java.lang.String,java.util.Set<java.lang.String>>)\npublic  com.android.server.pm.PackageSetting setOldCodePaths(java.util.Set<java.lang.String>)\npublic  com.android.server.pm.PackageSetting setUsesSdkLibraries(java.lang.String[])\npublic  com.android.server.pm.PackageSetting setUsesSdkLibrariesVersionsMajor(long[])\npublic  com.android.server.pm.PackageSetting setUsesStaticLibraries(java.lang.String[])\npublic  com.android.server.pm.PackageSetting setUsesStaticLibrariesVersions(long[])\npublic  com.android.server.pm.PackageSetting setApexModuleName(java.lang.String)\npublic @android.annotation.NonNull @java.lang.Override com.android.server.pm.pkg.PackageStateUnserialized getTransientState()\npublic @android.annotation.NonNull android.util.SparseArray<? extends PackageUserStateInternal> getUserStates()\npublic  com.android.server.pm.PackageSetting addMimeTypes(java.lang.String,java.util.Set<java.lang.String>)\npublic @android.annotation.NonNull @java.lang.Override com.android.server.pm.pkg.PackageUserState getStateForUser(android.os.UserHandle)\npublic @android.annotation.Nullable java.lang.String getPrimaryCpuAbi()\npublic @android.annotation.Nullable java.lang.String getSecondaryCpuAbi()\npublic @android.annotation.Nullable @java.lang.Override java.lang.String getSeInfo()\npublic @android.annotation.Nullable java.lang.String getPrimaryCpuAbiLegacy()\npublic @android.annotation.Nullable java.lang.String getSecondaryCpuAbiLegacy()\npublic @android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy @java.lang.Override int getHiddenApiEnforcementPolicy()\npublic @java.lang.Override boolean isApex()\npublic @java.lang.Override boolean isForceQueryableOverride()\npublic @java.lang.Override boolean isUpdateAvailable()\npublic @java.lang.Override boolean isInstallPermissionsFixed()\npublic @java.lang.Override boolean isDefaultToDeviceProtectedStorage()\npublic @java.lang.Override boolean isPersistent()\nclass PackageSetting extends com.android.server.pm.SettingBase implements [com.android.server.pm.pkg.PackageStateInternal]\nprivate static final  int INSTALL_PERMISSION_FIXED\nprivate static final  int UPDATE_AVAILABLE\nprivate static final  int FORCE_QUERYABLE_OVERRIDE\nclass Booleans extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genGetters=true, genConstructor=false, genSetters=false, genBuilder=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/services/core/java/com/android/server/pm/ScanPackageUtils.java b/services/core/java/com/android/server/pm/ScanPackageUtils.java
index 8d8acfd4..7ea9e3f 100644
--- a/services/core/java/com/android/server/pm/ScanPackageUtils.java
+++ b/services/core/java/com/android/server/pm/ScanPackageUtils.java
@@ -220,7 +220,7 @@
                     UserManagerService.getInstance(), usesSdkLibraries,
                     parsedPackage.getUsesSdkLibrariesVersionsMajor(), usesStaticLibraries,
                     parsedPackage.getUsesStaticLibrariesVersions(), parsedPackage.getMimeGroups(),
-                    newDomainSetId, parsedPackage.isPersistent(),
+                    newDomainSetId,
                     parsedPackage.getTargetSdkVersion(), parsedPackage.getRestrictUpdateHash());
         } else {
             // make a deep copy to avoid modifying any existing system state.
@@ -241,7 +241,7 @@
                     UserManagerService.getInstance(),
                     usesSdkLibraries, parsedPackage.getUsesSdkLibrariesVersionsMajor(),
                     usesStaticLibraries, parsedPackage.getUsesStaticLibrariesVersions(),
-                    parsedPackage.getMimeGroups(), newDomainSetId, parsedPackage.isPersistent(),
+                    parsedPackage.getMimeGroups(), newDomainSetId,
                     parsedPackage.getTargetSdkVersion(), parsedPackage.getRestrictUpdateHash());
         }
 
@@ -464,8 +464,6 @@
                             + " to " + volumeUuid);
             pkgSetting.setVolumeUuid(volumeUuid);
         }
-        pkgSetting.setDefaultToDeviceProtectedStorage(
-                parsedPackage.isDefaultToDeviceProtectedStorage());
 
         SharedLibraryInfo sdkLibraryInfo = null;
         if (!TextUtils.isEmpty(parsedPackage.getSdkLibraryName())) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index a39178e..440823c 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -946,7 +946,6 @@
             ret.setMimeGroups(p.getMimeGroups());
             ret.setAppMetadataFilePath(p.getAppMetadataFilePath());
             ret.getPkgState().setUpdatedSystemApp(false);
-            ret.setIsPersistent(p.isPersistent());
             ret.setTargetSdkVersion(p.getTargetSdkVersion());
             ret.setRestrictUpdateHash(p.getRestrictUpdateHash());
         }
@@ -1061,7 +1060,7 @@
             boolean virtualPreload, boolean isStoppedSystemApp, UserManagerService userManager,
             String[] usesSdkLibraries, long[] usesSdkLibrariesVersions,
             String[] usesStaticLibraries, long[] usesStaticLibrariesVersions,
-            Set<String> mimeGroupNames, @NonNull UUID domainSetId, boolean isPersistent,
+            Set<String> mimeGroupNames, @NonNull UUID domainSetId,
             int targetSdkVersion, byte[] restrictUpdatedHash) {
         final PackageSetting pkgSetting;
         if (originalPkg != null) {
@@ -1083,7 +1082,6 @@
                     // Update new package state.
                     .setLastModifiedTime(codePath.lastModified())
                     .setDomainSetId(domainSetId)
-                    .setIsPersistent(isPersistent)
                     .setTargetSdkVersion(targetSdkVersion)
                     .setRestrictUpdateHash(restrictUpdatedHash);
             pkgSetting.setFlags(pkgFlags)
@@ -1103,7 +1101,6 @@
                     .setSecondaryCpuAbi(secondaryCpuAbi)
                     .setLongVersionCode(versionCode)
                     .setMimeGroups(createMimeGroups(mimeGroupNames))
-                    .setIsPersistent(isPersistent)
                     .setTargetSdkVersion(targetSdkVersion)
                     .setRestrictUpdateHash(restrictUpdatedHash)
                     .setLastModifiedTime(codePath.lastModified());
@@ -1219,7 +1216,7 @@
             int pkgPrivateFlags, @NonNull UserManagerService userManager,
             @Nullable String[] usesSdkLibraries, @Nullable long[] usesSdkLibrariesVersions,
             @Nullable String[] usesStaticLibraries, @Nullable long[] usesStaticLibrariesVersions,
-            @Nullable Set<String> mimeGroupNames, @NonNull UUID domainSetId, boolean isPersistent,
+            @Nullable Set<String> mimeGroupNames, @NonNull UUID domainSetId,
             int targetSdkVersion, byte[] restrictUpdatedHash)
                     throws PackageManagerException {
         final String pkgName = pkgSetting.getPackageName();
@@ -1273,7 +1270,6 @@
                 .setSecondaryCpuAbi(secondaryCpuAbi)
                 .updateMimeGroups(mimeGroupNames)
                 .setDomainSetId(domainSetId)
-                .setIsPersistent(isPersistent)
                 .setTargetSdkVersion(targetSdkVersion)
                 .setRestrictUpdateHash(restrictUpdatedHash);
         // Update SDK library dependencies if needed.
@@ -3071,7 +3067,6 @@
         serializer.attributeLongHex(null, "ft", pkg.getLastModifiedTime());
         serializer.attributeLongHex(null, "ut", pkg.getLastUpdateTime());
         serializer.attributeLong(null, "version", pkg.getVersionCode());
-        serializer.attributeBoolean(null, "isPersistent", pkg.isPersistent());
         serializer.attributeInt(null, "targetSdkVersion", pkg.getTargetSdkVersion());
         if (pkg.getRestrictUpdateHash() != null) {
             serializer.attributeBytesBase64(null, "restrictUpdateHash",
@@ -3140,7 +3135,6 @@
         serializer.attributeLongHex(null, "ft", pkg.getLastModifiedTime());
         serializer.attributeLongHex(null, "ut", pkg.getLastUpdateTime());
         serializer.attributeLong(null, "version", pkg.getVersionCode());
-        serializer.attributeBoolean(null, "isPersistent", pkg.isPersistent());
         serializer.attributeInt(null, "targetSdkVersion", pkg.getTargetSdkVersion());
         if (pkg.getRestrictUpdateHash() != null) {
             serializer.attributeBytesBase64(null, "restrictUpdateHash",
@@ -3182,8 +3176,6 @@
         if (pkg.getVolumeUuid() != null) {
             serializer.attribute(null, "volumeUuid", pkg.getVolumeUuid());
         }
-        serializer.attributeBoolean(null, "defaultToDeviceProtectedStorage",
-                pkg.isDefaultToDeviceProtectedStorage());
         if (pkg.getCategoryOverride() != ApplicationInfo.CATEGORY_UNDEFINED) {
             serializer.attributeInt(null, "categoryHint", pkg.getCategoryOverride());
         }
@@ -3878,7 +3870,6 @@
         }
 
         long versionCode = parser.getAttributeLong(null, "version", 0);
-        boolean isPersistent = parser.getAttributeBoolean(null, "isPersistent", false);
         int targetSdkVersion = parser.getAttributeInt(null, "targetSdkVersion", 0);
         byte[] restrictUpdateHash = parser.getAttributeBytesBase64(null, "restrictUpdateHash",
                 null);
@@ -3901,7 +3892,6 @@
                 .setSecondaryCpuAbi(secondaryCpuAbiStr)
                 .setCpuAbiOverride(cpuAbiOverrideStr)
                 .setLongVersionCode(versionCode)
-                .setIsPersistent(isPersistent)
                 .setTargetSdkVersion(targetSdkVersion)
                 .setRestrictUpdateHash(restrictUpdateHash);
         long timeStamp = parser.getAttributeLongHex(null, "ft", 0);
@@ -3982,7 +3972,6 @@
         String installInitiatingPackageName = null;
         boolean installInitiatorUninstalled = false;
         String volumeUuid = null;
-        boolean defaultToDeviceProtectedStorage = false;
         boolean updateAvailable = false;
         int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED;
         int pkgFlags = 0;
@@ -3997,7 +3986,6 @@
         long loadingCompletedTime = 0;
         UUID domainSetId;
         String appMetadataFilePath = null;
-        boolean isPersistent = false;
         int targetSdkVersion = 0;
         byte[] restrictUpdateHash = null;
         try {
@@ -4023,7 +4011,6 @@
             }
 
             versionCode = parser.getAttributeLong(null, "version", 0);
-            isPersistent = parser.getAttributeBoolean(null, "isPersistent", false);
             targetSdkVersion = parser.getAttributeInt(null, "targetSdkVersion", 0);
             restrictUpdateHash = parser.getAttributeBytesBase64(null, "restrictUpdateHash", null);
             installerPackageName = parser.getAttributeValue(null, "installer");
@@ -4038,8 +4025,6 @@
             installInitiatorUninstalled = parser.getAttributeBoolean(null,
                     "installInitiatorUninstalled", false);
             volumeUuid = parser.getAttributeValue(null, "volumeUuid");
-            defaultToDeviceProtectedStorage = parser.getAttributeBoolean(
-                    null, "defaultToDeviceProtectedStorage", false);
             categoryHint = parser.getAttributeInt(null, "categoryHint",
                     ApplicationInfo.CATEGORY_UNDEFINED);
             appMetadataFilePath = parser.getAttributeValue(null, "appMetadataFilePath");
@@ -4179,7 +4164,6 @@
                     installInitiatorUninstalled);
             packageSetting.setInstallSource(installSource)
                     .setVolumeUuid(volumeUuid)
-                    .setDefaultToDeviceProtectedStorage(defaultToDeviceProtectedStorage)
                     .setCategoryOverride(categoryHint)
                     .setLegacyNativeLibraryPath(legacyNativeLibraryPathStr)
                     .setPrimaryCpuAbi(primaryCpuAbiString)
@@ -4189,7 +4173,6 @@
                     .setLoadingProgress(loadingProgress)
                     .setLoadingCompletedTime(loadingCompletedTime)
                     .setAppMetadataFilePath(appMetadataFilePath)
-                    .setIsPersistent(isPersistent)
                     .setTargetSdkVersion(targetSdkVersion)
                     .setRestrictUpdateHash(restrictUpdateHash);
             // Handle legacy string here for single-user mode
diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java
index 823fbc9..2fabb0e 100644
--- a/services/core/java/com/android/server/wm/Dimmer.java
+++ b/services/core/java/com/android/server/wm/Dimmer.java
@@ -29,7 +29,7 @@
  */
 public abstract class Dimmer {
 
-    static final boolean DIMMER_REFACTOR = Flags.dimmerRefactor();
+    static final boolean DIMMER_REFACTOR = Flags.introduceSmootherDimmer();
 
     /**
      * The {@link WindowContainer} that our Dims are bounded to. We may be dimming on behalf of the
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 2315fca..6c31e3e 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -199,7 +199,6 @@
 import com.android.server.am.ActivityManagerService;
 import com.android.server.am.AppTimeTracker;
 import com.android.server.uri.NeededUriGrants;
-import com.android.window.flags.Flags;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -3301,7 +3300,7 @@
         // Once at the root task level, we want to check {@link #isTranslucent(ActivityRecord)}.
         // If true, we want to get the Dimmer from the level above since we don't want to animate
         // the dim with the Task.
-        if (!isRootTask() || (Flags.dimmerRefactor() && isTranslucentAndVisible())
+        if (!isRootTask() || (Dimmer.DIMMER_REFACTOR && isTranslucentAndVisible())
                 || isTranslucent(null)) {
             return super.getDimmer();
         }
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 77a23ec..82d3424 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -103,7 +103,6 @@
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.server.am.HostingRecord;
 import com.android.server.pm.pkg.AndroidPackage;
-import com.android.window.flags.Flags;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -210,7 +209,7 @@
      */
     int mMinHeight;
 
-    Dimmer mDimmer = Flags.dimmerRefactor()
+    Dimmer mDimmer = Dimmer.DIMMER_REFACTOR
             ? new SmoothDimmer(this) : new LegacyDimmer(this);
 
     /** Apply the dim layer on the embedded TaskFragment. */
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 924e2f8..0d024d6 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -2083,17 +2083,14 @@
                 t.traceEnd();
             }
 
-            // Devices without WebView/JavaScript cannot support PAC proxies.
-            if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
-                t.traceBegin("StartPacProxyService");
-                try {
-                    pacProxyService = new PacProxyService(context);
-                    ServiceManager.addService(Context.PAC_PROXY_SERVICE, pacProxyService);
-                } catch (Throwable e) {
-                    reportWtf("starting PacProxyService", e);
-                }
-                t.traceEnd();
+            t.traceBegin("StartPacProxyService");
+            try {
+                pacProxyService = new PacProxyService(context);
+                ServiceManager.addService(Context.PAC_PROXY_SERVICE, pacProxyService);
+            } catch (Throwable e) {
+                reportWtf("starting PacProxyService", e);
             }
+            t.traceEnd();
 
             t.traceBegin("StartConnectivityService");
             // This has to be called after NetworkManagementService, NetworkStatsService
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java
index aaad669..2810145 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -1051,7 +1051,6 @@
                 null /*usesStaticLibrariesVersions*/,
                 null /*mimeGroups*/,
                 UUID.randomUUID(),
-                false /*isPersistent*/,
                 34 /*targetSdkVersion*/,
                 null /*restrictUpdateHash*/);
         assertThat(testPkgSetting01.getPrimaryCpuAbi(), is("arm64-v8a"));
@@ -1092,7 +1091,6 @@
                 null /*usesStaticLibrariesVersions*/,
                 null /*mimeGroups*/,
                 UUID.randomUUID(),
-                false /*isPersistent*/,
                 34 /*targetSdkVersion*/,
                 null /*restrictUpdateHash*/);
         assertThat(testPkgSetting01.getPrimaryCpuAbi(), is("arm64-v8a"));
@@ -1135,7 +1133,6 @@
                     null /*usesStaticLibrariesVersions*/,
                     null /*mimeGroups*/,
                     UUID.randomUUID(),
-                    false /*isPersistent*/,
                     34 /*targetSdkVersion*/,
                     null /*restrictUpdateHash*/);
             fail("Expected a PackageManagerException");
@@ -1174,7 +1171,6 @@
                 null /*usesStaticLibrariesVersions*/,
                 null /*mimeGroups*/,
                 UUID.randomUUID(),
-                false /*isPersistent*/,
                 34 /*targetSdkVersion*/,
                 null /*restrictUpdateHash*/);
         assertThat(testPkgSetting01.getPath(), is(UPDATED_CODE_PATH));
@@ -1222,7 +1218,6 @@
                 null /*usesStaticLibrariesVersions*/,
                 null /*mimeGroups*/,
                 UUID.randomUUID(),
-                false /*isPersistent*/,
                 34 /*targetSdkVersion*/,
                 null /*restrictUpdateHash*/);
         assertThat(testPkgSetting01.getAppId(), is(0));
@@ -1270,7 +1265,6 @@
                 null /*usesStaticLibrariesVersions*/,
                 null /*mimeGroups*/,
                 UUID.randomUUID(),
-                false /*isPersistent*/,
                 34 /*targetSdkVersion*/,
                 null /*restrictUpdateHash*/);
         assertThat(testPkgSetting01.getAppId(), is(10064));
@@ -1319,7 +1313,6 @@
                 null /*usesStaticLibrariesVersions*/,
                 null /*mimeGroups*/,
                 UUID.randomUUID(),
-                false /*isPersistent*/,
                 34 /*targetSdkVersion*/,
                 null /*restrictUpdateHash*/);
         assertThat(testPkgSetting01.getAppId(), is(10064));
@@ -1365,7 +1358,6 @@
                 null /*usesStaticLibrariesVersions*/,
                 null /*mimeGroups*/,
                 UUID.randomUUID(),
-                false /*isPersistent*/,
                 34 /*targetSdkVersion*/,
                 null /*restrictUpdateHash*/);
         assertThat(testPkgSetting01.getAppId(), is(0));
diff --git a/services/tests/servicestests/src/com/android/server/contentcapture/ContentCaptureManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/contentcapture/ContentCaptureManagerServiceTest.java
index 5cc84b1..78bf9b0 100644
--- a/services/tests/servicestests/src/com/android/server/contentcapture/ContentCaptureManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/contentcapture/ContentCaptureManagerServiceTest.java
@@ -24,7 +24,6 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
@@ -44,7 +43,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.server.LocalServices;
-import com.android.server.contentprotection.ContentProtectionBlocklistManager;
+import com.android.server.contentprotection.ContentProtectionAllowlistManager;
 import com.android.server.contentprotection.ContentProtectionConsentManager;
 import com.android.server.contentprotection.RemoteContentProtectionService;
 import com.android.server.pm.UserManagerInternal;
@@ -94,7 +93,7 @@
 
     @Mock private UserManagerInternal mMockUserManagerInternal;
 
-    @Mock private ContentProtectionBlocklistManager mMockContentProtectionBlocklistManager;
+    @Mock private ContentProtectionAllowlistManager mMockContentProtectionAllowlistManager;
 
     @Mock private ContentCaptureServiceInfo mMockContentCaptureServiceInfo;
 
@@ -108,7 +107,7 @@
 
     private List<List<String>> mDevCfgContentProtectionOptionalGroups = Collections.emptyList();
 
-    private int mContentProtectionBlocklistManagersCreated;
+    private int mContentProtectionAllowlistManagersCreated;
 
     private int mContentProtectionServiceInfosCreated;
 
@@ -132,10 +131,10 @@
 
     @Test
     public void constructor_contentProtection_flagDisabled_noManagers() {
-        assertThat(mContentProtectionBlocklistManagersCreated).isEqualTo(0);
+        assertThat(mContentProtectionAllowlistManagersCreated).isEqualTo(0);
         assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0);
         assertThat(mContentProtectionConsentManagersCreated).isEqualTo(0);
-        verifyZeroInteractions(mMockContentProtectionBlocklistManager);
+        verifyZeroInteractions(mMockContentProtectionAllowlistManager);
         verifyZeroInteractions(mMockContentProtectionConsentManager);
     }
 
@@ -145,10 +144,10 @@
 
         mContentCaptureManagerService = new TestContentCaptureManagerService();
 
-        assertThat(mContentProtectionBlocklistManagersCreated).isEqualTo(0);
+        assertThat(mContentProtectionAllowlistManagersCreated).isEqualTo(0);
         assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0);
         assertThat(mContentProtectionConsentManagersCreated).isEqualTo(0);
-        verifyZeroInteractions(mMockContentProtectionBlocklistManager);
+        verifyZeroInteractions(mMockContentProtectionAllowlistManager);
         verifyZeroInteractions(mMockContentProtectionConsentManager);
     }
 
@@ -158,10 +157,10 @@
 
         mContentCaptureManagerService = new TestContentCaptureManagerService();
 
-        assertThat(mContentProtectionBlocklistManagersCreated).isEqualTo(0);
+        assertThat(mContentProtectionAllowlistManagersCreated).isEqualTo(0);
         assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0);
         assertThat(mContentProtectionConsentManagersCreated).isEqualTo(0);
-        verifyZeroInteractions(mMockContentProtectionBlocklistManager);
+        verifyZeroInteractions(mMockContentProtectionAllowlistManager);
         verifyZeroInteractions(mMockContentProtectionConsentManager);
     }
 
@@ -171,26 +170,13 @@
 
         mContentCaptureManagerService = new TestContentCaptureManagerService();
 
-        assertThat(mContentProtectionBlocklistManagersCreated).isEqualTo(1);
+        assertThat(mContentProtectionAllowlistManagersCreated).isEqualTo(1);
         assertThat(mContentProtectionConsentManagersCreated).isEqualTo(1);
         assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0);
-        verify(mMockContentProtectionBlocklistManager).updateBlocklist(anyInt());
         verifyZeroInteractions(mMockContentProtectionConsentManager);
     }
 
     @Test
-    public void setFineTuneParamsFromDeviceConfig_doesNotUpdateContentProtectionBlocklist() {
-        mDevCfgEnableContentProtectionReceiver = true;
-        mContentCaptureManagerService = new TestContentCaptureManagerService();
-        mContentCaptureManagerService.mDevCfgContentProtectionAppsBlocklistSize += 100;
-        verify(mMockContentProtectionBlocklistManager).updateBlocklist(anyInt());
-
-        mContentCaptureManagerService.setFineTuneParamsFromDeviceConfig();
-
-        verifyNoMoreInteractions(mMockContentProtectionBlocklistManager);
-    }
-
-    @Test
     public void getOptions_contentCaptureDisabled_contentProtectionDisabled() {
         mDevCfgEnableContentProtectionReceiver = true;
         mContentCaptureManagerService = new TestContentCaptureManagerService();
@@ -201,13 +187,13 @@
 
         assertThat(actual).isNull();
         verify(mMockContentProtectionConsentManager).isConsentGranted(USER_ID);
-        verify(mMockContentProtectionBlocklistManager, never()).isAllowed(anyString());
+        verify(mMockContentProtectionAllowlistManager, never()).isAllowed(anyString());
     }
 
     @Test
     public void getOptions_contentCaptureDisabled_contentProtectionEnabled() {
         when(mMockContentProtectionConsentManager.isConsentGranted(USER_ID)).thenReturn(true);
-        when(mMockContentProtectionBlocklistManager.isAllowed(PACKAGE_NAME)).thenReturn(true);
+        when(mMockContentProtectionAllowlistManager.isAllowed(PACKAGE_NAME)).thenReturn(true);
         mDevCfgEnableContentProtectionReceiver = true;
         mContentCaptureManagerService = new TestContentCaptureManagerService();
 
@@ -239,13 +225,13 @@
         assertThat(actual.contentProtectionOptions.enableReceiver).isFalse();
         assertThat(actual.whitelistedComponents).isNull();
         verify(mMockContentProtectionConsentManager).isConsentGranted(USER_ID);
-        verify(mMockContentProtectionBlocklistManager, never()).isAllowed(anyString());
+        verify(mMockContentProtectionAllowlistManager, never()).isAllowed(anyString());
     }
 
     @Test
     public void getOptions_contentCaptureEnabled_contentProtectionEnabled() {
         when(mMockContentProtectionConsentManager.isConsentGranted(USER_ID)).thenReturn(true);
-        when(mMockContentProtectionBlocklistManager.isAllowed(PACKAGE_NAME)).thenReturn(true);
+        when(mMockContentProtectionAllowlistManager.isAllowed(PACKAGE_NAME)).thenReturn(true);
         mDevCfgEnableContentProtectionReceiver = true;
         mContentCaptureManagerService = new TestContentCaptureManagerService();
         mContentCaptureManagerService.mGlobalContentCaptureOptions.setWhitelist(
@@ -273,7 +259,7 @@
 
         assertThat(actual).isFalse();
         verify(mMockContentProtectionConsentManager).isConsentGranted(USER_ID);
-        verify(mMockContentProtectionBlocklistManager, never()).isAllowed(anyString());
+        verify(mMockContentProtectionAllowlistManager, never()).isAllowed(anyString());
     }
 
     @Test
@@ -287,13 +273,13 @@
                         USER_ID, PACKAGE_NAME);
 
         assertThat(actual).isFalse();
-        verify(mMockContentProtectionBlocklistManager).isAllowed(PACKAGE_NAME);
+        verify(mMockContentProtectionAllowlistManager).isAllowed(PACKAGE_NAME);
     }
 
     @Test
     public void isWhitelisted_packageName_contentCaptureDisabled_contentProtectionEnabled() {
         when(mMockContentProtectionConsentManager.isConsentGranted(USER_ID)).thenReturn(true);
-        when(mMockContentProtectionBlocklistManager.isAllowed(PACKAGE_NAME)).thenReturn(true);
+        when(mMockContentProtectionAllowlistManager.isAllowed(PACKAGE_NAME)).thenReturn(true);
         mDevCfgEnableContentProtectionReceiver = true;
         mContentCaptureManagerService = new TestContentCaptureManagerService();
 
@@ -317,7 +303,7 @@
 
         assertThat(actual).isTrue();
         verify(mMockContentProtectionConsentManager, never()).isConsentGranted(anyInt());
-        verify(mMockContentProtectionBlocklistManager, never()).isAllowed(anyString());
+        verify(mMockContentProtectionAllowlistManager, never()).isAllowed(anyString());
     }
 
     @Test
@@ -331,7 +317,7 @@
 
         assertThat(actual).isFalse();
         verify(mMockContentProtectionConsentManager).isConsentGranted(USER_ID);
-        verify(mMockContentProtectionBlocklistManager, never()).isAllowed(anyString());
+        verify(mMockContentProtectionAllowlistManager, never()).isAllowed(anyString());
     }
 
     @Test
@@ -345,13 +331,13 @@
                         USER_ID, COMPONENT_NAME);
 
         assertThat(actual).isFalse();
-        verify(mMockContentProtectionBlocklistManager).isAllowed(PACKAGE_NAME);
+        verify(mMockContentProtectionAllowlistManager).isAllowed(PACKAGE_NAME);
     }
 
     @Test
     public void isWhitelisted_componentName_contentCaptureDisabled_contentProtectionEnabled() {
         when(mMockContentProtectionConsentManager.isConsentGranted(USER_ID)).thenReturn(true);
-        when(mMockContentProtectionBlocklistManager.isAllowed(PACKAGE_NAME)).thenReturn(true);
+        when(mMockContentProtectionAllowlistManager.isAllowed(PACKAGE_NAME)).thenReturn(true);
         mDevCfgEnableContentProtectionReceiver = true;
         mContentCaptureManagerService = new TestContentCaptureManagerService();
 
@@ -375,13 +361,13 @@
 
         assertThat(actual).isTrue();
         verify(mMockContentProtectionConsentManager, never()).isConsentGranted(anyInt());
-        verify(mMockContentProtectionBlocklistManager, never()).isAllowed(anyString());
+        verify(mMockContentProtectionAllowlistManager, never()).isAllowed(anyString());
     }
 
     @Test
     public void isContentProtectionReceiverEnabled_true() {
         when(mMockContentProtectionConsentManager.isConsentGranted(USER_ID)).thenReturn(true);
-        when(mMockContentProtectionBlocklistManager.isAllowed(PACKAGE_NAME)).thenReturn(true);
+        when(mMockContentProtectionAllowlistManager.isAllowed(PACKAGE_NAME)).thenReturn(true);
         mDevCfgEnableContentProtectionReceiver = true;
         mContentCaptureManagerService = new TestContentCaptureManagerService();
 
@@ -400,7 +386,7 @@
 
         assertThat(actual).isFalse();
         verify(mMockContentProtectionConsentManager, never()).isConsentGranted(anyInt());
-        verify(mMockContentProtectionBlocklistManager, never()).isAllowed(anyString());
+        verify(mMockContentProtectionAllowlistManager, never()).isAllowed(anyString());
     }
 
     @Test
@@ -415,7 +401,7 @@
 
         assertThat(actual).isFalse();
         verify(mMockContentProtectionConsentManager, never()).isConsentGranted(anyInt());
-        verify(mMockContentProtectionBlocklistManager, never()).isAllowed(anyString());
+        verify(mMockContentProtectionAllowlistManager, never()).isAllowed(anyString());
     }
 
     @Test
@@ -431,7 +417,7 @@
 
         assertThat(actual).isFalse();
         verify(mMockContentProtectionConsentManager, never()).isConsentGranted(anyInt());
-        verify(mMockContentProtectionBlocklistManager, never()).isAllowed(anyString());
+        verify(mMockContentProtectionAllowlistManager, never()).isAllowed(anyString());
     }
 
     @Test
@@ -572,9 +558,9 @@
         }
 
         @Override
-        protected ContentProtectionBlocklistManager createContentProtectionBlocklistManager() {
-            mContentProtectionBlocklistManagersCreated++;
-            return mMockContentProtectionBlocklistManager;
+        protected ContentProtectionAllowlistManager createContentProtectionAllowlistManager() {
+            mContentProtectionAllowlistManagersCreated++;
+            return mMockContentProtectionAllowlistManager;
         }
 
         @Override
diff --git a/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionAllowlistManagerTest.java b/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionAllowlistManagerTest.java
new file mode 100644
index 0000000..6767a85
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionAllowlistManagerTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 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.server.contentprotection;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+/**
+ * Test for {@link ContentProtectionAllowlistManager}.
+ *
+ * <p>Run with: {@code atest FrameworksServicesTests:
+ * com.android.server.contentprotection.ContentProtectionAllowlistManagerTest}
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ContentProtectionAllowlistManagerTest {
+
+    private static final String PACKAGE_NAME = "com.test.package.name";
+
+    @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    private ContentProtectionAllowlistManager mContentProtectionAllowlistManager;
+
+    @Before
+    public void setup() {
+        mContentProtectionAllowlistManager = new ContentProtectionAllowlistManager();
+    }
+
+    @Test
+    public void isAllowed() {
+        boolean actual = mContentProtectionAllowlistManager.isAllowed(PACKAGE_NAME);
+
+        assertThat(actual).isFalse();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionBlocklistManagerTest.java b/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionBlocklistManagerTest.java
deleted file mode 100644
index ba9956a..0000000
--- a/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionBlocklistManagerTest.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2023 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.server.contentprotection;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.content.pm.PackageInfo;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.google.common.collect.ImmutableList;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Test for {@link ContentProtectionBlocklistManager}.
- *
- * <p>Run with: {@code atest
- * FrameworksServicesTests:
- * com.android.server.contentprotection.ContentProtectionBlocklistManagerTest}
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class ContentProtectionBlocklistManagerTest {
-
-    private static final String FIRST_PACKAGE_NAME = "com.test.first.package.name";
-
-    private static final String SECOND_PACKAGE_NAME = "com.test.second.package.name";
-
-    private static final String UNLISTED_PACKAGE_NAME = "com.test.unlisted.package.name";
-
-    private static final String PACKAGE_NAME_BLOCKLIST_FILENAME =
-            "/product/etc/res/raw/content_protection/package_name_blocklist.txt";
-
-    private static final PackageInfo PACKAGE_INFO = new PackageInfo();
-
-    private static final List<String> LINES =
-            ImmutableList.of(FIRST_PACKAGE_NAME, SECOND_PACKAGE_NAME);
-
-    @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
-
-    @Mock private ContentProtectionPackageManager mMockContentProtectionPackageManager;
-
-    private final List<String> mReadRawFiles = new ArrayList<>();
-
-    private ContentProtectionBlocklistManager mContentProtectionBlocklistManager;
-
-    @Before
-    public void setup() {
-        mContentProtectionBlocklistManager = new TestContentProtectionBlocklistManager();
-    }
-
-    @Test
-    public void isAllowed_blocklistNotLoaded() {
-        boolean actual = mContentProtectionBlocklistManager.isAllowed(FIRST_PACKAGE_NAME);
-
-        assertThat(actual).isFalse();
-        assertThat(mReadRawFiles).isEmpty();
-        verifyZeroInteractions(mMockContentProtectionPackageManager);
-    }
-
-    @Test
-    public void isAllowed_inBlocklist() {
-        mContentProtectionBlocklistManager.updateBlocklist(LINES.size());
-
-        boolean actual = mContentProtectionBlocklistManager.isAllowed(FIRST_PACKAGE_NAME);
-
-        assertThat(actual).isFalse();
-        verifyZeroInteractions(mMockContentProtectionPackageManager);
-    }
-
-    @Test
-    public void isAllowed_packageInfoNotFound() {
-        mContentProtectionBlocklistManager.updateBlocklist(LINES.size());
-        when(mMockContentProtectionPackageManager.getPackageInfo(UNLISTED_PACKAGE_NAME))
-                .thenReturn(null);
-
-        boolean actual = mContentProtectionBlocklistManager.isAllowed(UNLISTED_PACKAGE_NAME);
-
-        assertThat(actual).isFalse();
-        verify(mMockContentProtectionPackageManager, never())
-                .hasRequestedInternetPermissions(any());
-        verify(mMockContentProtectionPackageManager, never()).isSystemApp(any());
-        verify(mMockContentProtectionPackageManager, never()).isUpdatedSystemApp(any());
-    }
-
-    @Test
-    public void isAllowed_notRequestedInternet() {
-        mContentProtectionBlocklistManager.updateBlocklist(LINES.size());
-        when(mMockContentProtectionPackageManager.getPackageInfo(UNLISTED_PACKAGE_NAME))
-                .thenReturn(PACKAGE_INFO);
-        when(mMockContentProtectionPackageManager.hasRequestedInternetPermissions(PACKAGE_INFO))
-                .thenReturn(false);
-
-        boolean actual = mContentProtectionBlocklistManager.isAllowed(UNLISTED_PACKAGE_NAME);
-
-        assertThat(actual).isFalse();
-        verify(mMockContentProtectionPackageManager, never()).isSystemApp(any());
-        verify(mMockContentProtectionPackageManager, never()).isUpdatedSystemApp(any());
-    }
-
-    @Test
-    public void isAllowed_systemApp() {
-        mContentProtectionBlocklistManager.updateBlocklist(LINES.size());
-        when(mMockContentProtectionPackageManager.getPackageInfo(UNLISTED_PACKAGE_NAME))
-                .thenReturn(PACKAGE_INFO);
-        when(mMockContentProtectionPackageManager.hasRequestedInternetPermissions(PACKAGE_INFO))
-                .thenReturn(true);
-        when(mMockContentProtectionPackageManager.isSystemApp(PACKAGE_INFO)).thenReturn(true);
-
-        boolean actual = mContentProtectionBlocklistManager.isAllowed(UNLISTED_PACKAGE_NAME);
-
-        assertThat(actual).isFalse();
-        verify(mMockContentProtectionPackageManager, never()).isUpdatedSystemApp(any());
-    }
-
-    @Test
-    public void isAllowed_updatedSystemApp() {
-        mContentProtectionBlocklistManager.updateBlocklist(LINES.size());
-        when(mMockContentProtectionPackageManager.getPackageInfo(UNLISTED_PACKAGE_NAME))
-                .thenReturn(PACKAGE_INFO);
-        when(mMockContentProtectionPackageManager.hasRequestedInternetPermissions(PACKAGE_INFO))
-                .thenReturn(true);
-        when(mMockContentProtectionPackageManager.isSystemApp(PACKAGE_INFO)).thenReturn(true);
-        when(mMockContentProtectionPackageManager.isUpdatedSystemApp(PACKAGE_INFO))
-                .thenReturn(true);
-
-        boolean actual = mContentProtectionBlocklistManager.isAllowed(UNLISTED_PACKAGE_NAME);
-
-        assertThat(actual).isFalse();
-    }
-
-    @Test
-    public void isAllowed_allowed() {
-        mContentProtectionBlocklistManager.updateBlocklist(LINES.size());
-        when(mMockContentProtectionPackageManager.getPackageInfo(UNLISTED_PACKAGE_NAME))
-                .thenReturn(PACKAGE_INFO);
-        when(mMockContentProtectionPackageManager.hasRequestedInternetPermissions(PACKAGE_INFO))
-                .thenReturn(true);
-        when(mMockContentProtectionPackageManager.isSystemApp(PACKAGE_INFO)).thenReturn(false);
-        when(mMockContentProtectionPackageManager.isUpdatedSystemApp(PACKAGE_INFO))
-                .thenReturn(false);
-
-        boolean actual = mContentProtectionBlocklistManager.isAllowed(UNLISTED_PACKAGE_NAME);
-
-        assertThat(actual).isTrue();
-    }
-
-    @Test
-    public void updateBlocklist_negativeSize() {
-        mContentProtectionBlocklistManager.updateBlocklist(/* blocklistSize= */ -1);
-        assertThat(mReadRawFiles).isEmpty();
-
-        mContentProtectionBlocklistManager.isAllowed(FIRST_PACKAGE_NAME);
-        verify(mMockContentProtectionPackageManager).getPackageInfo(FIRST_PACKAGE_NAME);
-    }
-
-    @Test
-    public void updateBlocklist_zeroSize() {
-        mContentProtectionBlocklistManager.updateBlocklist(/* blocklistSize= */ 0);
-        assertThat(mReadRawFiles).isEmpty();
-
-        mContentProtectionBlocklistManager.isAllowed(FIRST_PACKAGE_NAME);
-        verify(mMockContentProtectionPackageManager).getPackageInfo(FIRST_PACKAGE_NAME);
-    }
-
-    @Test
-    public void updateBlocklist_positiveSize_belowTotal() {
-        mContentProtectionBlocklistManager.updateBlocklist(/* blocklistSize= */ 1);
-        assertThat(mReadRawFiles).containsExactly(PACKAGE_NAME_BLOCKLIST_FILENAME);
-
-        mContentProtectionBlocklistManager.isAllowed(FIRST_PACKAGE_NAME);
-        mContentProtectionBlocklistManager.isAllowed(SECOND_PACKAGE_NAME);
-
-        verify(mMockContentProtectionPackageManager, never()).getPackageInfo(FIRST_PACKAGE_NAME);
-        verify(mMockContentProtectionPackageManager).getPackageInfo(SECOND_PACKAGE_NAME);
-    }
-
-    @Test
-    public void updateBlocklist_positiveSize_aboveTotal() {
-        mContentProtectionBlocklistManager.updateBlocklist(LINES.size() + 1);
-        assertThat(mReadRawFiles).containsExactly(PACKAGE_NAME_BLOCKLIST_FILENAME);
-
-        mContentProtectionBlocklistManager.isAllowed(FIRST_PACKAGE_NAME);
-        mContentProtectionBlocklistManager.isAllowed(SECOND_PACKAGE_NAME);
-
-        verify(mMockContentProtectionPackageManager, never()).getPackageInfo(FIRST_PACKAGE_NAME);
-        verify(mMockContentProtectionPackageManager, never()).getPackageInfo(SECOND_PACKAGE_NAME);
-    }
-
-    private final class TestContentProtectionBlocklistManager
-            extends ContentProtectionBlocklistManager {
-
-        TestContentProtectionBlocklistManager() {
-            super(mMockContentProtectionPackageManager);
-        }
-
-        @Override
-        protected List<String> readLinesFromRawFile(@NonNull String filename) {
-            mReadRawFiles.add(filename);
-            return LINES;
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionPackageManagerTest.java b/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionPackageManagerTest.java
deleted file mode 100644
index 7d45ea4..0000000
--- a/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionPackageManagerTest.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2023 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.server.contentprotection;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.when;
-
-import android.Manifest.permission;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.PackageManager.PackageInfoFlags;
-import android.testing.TestableContext;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-/**
- * Test for {@link ContentProtectionPackageManager}.
- *
- * <p>Run with: {@code atest
- * FrameworksServicesTests:com.android.server.contentprotection.ContentProtectionPackageManagerTest}
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class ContentProtectionPackageManagerTest {
-    private static final String PACKAGE_NAME = "PACKAGE_NAME";
-
-    private static final PackageInfo EMPTY_PACKAGE_INFO = new PackageInfo();
-
-    private static final PackageInfo SYSTEM_APP_PACKAGE_INFO = createSystemAppPackageInfo();
-
-    private static final PackageInfo UPDATED_SYSTEM_APP_PACKAGE_INFO =
-            createUpdatedSystemAppPackageInfo();
-
-    @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
-
-    @Rule
-    public final TestableContext mContext =
-            new TestableContext(ApplicationProvider.getApplicationContext());
-
-    @Mock private PackageManager mMockPackageManager;
-
-    private ContentProtectionPackageManager mContentProtectionPackageManager;
-
-    @Before
-    public void setup() {
-        mContext.setMockPackageManager(mMockPackageManager);
-        mContentProtectionPackageManager = new ContentProtectionPackageManager(mContext);
-    }
-
-    @Test
-    public void getPackageInfo_found() throws Exception {
-        PackageInfo expected = createPackageInfo(/* flags= */ 0);
-        when(mMockPackageManager.getPackageInfo(eq(PACKAGE_NAME), any(PackageInfoFlags.class)))
-                .thenReturn(expected);
-
-        PackageInfo actual = mContentProtectionPackageManager.getPackageInfo(PACKAGE_NAME);
-
-        assertThat(actual).isEqualTo(expected);
-    }
-
-    @Test
-    public void getPackageInfo_notFound() throws Exception {
-        when(mMockPackageManager.getPackageInfo(eq(PACKAGE_NAME), any(PackageInfoFlags.class)))
-                .thenThrow(new NameNotFoundException());
-
-        PackageInfo actual = mContentProtectionPackageManager.getPackageInfo(PACKAGE_NAME);
-
-        assertThat(actual).isNull();
-    }
-
-    @Test
-    public void getPackageInfo_null() {
-        PackageInfo actual = mContentProtectionPackageManager.getPackageInfo(PACKAGE_NAME);
-
-        assertThat(actual).isNull();
-    }
-
-    @Test
-    public void isSystemApp_true() {
-        boolean actual = mContentProtectionPackageManager.isSystemApp(SYSTEM_APP_PACKAGE_INFO);
-
-        assertThat(actual).isTrue();
-    }
-
-    @Test
-    public void isSystemApp_false() {
-        boolean actual =
-                mContentProtectionPackageManager.isSystemApp(UPDATED_SYSTEM_APP_PACKAGE_INFO);
-
-        assertThat(actual).isFalse();
-    }
-
-    @Test
-    public void isSystemApp_noApplicationInfo() {
-        boolean actual = mContentProtectionPackageManager.isSystemApp(EMPTY_PACKAGE_INFO);
-
-        assertThat(actual).isFalse();
-    }
-
-    @Test
-    public void isUpdatedSystemApp_true() {
-        boolean actual =
-                mContentProtectionPackageManager.isUpdatedSystemApp(
-                        UPDATED_SYSTEM_APP_PACKAGE_INFO);
-
-        assertThat(actual).isTrue();
-    }
-
-    @Test
-    public void isUpdatedSystemApp_false() {
-        boolean actual =
-                mContentProtectionPackageManager.isUpdatedSystemApp(SYSTEM_APP_PACKAGE_INFO);
-
-        assertThat(actual).isFalse();
-    }
-
-    @Test
-    public void isUpdatedSystemApp_noApplicationInfo() {
-        boolean actual = mContentProtectionPackageManager.isUpdatedSystemApp(EMPTY_PACKAGE_INFO);
-
-        assertThat(actual).isFalse();
-    }
-
-    @Test
-    public void hasRequestedInternetPermissions_true() {
-        PackageInfo packageInfo = createPackageInfo(new String[] {permission.INTERNET});
-
-        boolean actual =
-                mContentProtectionPackageManager.hasRequestedInternetPermissions(packageInfo);
-
-        assertThat(actual).isTrue();
-    }
-
-    @Test
-    public void hasRequestedInternetPermissions_false() {
-        PackageInfo packageInfo = createPackageInfo(new String[] {permission.ACCESS_FINE_LOCATION});
-
-        boolean actual =
-                mContentProtectionPackageManager.hasRequestedInternetPermissions(packageInfo);
-
-        assertThat(actual).isFalse();
-    }
-
-    @Test
-    public void hasRequestedInternetPermissions_noRequestedPermissions() {
-        boolean actual =
-                mContentProtectionPackageManager.hasRequestedInternetPermissions(
-                        EMPTY_PACKAGE_INFO);
-
-        assertThat(actual).isFalse();
-    }
-
-    private static PackageInfo createSystemAppPackageInfo() {
-        return createPackageInfo(ApplicationInfo.FLAG_SYSTEM);
-    }
-
-    private static PackageInfo createUpdatedSystemAppPackageInfo() {
-        return createPackageInfo(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
-    }
-
-    private static PackageInfo createPackageInfo(int flags) {
-        return createPackageInfo(flags, /* requestedPermissions= */ new String[0]);
-    }
-
-    private static PackageInfo createPackageInfo(String[] requestedPermissions) {
-        return createPackageInfo(/* flags= */ 0, requestedPermissions);
-    }
-
-    private static PackageInfo createPackageInfo(int flags, String[] requestedPermissions) {
-        PackageInfo packageInfo = new PackageInfo();
-        packageInfo.packageName = PACKAGE_NAME;
-        packageInfo.applicationInfo = new ApplicationInfo();
-        packageInfo.applicationInfo.packageName = PACKAGE_NAME;
-        packageInfo.applicationInfo.flags = flags;
-        packageInfo.requestedPermissions = requestedPermissions;
-        return packageInfo;
-    }
-}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
index 6a738be..9f58491 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
@@ -41,7 +41,6 @@
 
 import com.android.server.testutils.StubTransaction;
 import com.android.server.wm.utils.MockAnimationAdapter;
-import com.android.window.flags.Flags;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -150,7 +149,7 @@
         mHost = new MockSurfaceBuildingContainer(mWm);
         mTransaction = spy(StubTransaction.class);
         mChild = new TestWindowContainer(mWm);
-        if (Flags.dimmerRefactor()) {
+        if (Dimmer.DIMMER_REFACTOR) {
             sTestAnimation = spy(new MockAnimationAdapter());
             mDimmer = new SmoothDimmer(mHost, new MockAnimationAdapterFactory());
         } else {
@@ -177,7 +176,7 @@
 
     @Test
     public void testDimBelowWithChildSurfaceCreatesSurfaceBelowChild_Smooth() {
-        assumeTrue(Flags.dimmerRefactor());
+        assumeTrue(Dimmer.DIMMER_REFACTOR);
         final float alpha = 0.7f;
         final int blur = 50;
         mHost.addChild(mChild, 0);
@@ -197,7 +196,7 @@
 
     @Test
     public void testDimBelowWithChildSurfaceCreatesSurfaceBelowChild_Legacy() {
-        assumeFalse(Flags.dimmerRefactor());
+        assumeFalse(Dimmer.DIMMER_REFACTOR);
         final float alpha = 0.7f;
         mHost.addChild(mChild, 0);
         mDimmer.adjustAppearance(mChild, alpha, 20);
@@ -212,7 +211,7 @@
 
     @Test
     public void testDimBelowWithChildSurfaceDestroyedWhenReset_Smooth() {
-        assumeTrue(Flags.dimmerRefactor());
+        assumeTrue(Dimmer.DIMMER_REFACTOR);
         mHost.addChild(mChild, 0);
 
         final float alpha = 0.8f;
@@ -232,7 +231,7 @@
 
     @Test
     public void testDimBelowWithChildSurfaceDestroyedWhenReset_Legacy() {
-        assumeFalse(Flags.dimmerRefactor());
+        assumeFalse(Dimmer.DIMMER_REFACTOR);
         mHost.addChild(mChild, 0);
 
         final float alpha = 0.8f;
@@ -292,7 +291,7 @@
 
     @Test
     public void testRemoveDimImmediately_Smooth() {
-        assumeTrue(Flags.dimmerRefactor());
+        assumeTrue(Dimmer.DIMMER_REFACTOR);
         mHost.addChild(mChild, 0);
         mDimmer.adjustAppearance(mChild, 1, 2);
         mDimmer.adjustRelativeLayer(mChild, -1);
@@ -312,7 +311,7 @@
 
     @Test
     public void testRemoveDimImmediately_Legacy() {
-        assumeFalse(Flags.dimmerRefactor());
+        assumeFalse(Dimmer.DIMMER_REFACTOR);
         mHost.addChild(mChild, 0);
         mDimmer.adjustAppearance(mChild, 1, 0);
         mDimmer.adjustRelativeLayer(mChild, -1);
@@ -332,7 +331,7 @@
 
     @Test
     public void testDimmerWithBlurUpdatesTransaction_Legacy() {
-        assumeFalse(Flags.dimmerRefactor());
+        assumeFalse(Dimmer.DIMMER_REFACTOR);
         mHost.addChild(mChild, 0);
 
         final int blurRadius = 50;
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 038b93f..0b70b40e 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -3148,6 +3148,14 @@
     public static final String KEY_ROAMING_OPERATOR_STRING_ARRAY = "roaming_operator_string_array";
 
     /**
+     * Config to show the roaming indicator (i.e. the "R" icon) from the status bar when roaming.
+     * The roaming indicator will be shown if this is {@code true} and will not be shown if this is
+     * {@code false}.
+     */
+    @FlaggedApi(Flags.FLAG_HIDE_ROAMING_ICON)
+    public static final String KEY_SHOW_ROAMING_INDICATOR_BOOL = "show_roaming_indicator_bool";
+
+    /**
      * URL from which the proto containing the public key of the Carrier used for
      * IMSI encryption will be downloaded.
      * @hide
@@ -3313,11 +3321,11 @@
      * If {@code false} the SPN display checks if the current MCC/MNC is different from the
      * SIM card's MCC/MNC.
      *
-     * @see KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY
-     * @see KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY
-     * @see KEY_NON_ROAMING_OPERATOR_STRING_ARRAY
-     * @see KEY_ROAMING_OPERATOR_STRING_ARRAY
-     * @see KEY_FORCE_HOME_NETWORK_BOOL
+     * @see #KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY
+     * @see #KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY
+     * @see #KEY_NON_ROAMING_OPERATOR_STRING_ARRAY
+     * @see #KEY_ROAMING_OPERATOR_STRING_ARRAY
+     * @see #KEY_FORCE_HOME_NETWORK_BOOL
      *
      * @hide
      */
@@ -10193,6 +10201,7 @@
                 false);
         sDefaults.putStringArray(KEY_NON_ROAMING_OPERATOR_STRING_ARRAY, null);
         sDefaults.putStringArray(KEY_ROAMING_OPERATOR_STRING_ARRAY, null);
+        sDefaults.putBoolean(KEY_SHOW_ROAMING_INDICATOR_BOOL, true);
         sDefaults.putBoolean(KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, false);
         sDefaults.putBoolean(KEY_RTT_SUPPORTED_BOOL, false);
         sDefaults.putBoolean(KEY_TTY_SUPPORTED_BOOL, true);
diff --git a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
index 158e065..dc55dd2 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
@@ -237,6 +237,12 @@
      */
     private transient LinkAddress[] mLinkAddresses6;
     /**
+     * For hidden lists, getters, setters and adders will be hidden.
+     * @hide
+     */
+    private @NonNull List<LinkAddress> mLinkAddresses7 = new ArrayList<>();
+
+    /**
      * When using transient fields for caching it's often also a good idea to initialize them
      * lazily.
      *
@@ -486,6 +492,8 @@
      *   Making a field public will suppress getter generation in favor of accessing it directly.
      * @param linkAddresses5
      *   Final fields suppress generating a setter (when setters are requested).
+     * @param linkAddresses7
+     *   For hidden lists, getters, setters and adders will be hidden.
      * @param stringRes
      *   Fields with certain annotations are automatically validated in constructor
      *
@@ -529,9 +537,10 @@
             @State int state,
             @NonNull CharSequence charSeq,
             @Nullable LinkAddress[] linkAddresses5,
+            @NonNull List<LinkAddress> linkAddresses7,
             @StringRes int stringRes,
             @android.annotation.IntRange(from = 0, to = 6) int dayOfWeek,
-            @Size(2) @NonNull @FloatRange(from = 0f) float[] coords,
+            @Size(2) @NonNull @Each @FloatRange(from = 0f) float[] coords,
             @NonNull IBinder token,
             @Nullable ICompanionDeviceManager iPCInterface) {
         this.mNum = num;
@@ -595,6 +604,9 @@
         AnnotationValidations.validate(
                 NonNull.class, null, charSeq);
         this.mLinkAddresses5 = linkAddresses5;
+        this.mLinkAddresses7 = linkAddresses7;
+        AnnotationValidations.validate(
+                NonNull.class, null, mLinkAddresses7);
         this.mStringRes = stringRes;
         AnnotationValidations.validate(
                 StringRes.class, null, mStringRes);
@@ -609,13 +621,11 @@
                 "value", 2);
         AnnotationValidations.validate(
                 NonNull.class, null, mCoords);
-        int coordsSize = mCoords.length;
-        for (int i = 0; i < coordsSize; i++) {
-            AnnotationValidations.validate(
-                    FloatRange.class, null, mCoords[i],
-                    "from", 0f);
-        }
-
+        AnnotationValidations.validate(
+                Each.class, null, mCoords);
+        AnnotationValidations.validate(
+                FloatRange.class, null, mCoords,
+                "from", 0f);
         this.mToken = token;
         AnnotationValidations.validate(
                 NonNull.class, null, mToken);
@@ -777,6 +787,16 @@
     }
 
     /**
+     * For hidden lists, getters, setters and adders will be hidden.
+     *
+     * @hide
+     */
+    @DataClass.Generated.Member
+    public @NonNull List<LinkAddress> getLinkAddresses7() {
+        return mLinkAddresses7;
+    }
+
+    /**
      * Fields with certain annotations are automatically validated in constructor
      *
      * You can see overloads in {@link AnnotationValidations} for a list of currently
@@ -815,7 +835,7 @@
      * @see AnnotationValidations#validate(Class, Size, int, String, int)
      */
     @DataClass.Generated.Member
-    public @Size(2) @NonNull @FloatRange(from = 0f) float[] getCoords() {
+    public @Size(2) @NonNull @Each @FloatRange(from = 0f) float[] getCoords() {
         return mCoords;
     }
 
@@ -1065,6 +1085,19 @@
     }
 
     /**
+     * For hidden lists, getters, setters and adders will be hidden.
+     *
+     * @hide
+     */
+    @DataClass.Generated.Member
+    public @NonNull SampleDataClass setLinkAddresses7(@NonNull List<LinkAddress> value) {
+        mLinkAddresses7 = value;
+        AnnotationValidations.validate(
+                NonNull.class, null, mLinkAddresses7);
+        return this;
+    }
+
+    /**
      * Fields with certain annotations are automatically validated in constructor
      *
      * You can see overloads in {@link AnnotationValidations} for a list of currently
@@ -1111,20 +1144,18 @@
      * @see AnnotationValidations#validate(Class, Size, int, String, int)
      */
     @DataClass.Generated.Member
-    public @NonNull SampleDataClass setCoords(@Size(2) @NonNull @FloatRange(from = 0f) float... value) {
+    public @NonNull SampleDataClass setCoords(@Size(2) @NonNull @Each @FloatRange(from = 0f) float... value) {
         mCoords = value;
         AnnotationValidations.validate(
                 Size.class, null, mCoords.length,
                 "value", 2);
         AnnotationValidations.validate(
                 NonNull.class, null, mCoords);
-        int coordsSize = mCoords.length;
-        for (int i = 0; i < coordsSize; i++) {
-            AnnotationValidations.validate(
-                    FloatRange.class, null, mCoords[i],
-                    "from", 0f);
-        }
-
+        AnnotationValidations.validate(
+                Each.class, null, mCoords);
+        AnnotationValidations.validate(
+                FloatRange.class, null, mCoords,
+                "from", 0f);
         return this;
     }
 
@@ -1172,6 +1203,7 @@
                 "state = " + stateToString(mState) + ", " +
                 "charSeq = " + charSeq + ", " +
                 "linkAddresses5 = " + java.util.Arrays.toString(mLinkAddresses5) + ", " +
+                "linkAddresses7 = " + mLinkAddresses7 + ", " +
                 "stringRes = " + mStringRes + ", " +
                 "dayOfWeek = " + mDayOfWeek + ", " +
                 "coords = " + java.util.Arrays.toString(mCoords) + ", " +
@@ -1210,6 +1242,7 @@
                 && mState == that.mState
                 && Objects.equals(charSeq, that.charSeq)
                 && java.util.Arrays.equals(mLinkAddresses5, that.mLinkAddresses5)
+                && Objects.equals(mLinkAddresses7, that.mLinkAddresses7)
                 && mStringRes == that.mStringRes
                 && mDayOfWeek == that.mDayOfWeek
                 && java.util.Arrays.equals(mCoords, that.mCoords)
@@ -1241,6 +1274,7 @@
         _hash = 31 * _hash + mState;
         _hash = 31 * _hash + Objects.hashCode(charSeq);
         _hash = 31 * _hash + java.util.Arrays.hashCode(mLinkAddresses5);
+        _hash = 31 * _hash + Objects.hashCode(mLinkAddresses7);
         _hash = 31 * _hash + mStringRes;
         _hash = 31 * _hash + mDayOfWeek;
         _hash = 31 * _hash + java.util.Arrays.hashCode(mCoords);
@@ -1270,6 +1304,7 @@
         actionInt.acceptInt(this, "state", mState);
         actionObject.acceptObject(this, "charSeq", charSeq);
         actionObject.acceptObject(this, "linkAddresses5", mLinkAddresses5);
+        actionObject.acceptObject(this, "linkAddresses7", mLinkAddresses7);
         actionInt.acceptInt(this, "stringRes", mStringRes);
         actionInt.acceptInt(this, "dayOfWeek", mDayOfWeek);
         actionObject.acceptObject(this, "coords", mCoords);
@@ -1298,6 +1333,7 @@
         action.acceptObject(this, "state", mState);
         action.acceptObject(this, "charSeq", charSeq);
         action.acceptObject(this, "linkAddresses5", mLinkAddresses5);
+        action.acceptObject(this, "linkAddresses7", mLinkAddresses7);
         action.acceptObject(this, "stringRes", mStringRes);
         action.acceptObject(this, "dayOfWeek", mDayOfWeek);
         action.acceptObject(this, "coords", mCoords);
@@ -1338,7 +1374,7 @@
         if (mOtherParcelable != null) flg |= 0x40;
         if (mLinkAddresses4 != null) flg |= 0x800;
         if (mLinkAddresses5 != null) flg |= 0x10000;
-        if (mIPCInterface != null) flg |= 0x200000;
+        if (mIPCInterface != null) flg |= 0x400000;
         dest.writeLong(flg);
         dest.writeInt(mNum);
         dest.writeInt(mNum2);
@@ -1357,6 +1393,7 @@
         dest.writeInt(mState);
         dest.writeCharSequence(charSeq);
         if (mLinkAddresses5 != null) dest.writeTypedArray(mLinkAddresses5, flags);
+        dest.writeParcelableList(mLinkAddresses7, flags);
         dest.writeInt(mStringRes);
         dest.writeInt(mDayOfWeek);
         dest.writeFloatArray(mCoords);
@@ -1395,11 +1432,13 @@
         int state = in.readInt();
         CharSequence _charSeq = (CharSequence) in.readCharSequence();
         LinkAddress[] linkAddresses5 = (flg & 0x10000) == 0 ? null : (LinkAddress[]) in.createTypedArray(LinkAddress.CREATOR);
+        List<LinkAddress> linkAddresses7 = new ArrayList<>();
+        in.readParcelableList(linkAddresses7, LinkAddress.class.getClassLoader());
         int stringRes = in.readInt();
         int dayOfWeek = in.readInt();
         float[] coords = in.createFloatArray();
         IBinder token = (IBinder) in.readStrongBinder();
-        ICompanionDeviceManager iPCInterface = (flg & 0x200000) == 0 ? null : ICompanionDeviceManager.Stub.asInterface(in.readStrongBinder());
+        ICompanionDeviceManager iPCInterface = (flg & 0x400000) == 0 ? null : ICompanionDeviceManager.Stub.asInterface(in.readStrongBinder());
 
         this.mNum = num;
         this.mNum2 = num2;
@@ -1462,6 +1501,9 @@
         AnnotationValidations.validate(
                 NonNull.class, null, charSeq);
         this.mLinkAddresses5 = linkAddresses5;
+        this.mLinkAddresses7 = linkAddresses7;
+        AnnotationValidations.validate(
+                NonNull.class, null, mLinkAddresses7);
         this.mStringRes = stringRes;
         AnnotationValidations.validate(
                 StringRes.class, null, mStringRes);
@@ -1476,13 +1518,11 @@
                 "value", 2);
         AnnotationValidations.validate(
                 NonNull.class, null, mCoords);
-        int coordsSize = mCoords.length;
-        for (int i = 0; i < coordsSize; i++) {
-            AnnotationValidations.validate(
-                    FloatRange.class, null, mCoords[i],
-                    "from", 0f);
-        }
-
+        AnnotationValidations.validate(
+                Each.class, null, mCoords);
+        AnnotationValidations.validate(
+                FloatRange.class, null, mCoords,
+                "from", 0f);
         this.mToken = token;
         AnnotationValidations.validate(
                 NonNull.class, null, mToken);
@@ -1529,9 +1569,10 @@
         private @State int mState;
         private @NonNull CharSequence charSeq;
         private @Nullable LinkAddress[] mLinkAddresses5;
+        private @NonNull List<LinkAddress> mLinkAddresses7;
         private @StringRes int mStringRes;
         private @android.annotation.IntRange(from = 0, to = 6) int mDayOfWeek;
-        private @Size(2) @NonNull @FloatRange(from = 0f) float[] mCoords;
+        private @Size(2) @NonNull @Each @FloatRange(from = 0f) float[] mCoords;
         private @NonNull IBinder mToken;
         private @Nullable ICompanionDeviceManager mIPCInterface;
 
@@ -1823,6 +1864,30 @@
         }
 
         /**
+         * For hidden lists, getters, setters and adders will be hidden.
+         *
+         * @hide
+         */
+        @DataClass.Generated.Member
+        public @NonNull Builder setLinkAddresses7(@NonNull List<LinkAddress> value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x20000;
+            mLinkAddresses7 = value;
+            return this;
+        }
+
+        /** @see #setLinkAddresses7 @hide */
+        @DataClass.Generated.Member
+        public @NonNull Builder addLinkAddresses7(@NonNull LinkAddress value) {
+            // You can refine this method's name by providing item's singular name, e.g.:
+            // @DataClass.PluralOf("item")) mItems = ...
+
+            if (mLinkAddresses7 == null) setLinkAddresses7(new ArrayList<>());
+            mLinkAddresses7.add(value);
+            return this;
+        }
+
+        /**
          * Fields with certain annotations are automatically validated in constructor
          *
          * You can see overloads in {@link AnnotationValidations} for a list of currently
@@ -1837,7 +1902,7 @@
         @DataClass.Generated.Member
         public @NonNull Builder setStringRes(@StringRes int value) {
             checkNotUsed();
-            mBuilderFieldsSet |= 0x20000;
+            mBuilderFieldsSet |= 0x40000;
             mStringRes = value;
             return this;
         }
@@ -1852,7 +1917,7 @@
         @DataClass.Generated.Member
         public @NonNull Builder setDayOfWeek(@android.annotation.IntRange(from = 0, to = 6) int value) {
             checkNotUsed();
-            mBuilderFieldsSet |= 0x40000;
+            mBuilderFieldsSet |= 0x80000;
             mDayOfWeek = value;
             return this;
         }
@@ -1867,9 +1932,9 @@
          * @see AnnotationValidations#validate(Class, Size, int, String, int)
          */
         @DataClass.Generated.Member
-        public @NonNull Builder setCoords(@Size(2) @NonNull @FloatRange(from = 0f) float... value) {
+        public @NonNull Builder setCoords(@Size(2) @NonNull @Each @FloatRange(from = 0f) float... value) {
             checkNotUsed();
-            mBuilderFieldsSet |= 0x80000;
+            mBuilderFieldsSet |= 0x100000;
             mCoords = value;
             return this;
         }
@@ -1880,7 +1945,7 @@
         @DataClass.Generated.Member
         public @NonNull Builder setToken(@NonNull IBinder value) {
             checkNotUsed();
-            mBuilderFieldsSet |= 0x100000;
+            mBuilderFieldsSet |= 0x200000;
             mToken = value;
             return this;
         }
@@ -1891,7 +1956,7 @@
         @DataClass.Generated.Member
         public @NonNull Builder setIPCInterface(@NonNull ICompanionDeviceManager value) {
             checkNotUsed();
-            mBuilderFieldsSet |= 0x200000;
+            mBuilderFieldsSet |= 0x400000;
             mIPCInterface = value;
             return this;
         }
@@ -1899,7 +1964,7 @@
         /** Builds the instance. This builder should not be touched after calling this! */
         public @NonNull SampleDataClass build() {
             checkNotUsed();
-            mBuilderFieldsSet |= 0x400000; // Mark builder used
+            mBuilderFieldsSet |= 0x800000; // Mark builder used
 
             if ((mBuilderFieldsSet & 0x10) == 0) {
                 mName2 = "Bob";
@@ -1935,18 +2000,21 @@
                 charSeq = "";
             }
             if ((mBuilderFieldsSet & 0x20000) == 0) {
-                mStringRes = 0;
+                mLinkAddresses7 = new ArrayList<>();
             }
             if ((mBuilderFieldsSet & 0x40000) == 0) {
-                mDayOfWeek = 3;
+                mStringRes = 0;
             }
             if ((mBuilderFieldsSet & 0x80000) == 0) {
-                mCoords = new float[] { 0f, 0f };
+                mDayOfWeek = 3;
             }
             if ((mBuilderFieldsSet & 0x100000) == 0) {
-                mToken = new Binder();
+                mCoords = new float[] { 0f, 0f };
             }
             if ((mBuilderFieldsSet & 0x200000) == 0) {
+                mToken = new Binder();
+            }
+            if ((mBuilderFieldsSet & 0x400000) == 0) {
                 mIPCInterface = null;
             }
             SampleDataClass o = new SampleDataClass(
@@ -1967,6 +2035,7 @@
                     mState,
                     charSeq,
                     mLinkAddresses5,
+                    mLinkAddresses7,
                     mStringRes,
                     mDayOfWeek,
                     mCoords,
@@ -1976,7 +2045,7 @@
         }
 
         private void checkNotUsed() {
-            if ((mBuilderFieldsSet & 0x400000) != 0) {
+            if ((mBuilderFieldsSet & 0x800000) != 0) {
                 throw new IllegalStateException(
                         "This Builder should not be reused. Use a new Builder instance instead");
             }
@@ -1984,10 +2053,10 @@
     }
 
     @DataClass.Generated(
-            time = 1616541539978L,
+            time = 1697693846352L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java",
-            inputSignatures = "public static final  java.lang.String STATE_NAME_UNDEFINED\npublic static final  java.lang.String STATE_NAME_ON\npublic static final  java.lang.String STATE_NAME_OFF\npublic static final  int STATE_ON\npublic static final  int STATE_OFF\npublic static final  int STATE_UNDEFINED\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_AUGMENTED_REQUEST\nprivate  int mNum\nprivate  int mNum2\nprivate  int mNum4\nprivate @android.annotation.Nullable java.lang.String mName\nprivate @android.annotation.NonNull java.lang.String mName2\nprivate @android.annotation.NonNull java.lang.String mName4\nprivate @android.annotation.Nullable android.view.accessibility.AccessibilityNodeInfo mOtherParcelable\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.codegentest.MyDateParcelling.class) @android.annotation.NonNull java.util.Date mDate\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForPattern.class) @android.annotation.NonNull java.util.regex.Pattern mPattern\nprivate @android.annotation.NonNull java.util.List<android.net.LinkAddress> mLinkAddresses2\nprivate @com.android.internal.util.DataClass.PluralOf(\"linkAddress\") @android.annotation.NonNull java.util.ArrayList<android.net.LinkAddress> mLinkAddresses\nprivate @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses4\nprivate @com.android.codegentest.SampleDataClass.StateName @android.annotation.NonNull java.lang.String mStateName\nprivate @com.android.codegentest.SampleDataClass.RequestFlags int mFlags\nprivate @com.android.codegentest.SampleDataClass.State int mState\npublic @android.annotation.NonNull java.lang.CharSequence charSeq\nprivate final @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses5\nprivate transient  android.net.LinkAddress[] mLinkAddresses6\ntransient  int[] mTmpStorage\nprivate @android.annotation.StringRes int mStringRes\nprivate @android.annotation.IntRange int mDayOfWeek\nprivate @android.annotation.Size @android.annotation.NonNull @com.android.internal.util.DataClass.Each @android.annotation.FloatRange float[] mCoords\nprivate @android.annotation.NonNull android.os.IBinder mToken\nprivate @android.annotation.Nullable android.companion.ICompanionDeviceManager mIPCInterface\nprivate static  java.lang.String defaultName4()\nprivate  int[] lazyInitTmpStorage()\npublic  android.net.LinkAddress[] getLinkAddresses4()\nprivate  boolean patternEquals(java.util.regex.Pattern)\nprivate  int patternHashCode()\nprivate  void onConstructed()\npublic  void dump(java.io.PrintWriter)\nclass SampleDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genConstructor=true, genEqualsHashCode=true, genToString=true, genForEachField=true, genSetters=true)")
+            inputSignatures = "public static final  java.lang.String STATE_NAME_UNDEFINED\npublic static final  java.lang.String STATE_NAME_ON\npublic static final  java.lang.String STATE_NAME_OFF\npublic static final  int STATE_ON\npublic static final  int STATE_OFF\npublic static final  int STATE_UNDEFINED\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_AUGMENTED_REQUEST\nprivate  int mNum\nprivate  int mNum2\nprivate  int mNum4\nprivate @android.annotation.Nullable java.lang.String mName\nprivate @android.annotation.NonNull java.lang.String mName2\nprivate @android.annotation.NonNull java.lang.String mName4\nprivate @android.annotation.Nullable android.view.accessibility.AccessibilityNodeInfo mOtherParcelable\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.codegentest.MyDateParcelling.class) @android.annotation.NonNull java.util.Date mDate\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForPattern.class) @android.annotation.NonNull java.util.regex.Pattern mPattern\nprivate @android.annotation.NonNull java.util.List<android.net.LinkAddress> mLinkAddresses2\nprivate @com.android.internal.util.DataClass.PluralOf(\"linkAddress\") @android.annotation.NonNull java.util.ArrayList<android.net.LinkAddress> mLinkAddresses\nprivate @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses4\nprivate @com.android.codegentest.SampleDataClass.StateName @android.annotation.NonNull java.lang.String mStateName\nprivate @com.android.codegentest.SampleDataClass.RequestFlags int mFlags\nprivate @com.android.codegentest.SampleDataClass.State int mState\npublic @android.annotation.NonNull java.lang.CharSequence charSeq\nprivate final @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses5\nprivate transient  android.net.LinkAddress[] mLinkAddresses6\nprivate @android.annotation.NonNull java.util.List<android.net.LinkAddress> mLinkAddresses7\ntransient  int[] mTmpStorage\nprivate @android.annotation.StringRes int mStringRes\nprivate @android.annotation.IntRange int mDayOfWeek\nprivate @android.annotation.Size @android.annotation.NonNull @com.android.internal.util.DataClass.Each @android.annotation.FloatRange float[] mCoords\nprivate @android.annotation.NonNull android.os.IBinder mToken\nprivate @android.annotation.Nullable android.companion.ICompanionDeviceManager mIPCInterface\nprivate static  java.lang.String defaultName4()\nprivate  int[] lazyInitTmpStorage()\npublic  android.net.LinkAddress[] getLinkAddresses4()\nprivate  boolean patternEquals(java.util.regex.Pattern)\nprivate  int patternHashCode()\nprivate  void onConstructed()\npublic  void dump(java.io.PrintWriter)\nclass SampleDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genConstructor=true, genEqualsHashCode=true, genToString=true, genForEachField=true, genSetters=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/tools/codegen/src/com/android/codegen/Generators.kt b/tools/codegen/src/com/android/codegen/Generators.kt
index 6857333..d3a8b03 100644
--- a/tools/codegen/src/com/android/codegen/Generators.kt
+++ b/tools/codegen/src/com/android/codegen/Generators.kt
@@ -327,7 +327,8 @@
             +"return$maybeCast this;"
         }
 
-        val javadocSeeSetter = "/** @see #$setterName */"
+        val javadocSeeSetter =
+                if (isHidden()) "/** @see #$setterName @hide */" else "/** @see #$setterName */"
         val adderName = "add$SingularName"
 
         val singularNameCustomizationHint = if (SingularNameOrNull == null) {
@@ -750,6 +751,15 @@
     }
 }
 
+fun FieldInfo.isHidden(): Boolean {
+    if (javadocFull != null) {
+        (javadocFull ?: "/**\n */").lines().forEach {
+            if (it.contains("@hide")) return true
+        }
+    }
+    return false
+}
+
 fun FieldInfo.generateFieldJavadoc(forceHide: Boolean = false) = classPrinter {
     if (javadocFull != null || forceHide) {
         var hidden = false